Merge branch 'release-1.7.1' oc-android-1.7.1_signed
authormasensio <masensio@solidgear.es>
Tue, 7 Apr 2015 12:06:32 +0000 (14:06 +0200)
committermasensio <masensio@solidgear.es>
Tue, 7 Apr 2015 12:06:32 +0000 (14:06 +0200)
276 files changed:
AndroidManifest.xml
oc_jb_workaround/AndroidManifest.xml
oc_jb_workaround/res/values/setup.xml
oc_jb_workaround/src/com/owncloud/android/workaround/accounts/AccountAuthenticatorService.java
owncloud-android-library
res/anim/disappear.xml
res/anim/grow_from_bottom.xml
res/anim/grow_from_bottomleft_to_topright.xml
res/anim/grow_from_bottomright_to_topleft.xml
res/anim/grow_from_top.xml
res/anim/grow_from_topleft_to_bottomright.xml
res/anim/grow_from_topright_to_bottomleft.xml
res/anim/pump_bottom.xml
res/anim/pump_top.xml
res/anim/shrink_from_bottom.xml
res/anim/shrink_from_bottomleft_to_topright.xml
res/anim/shrink_from_bottomright_to_topleft.xml
res/anim/shrink_from_top.xml
res/anim/shrink_from_topleft_to_bottomright.xml
res/anim/shrink_from_topright_to_bottomleft.xml
res/drawable/action_item_btn.xml
res/drawable/btn.xml
res/drawable/btn_round.xml
res/drawable/btn_round_pressed.xml
res/drawable/list_selector.xml
res/drawable/main_header_bg.xml
res/drawable/progress_small.xml
res/drawable/split_action_bg.xml
res/drawable/uploader_list_separator.xml
res/layout-land/account_setup.xml
res/layout-v11/activity_row.xml
res/layout-v11/notification_with_progress_bar.xml
res/layout-v14/generic_explanation.xml
res/layout/account_setup.xml
res/layout/action_item.xml
res/layout/activity_row.xml
res/layout/edit_box_dialog.xml
res/layout/file_details_empty.xml
res/layout/file_details_fragment.xml
res/layout/file_download_fragment.xml
res/layout/file_preview.xml
res/layout/files.xml
res/layout/files_folder_picker.xml
res/layout/generic_explanation.xml
res/layout/grid_image.xml
res/layout/grid_item.xml
res/layout/list_fragment.xml
res/layout/list_item.xml
res/layout/loading_dialog.xml
res/layout/log_item.xml
res/layout/log_send_file.xml
res/layout/media_control.xml
res/layout/notification_with_progress_bar.xml
res/layout/password_dialog.xml [new file with mode: 0644]
res/layout/pincodelock.xml
res/layout/popup.xml
res/layout/preview_image_activity.xml
res/layout/preview_image_fragment.xml
res/layout/ssl_untrusted_cert_layout.xml
res/layout/ssl_validator_layout.xml
res/layout/sso_dialog.xml
res/layout/upload_files_layout.xml
res/layout/uploader_layout.xml
res/layout/uploader_list_item_layout.xml
res/layout/video_layout.xml
res/menu/account_picker_long_click.xml
res/menu/file_actions_menu.xml
res/menu/main_menu.xml
res/raw-de/changelog.html
res/raw-es/changelog.html
res/raw/changelog.html
res/values-ar/strings.xml
res/values-az/strings.xml
res/values-bg-rBG/strings.xml
res/values-bn-rBD/strings.xml
res/values-bs/strings.xml
res/values-ca/strings.xml
res/values-cs-rCZ/strings.xml
res/values-da/strings.xml
res/values-de-rAT/strings.xml
res/values-de-rDE/strings.xml
res/values-de/strings.xml
res/values-el/strings.xml
res/values-en-rGB/strings.xml
res/values-eo/strings.xml
res/values-es-rAR/strings.xml
res/values-es-rCL/strings.xml
res/values-es-rCR/strings.xml
res/values-es-rMX/strings.xml
res/values-es/strings.xml
res/values-et-rEE/strings.xml
res/values-eu/strings.xml
res/values-fa/strings.xml
res/values-fi-rFI/strings.xml
res/values-fr/strings.xml
res/values-gl/strings.xml
res/values-he/strings.xml
res/values-hr/strings.xml
res/values-hu-rHU/strings.xml
res/values-ia/strings.xml
res/values-id/strings.xml
res/values-is/strings.xml
res/values-it/strings.xml
res/values-ja-rJP/strings.xml
res/values-ka-rGE/strings.xml
res/values-km/strings.xml
res/values-kn/strings.xml
res/values-ko/strings.xml
res/values-ku-rIQ/strings.xml
res/values-large-land/bools.xml
res/values-lb/strings.xml
res/values-lo/strings.xml
res/values-lt-rLT/strings.xml
res/values-lv/strings.xml
res/values-mk/strings.xml
res/values-mr/strings.xml [new file with mode: 0644]
res/values-ms-rMY/strings.xml
res/values-nb-rNO/strings.xml
res/values-nl/strings.xml
res/values-nn-rNO/strings.xml
res/values-pa/strings.xml
res/values-pl/strings.xml
res/values-pt-rBR/strings.xml
res/values-pt-rPT/strings.xml
res/values-ro/strings.xml
res/values-ru/strings.xml
res/values-si-rLK/strings.xml
res/values-sk-rSK/strings.xml
res/values-sl/strings.xml
res/values-sq/strings.xml
res/values-sr/strings.xml
res/values-sv/strings.xml
res/values-ta-rLK/strings.xml
res/values-te/strings.xml
res/values-th-rTH/strings.xml
res/values-tr/strings.xml
res/values-ug/strings.xml
res/values-uk/strings.xml
res/values-vi/strings.xml
res/values-zh-rCN/strings.xml
res/values-zh-rHK/strings.xml
res/values-zh-rTW/strings.xml
res/values/bools.xml
res/values/colors.xml
res/values/setup.xml
res/values/strings.xml
res/values/styles.xml
res/xml/authenticator.xml
res/xml/preferences.xml
res/xml/syncadapter_files.xml
src/com/owncloud/android/MainApp.java
src/com/owncloud/android/authentication/AccountAuthenticator.java
src/com/owncloud/android/authentication/AccountAuthenticatorService.java
src/com/owncloud/android/authentication/AccountUtils.java
src/com/owncloud/android/authentication/AuthenticatorActivity.java
src/com/owncloud/android/authentication/AuthenticatorAsyncTask.java [new file with mode: 0644]
src/com/owncloud/android/authentication/OAuth2Constants.java
src/com/owncloud/android/authentication/SsoWebViewClient.java
src/com/owncloud/android/datamodel/FileDataStorageManager.java
src/com/owncloud/android/datamodel/OCFile.java
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
src/com/owncloud/android/db/DbHandler.java
src/com/owncloud/android/db/ProviderMeta.java
src/com/owncloud/android/files/BootupBroadcastReceiver.java
src/com/owncloud/android/files/FileMenuFilter.java
src/com/owncloud/android/files/FileOperationsHelper.java
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java
src/com/owncloud/android/files/services/FileDownloader.java
src/com/owncloud/android/files/services/FileUploader.java
src/com/owncloud/android/files/services/IndexedForest.java
src/com/owncloud/android/files/services/OnUploadCompletedListener.java
src/com/owncloud/android/media/MediaControlView.java
src/com/owncloud/android/media/MediaService.java
src/com/owncloud/android/media/MediaServiceBinder.java
src/com/owncloud/android/notifications/NotificationBuilderWithProgressBar.java
src/com/owncloud/android/notifications/NotificationDelayer.java
src/com/owncloud/android/operations/CreateFolderOperation.java
src/com/owncloud/android/operations/CreateShareOperation.java
src/com/owncloud/android/operations/DetectAuthenticationMethodOperation.java
src/com/owncloud/android/operations/DownloadFileOperation.java
src/com/owncloud/android/operations/GetServerInfoOperation.java
src/com/owncloud/android/operations/GetSharesForFileOperation.java
src/com/owncloud/android/operations/GetSharesOperation.java
src/com/owncloud/android/operations/MoveFileOperation.java
src/com/owncloud/android/operations/OAuth2GetAccessToken.java
src/com/owncloud/android/operations/RefreshFolderOperation.java
src/com/owncloud/android/operations/RemoveFileOperation.java
src/com/owncloud/android/operations/RenameFileOperation.java
src/com/owncloud/android/operations/SynchronizeFileOperation.java
src/com/owncloud/android/operations/SynchronizeFolderOperation.java
src/com/owncloud/android/operations/UnshareLinkOperation.java
src/com/owncloud/android/operations/UpdateOCVersionOperation.java
src/com/owncloud/android/operations/UploadFileOperation.java
src/com/owncloud/android/operations/common/SyncOperation.java
src/com/owncloud/android/providers/FileContentProvider.java
src/com/owncloud/android/services/OperationsService.java
src/com/owncloud/android/services/SyncFolderHandler.java
src/com/owncloud/android/services/observer/FileObserverService.java
src/com/owncloud/android/services/observer/FolderObserver.java
src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java
src/com/owncloud/android/syncadapter/ContactSyncAdapter.java
src/com/owncloud/android/syncadapter/ContactSyncService.java
src/com/owncloud/android/syncadapter/FileSyncAdapter.java
src/com/owncloud/android/syncadapter/FileSyncService.java
src/com/owncloud/android/ui/ActionItem.java
src/com/owncloud/android/ui/CheckBoxPreferenceWithLongTitle.java
src/com/owncloud/android/ui/CustomPopup.java
src/com/owncloud/android/ui/ExtendedListView.java
src/com/owncloud/android/ui/PreferenceWithLongSummary.java
src/com/owncloud/android/ui/QuickAction.java
src/com/owncloud/android/ui/RadioButtonPreference.java
src/com/owncloud/android/ui/SquareImageView.java
src/com/owncloud/android/ui/SquareLinearLayout.java
src/com/owncloud/android/ui/activity/ComponentsGetter.java
src/com/owncloud/android/ui/activity/ConflictsResolveActivity.java
src/com/owncloud/android/ui/activity/CopyToClipboardActivity.java
src/com/owncloud/android/ui/activity/ErrorsWhileCopyingHandlerActivity.java
src/com/owncloud/android/ui/activity/FileActivity.java
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/activity/FolderPickerActivity.java
src/com/owncloud/android/ui/activity/GenericExplanationActivity.java
src/com/owncloud/android/ui/activity/HookActivity.java
src/com/owncloud/android/ui/activity/LogHistoryActivity.java
src/com/owncloud/android/ui/activity/OnEnforceableRefreshListener.java
src/com/owncloud/android/ui/activity/PinCodeActivity.java
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/UploadFilesActivity.java
src/com/owncloud/android/ui/activity/UploadPathActivity.java
src/com/owncloud/android/ui/activity/Uploader.java
src/com/owncloud/android/ui/adapter/CertificateCombinedExceptionViewAdapter.java
src/com/owncloud/android/ui/adapter/DiskLruImageCache.java
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java
src/com/owncloud/android/ui/adapter/LogListAdapter.java
src/com/owncloud/android/ui/adapter/SslCertificateViewAdapter.java
src/com/owncloud/android/ui/adapter/SslErrorViewAdapter.java
src/com/owncloud/android/ui/adapter/X509CertificateViewAdapter.java
src/com/owncloud/android/ui/dialog/ChangelogDialog.java
src/com/owncloud/android/ui/dialog/ConfirmationDialogFragment.java
src/com/owncloud/android/ui/dialog/ConflictsResolveDialog.java
src/com/owncloud/android/ui/dialog/CreateFolderDialogFragment.java
src/com/owncloud/android/ui/dialog/CredentialsDialogFragment.java
src/com/owncloud/android/ui/dialog/IndeterminateProgressDialog.java
src/com/owncloud/android/ui/dialog/LoadingDialog.java
src/com/owncloud/android/ui/dialog/RemoveFileDialogFragment.java
src/com/owncloud/android/ui/dialog/RenameFileDialogFragment.java
src/com/owncloud/android/ui/dialog/SamlWebViewDialog.java
src/com/owncloud/android/ui/dialog/ShareLinkToDialog.java
src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/dialog/SslUntrustedCertDialog.java
src/com/owncloud/android/ui/dialog/SslValidatorDialog.java
src/com/owncloud/android/ui/dialog/SsoWebView.java
src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java
src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/FileDetailFragment.java
src/com/owncloud/android/ui/fragment/FileFragment.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/ui/preview/FileDownloadFragment.java
src/com/owncloud/android/ui/preview/PreviewImageActivity.java
src/com/owncloud/android/ui/preview/PreviewImageFragment.java
src/com/owncloud/android/ui/preview/PreviewImagePagerAdapter.java
src/com/owncloud/android/ui/preview/PreviewMediaFragment.java
src/com/owncloud/android/ui/preview/PreviewVideoActivity.java
src/com/owncloud/android/utils/BitmapUtils.java
src/com/owncloud/android/utils/DisplayUtils.java
src/com/owncloud/android/utils/ErrorMessageAdapter.java
src/com/owncloud/android/utils/FileStorageUtils.java
src/com/owncloud/android/utils/OwnCloudSession.java
src/com/owncloud/android/utils/RecursiveFileObserver.java
src/com/owncloud/android/utils/TouchImageViewCustom.java [deleted file]
src/com/owncloud/android/utils/UriUtils.java
src/com/owncloud/android/widgets/ActionEditText.java
src/third_parties/michaelOrtiz/TouchImageViewCustom.java [new file with mode: 0644]
tests/src/com/owncloud/android/test/AccountUtilsTest.java

index 780875b..8b9f214 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2014 ownCloud Inc.
+  Copyright (C) 2012-2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
@@ -18,8 +18,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  -->
 <manifest package="com.owncloud.android"
-    android:versionCode="10700000"
-    android:versionName="1.7.0" xmlns:android="http://schemas.android.com/apk/res/android">
+    android:versionCode="10700100"
+    android:versionName="1.7.1" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
@@ -32,7 +32,6 @@
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     
@@ -86,7 +85,6 @@
             android:name=".ui.activity.Preferences"
             android:theme="@style/Theme.ownCloud" >
         </activity>
-
         <activity      
             android:name=".ui.preview.PreviewImageActivity" 
             />
index 18ffb4c..c08002c 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.owncloud.android.workaround.accounts"
-    android:versionCode="0100021"
-    android:versionName="1.0.21" >
+    android:versionCode="0100022"
+    android:versionName="1.0.22" >
 
     <uses-sdk
         android:minSdkVersion="16"
index 0bf5e1d..d4d347e 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 5a7c57e..6526f94 100644 (file)
@@ -1,5 +1,5 @@
 /* ownCloud Jelly Bean Workaround for lost credentials
- *   Copyright (C) 2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 2f178c9..2b2fc91 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2f178c9c34e3dab507c46e718705913ed44db3c5
+Subproject commit 2b2fc9171f2cf2c4701a74e4a564148584aab33a
index 8bb865d..5fd6f07 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 78bd62b..774c8d8 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 32b251b..c7920d3 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index f92b219..aff710a 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 851f847..eec19be 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 951ca01..4054bcb 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 972a5b7..6e77a2f 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 6016e00..800c583 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index fa0b6c9..f27627d 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index c330980..7de2c91 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 086eab3..e66e675 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index c96ea9a..4529965 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 4438ebf..1cb18e3 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 680e848..6647158 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 773b51d..19bb0ef 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index dd27833..25fcd40 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 0b0a399..ec8ccee 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 1a47be5..a9d8cdc 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index bc138c7..ab90d28 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index e0e86b3..7d193c3 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 8cd82e4..f3544df 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 1233647..d1ce788 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 99219b6..b449e7f 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 1e53367..bc9cdbd 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 68625ef..fa357c2 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
@@ -38,7 +38,8 @@
                        android:layout_weight="1"\r
                        android:layout_gravity="center"\r
                        android:background="@color/login_logo_background_color"\r
-                       android:src="@drawable/logo" \r
+                       android:src="@drawable/logo"\r
+            android:contentDescription="@string/app_name"\r
                        />\r
                \r
                <ScrollView\r
@@ -65,7 +66,8 @@
                                        android:layout_marginBottom="10dp"\r
                        android:onClick="onRefreshClick"\r
                                    android:text="@string/auth_check_server"\r
-                                   android:visibility="gone" />\r
+                                   android:visibility="gone"\r
+                    android:contentDescription="@string/auth_check_server"/>\r
                                <TextView\r
                                    android:id="@+id/instructions_message"\r
                                    android:layout_width="wrap_content"\r
@@ -73,7 +75,8 @@
                                    android:layout_gravity="fill_horizontal"\r
                                    android:text="@string/auth_expired_basic_auth_toast" \r
                                    android:visibility="gone"\r
-                                   android:layout_marginBottom="10dp"/>\r
+                                   android:layout_marginBottom="10dp"\r
+                    android:contentDescription="@string/auth_expired_basic_auth_toast"/>\r
                            <FrameLayout \r
                                android:id="@+id/hostUrlFrame"\r
                                        android:layout_width="match_parent"\r
@@ -89,6 +92,7 @@
                                                android:inputType="textUri"\r
                                                android:drawablePadding="5dp"\r
                                                android:paddingRight="55dp"\r
+                                               android:contentDescription="@string/auth_host_address"\r
                                                >\r
                                                <requestFocus />\r
                                        </EditText>\r
                                android:onClick="onRefreshClick"\r
                                            android:visibility="gone"\r
                                                android:background="@android:color/transparent"\r
+                        android:contentDescription="@string/auth_refresh_button"\r
                                            />\r
                                </FrameLayout>\r
                \r
                                        android:drawableLeft="@android:drawable/stat_notify_sync"\r
                                        android:drawablePadding="5dp"\r
                                        android:gravity="center_vertical"\r
-                                       android:text="@string/auth_testing_connection" />\r
+                                       android:text="@string/auth_testing_connection"\r
+                    android:contentDescription="@string/auth_testing_connection"/>\r
                             \r
                                <CheckBox\r
                                        android:id="@+id/oauth_onOff_check"\r
                                        android:onClick="onCheckClick"\r
                                        android:text="@string/oauth_check_onoff"\r
                                        android:textAppearance="?android:attr/textAppearanceSmall"\r
+                    android:contentDescription="@string/oauth_check_onoff"\r
                                        />\r
                \r
                                <EditText\r
                                        android:text="@string/oauth2_url_endpoint_auth"\r
                                        android:singleLine="true"\r
                                        android:inputType="textUri"\r
-                                       android:visibility="gone" >\r
+                                       android:visibility="gone">\r
                                </EditText>            \r
                                \r
                                <EditText\r
                                        android:text="@string/oauth2_url_endpoint_access"\r
                                        android:singleLine="true"\r
                                        android:inputType="textUri"\r
-                                       android:visibility="gone" >\r
+                                       android:visibility="gone">\r
                                        <requestFocus />\r
                                </EditText>            \r
                \r
                                        android:layout_height="wrap_content"\r
                                        android:ems="10"\r
                                        android:hint="@string/auth_username"\r
-                                       android:inputType="textNoSuggestions" />\r
+                                       android:inputType="textNoSuggestions"\r
+                                       android:contentDescription="@string/auth_username"/>\r
                \r
                                <EditText\r
                                    android:id="@+id/account_password"\r
                                        android:hint="@string/auth_password"\r
                                        android:inputType="textPassword"\r
                                        android:drawablePadding="5dp"\r
+                                       android:contentDescription="@string/auth_password"\r
                                        />\r
                        \r
                                <TextView\r
                                        android:text="@string/auth_unauthorized"\r
                                        android:drawableLeft="@android:drawable/stat_notify_sync"\r
                                        android:drawablePadding="5dip"\r
+                    android:contentDescription="@string/auth_unauthorized"\r
                                        />\r
 \r
                        </LinearLayout>\r
                    android:layout_gravity="center_horizontal"\r
                    android:enabled="false"\r
                    android:onClick="onOkClick"\r
-                   android:text="@string/setup_btn_connect" />\r
+                   android:text="@string/setup_btn_connect"\r
+            android:contentDescription="@string/setup_btn_connect"/>\r
                \r
                <Button\r
                    android:id="@+id/welcome_link"\r
                    android:paddingBottom="5dp"\r
                    android:paddingTop="5dp"\r
                    android:text="@string/auth_register"\r
-                   android:textColor="#0000FF"/>\r
+                   android:textColor="#0000FF"\r
+            android:contentDescription="@string/auth_register"/>\r
        </LinearLayout>\r
                \r
 </RelativeLayout>\r
index 95c7dfc..a85c3ee 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2014 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index f4d4fab..c67b9a9 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 
     ownCloud Android client application
-    Copyright (C) 2014 ownCloud Inc.
+    Copyright (C) 2015 ownCloud Inc.
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2,
index fcf5429..bd4b0b6 100644 (file)
@@ -2,7 +2,7 @@
 <!-- 
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index b2973a0..1f712ee 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
@@ -41,7 +41,8 @@
             android:layout_marginBottom="10dp"\r
             android:layout_marginTop="10dp"\r
             android:background="@color/login_logo_background_color"\r
-            android:src="@drawable/logo" />\r
+            android:src="@drawable/logo"\r
+            android:contentDescription="@string/app_name"/>\r
 \r
         <Button\r
             android:id="@+id/centeredRefreshButton"\r
@@ -51,7 +52,8 @@
             android:layout_marginBottom="10dp"\r
             android:onClick="onRefreshClick"\r
             android:text="@string/auth_check_server"\r
-            android:visibility="gone" />\r
+            android:visibility="gone"\r
+            android:contentDescription="@string/auth_check_server"/>\r
         \r
         <TextView\r
             android:id="@+id/instructions_message"\r
@@ -60,7 +62,8 @@
             android:layout_gravity="fill_horizontal"\r
             android:text="@string/auth_expired_basic_auth_toast"\r
             android:visibility="gone"\r
-            android:layout_marginBottom="10dp" />\r
+            android:layout_marginBottom="10dp"\r
+            android:contentDescription="@string/auth_expired_basic_auth_toast"/>\r
 \r
            <FrameLayout \r
                android:id="@+id/hostUrlFrame"\r
@@ -77,6 +80,7 @@
                                android:inputType="textUri"\r
                                android:drawablePadding="5dp"\r
                                android:paddingRight="55dp"\r
+                               android:contentDescription="@string/auth_host_address"\r
                                >\r
                                <requestFocus />\r
                        </EditText>\r
@@ -92,6 +96,7 @@
                android:onClick="onRefreshClick"\r
                                android:visibility="gone"\r
                                android:background="@android:color/transparent"\r
+                android:contentDescription="@string/auth_refresh_button"\r
                            />\r
                </FrameLayout>\r
 \r
             android:drawableLeft="@android:drawable/stat_notify_sync"\r
             android:drawablePadding="5dp"\r
             android:gravity="center_vertical"\r
-            android:text="@string/auth_testing_connection" />\r
+            android:text="@string/auth_testing_connection"\r
+            android:contentDescription="@string/auth_testing_connection"/>\r
 \r
         <CheckBox\r
             android:id="@+id/oauth_onOff_check"\r
             android:onClick="onCheckClick"\r
             android:text="@string/oauth_check_onoff"\r
             android:textAppearance="?android:attr/textAppearanceSmall"\r
+            android:contentDescription="@string/oauth_check_onoff"\r
             />\r
 \r
         <EditText\r
             android:text="@string/oauth2_url_endpoint_auth"\r
             android:singleLine="true"\r
             android:inputType="textUri"\r
-            android:visibility="gone" >\r
+            android:visibility="gone">\r
         </EditText>\r
 \r
         <EditText\r
             android:text="@string/oauth2_url_endpoint_access"\r
             android:singleLine="true"\r
             android:inputType="textUri"\r
-            android:visibility="gone" />\r
+            android:visibility="gone"/>\r
 \r
         <EditText\r
             android:id="@+id/account_username"\r
             android:layout_height="wrap_content"\r
             android:ems="10"\r
             android:hint="@string/auth_username"\r
-            android:inputType="textNoSuggestions" \r
+            android:inputType="textNoSuggestions"\r
+            android:contentDescription="@string/auth_username"\r
                        />\r
 \r
                <EditText\r
                    android:drawablePadding="5dp"\r
                    android:ems="10"\r
                    android:hint="@string/auth_password"\r
-                   android:inputType="textPassword" \r
+                   android:inputType="textPassword"\r
+                   android:contentDescription="@string/auth_password"\r
             />\r
         \r
         <TextView\r
             android:drawableLeft="@android:drawable/stat_notify_sync"\r
             android:drawablePadding="5dp"\r
             android:gravity="center_vertical"\r
-            android:text="@string/auth_unauthorized" />\r
+            android:text="@string/auth_unauthorized"\r
+            android:contentDescription="@string/auth_unauthorized"/>\r
 \r
         <Button\r
             android:id="@+id/buttonOK"\r
             android:layout_gravity="center_horizontal"\r
             android:enabled="false"\r
             android:onClick="onOkClick"\r
-            android:text="@string/setup_btn_connect" />\r
+            android:text="@string/setup_btn_connect"\r
+            android:contentDescription="@string/setup_btn_connect"/>\r
 \r
         <Button\r
             android:id="@+id/welcome_link"\r
             android:paddingBottom="5dp"\r
             android:paddingTop="5dp"\r
             android:text="@string/auth_register"\r
-            android:textColor="#0000FF"/>\r
+            android:textColor="#0000FF"\r
+            android:contentDescription="@string/auth_register"/>\r
 \r
     </LinearLayout>\r
 \r
index 0951958..940c3bc 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index b917600..9297bcd 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2014 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 500945b..875a40c 100644 (file)
@@ -3,7 +3,7 @@
     ownCloud Android client application
 
     Copyright (C) 2012  Bartek Przybylski
-    Copyright (C) 2012-2013 ownCloud Inc.
+    Copyright (C) 2015 ownCloud Inc.
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2,
index 56438e9..5d16b07 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index db41532..93983c2 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 8f571dc..0494b8a 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013  ownCloud Inc.
+  Copyright (C) 2015  ownCloud Inc.
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
   as published by the Free Software Foundation.
index 483a369..d371e10 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013  ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
   
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 50bc105..5d62c13 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 6db8377..0b11589 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+    <!--
+  ownCloud Android client application
+
+  Copyright (C) 2015 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
index 183f926..e684397 100644 (file)
@@ -2,7 +2,7 @@
 <!-- 
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 8bccde6..383c615 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 <!--\r
   ownCloud Android client application\r
-  Copyright (C) 2014 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index b494d48..d0f3d0f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 <!--\r
   ownCloud Android client application\r
-  Copyright (C) 2014 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 4564fbf..81b5210 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2015 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 0ea3bce..c66ff73 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index 629d8e2..0dbb9ef 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
+
+  Copyright (C) 2015 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/loadingLayout"
     android:layout_width="match_parent"
index d9326ff..2353b19 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
+
+  Copyright (C) 2015 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
index 6f129eb..756a2ed 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
+
+  Copyright (C) 2015 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
index f308edc..27900c4 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013  ownCloud Inc.
+  Copyright (C) 2015  ownCloud Inc.
   
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 1df31dc..ae2dbfa 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!-- 
     ownCloud Android client application
-    Copyright (C) 2014 ownCloud Inc.
+    Copyright (C) 2015 ownCloud Inc.
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2,
diff --git a/res/layout/password_dialog.xml b/res/layout/password_dialog.xml
new file mode 100644 (file)
index 0000000..b81e40b
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    ownCloud Android client application
+
+    Copyright (C) 2015 ownCloud Inc.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2,
+    as published by the Free Software Foundation.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <EditText
+        android:id="@+id/share_password"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:ems="10"
+               android:inputType="textPassword">
+    </EditText>
+
+</LinearLayout>
\ No newline at end of file
index b2cf5df..8c95c72 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
@@ -34,7 +34,8 @@
         android:textColor="@android:color/black"\r
         android:gravity="center_horizontal"\r
          />\r
-\r    <TextView\r
+\r
+    <TextView\r
         android:id="@+id/pinHdrExpl"\r
         android:layout_width="wrap_content"\r
         android:layout_height="wrap_content"\r
index ad0676b..52dadd7 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application\r
 \r
   Copyright (C) 2012  Bartek Przybylski\r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
index d712b7f..9baf6c2 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013  ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
   
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 9467d34..611351b 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013  ownCloud Inc.
+  Copyright (C) 2015  ownCloud Inc.
   
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
@@ -43,7 +43,7 @@
         android:layout_centerInParent="true"
         />
     
-    <com.owncloud.android.utils.TouchImageViewCustom
+    <third_parties.michaelOrtiz.TouchImageViewCustom
         android:id="@+id/image"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
index 6a30c2e..813d677 100644 (file)
@@ -2,7 +2,7 @@
 <!-- 
     ownCloud Android client application
 
-    Copyright (C) 2012-2013 ownCloud Inc.
+    Copyright (C) 2015 ownCloud Inc.
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2,
index 27204a2..f3153b3 100644 (file)
@@ -2,7 +2,7 @@
 <!-- 
     ownCloud Android client application
 
-    Copyright (C) 2012-2013 ownCloud Inc.
+    Copyright (C) 2015 ownCloud Inc.
 
     This program is free software: you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2,
index ccfb04b..652acb4 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 6c15ff7..42bdcdd 100644 (file)
@@ -2,7 +2,7 @@
 <!-- \r
   ownCloud Android client application\r
 \r
-  Copyright (C) 2012-2013 ownCloud Inc.\r
+  Copyright (C) 2015 ownCloud Inc.\r
 \r
   This program is free software: you can redistribute it and/or modify\r
   it under the terms of the GNU General Public License version 2,\r
     android:layout_height="fill_parent"\r
     android:background="@color/background_color"\r
     android:orientation="vertical" >\r
-
+\r
     <fragment\r
         android:id="@+id/local_files_list"\r
         android:layout_width="match_parent"\r
         android:layout_height="0dip"\r
         android:layout_weight="1"\r
         class="com.owncloud.android.ui.fragment.LocalFileListFragment" />\r
-
+\r
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:layout_height="wrap_content"\r
         android:gravity="center"\r
         android:orientation="horizontal" >\r
-\r        <Button\r
+\r
+        <Button\r
             android:id="@+id/upload_files_btn_cancel"\r
             android:layout_width="wrap_content"\r
             android:layout_height="wrap_content"\r
             android:layout_weight="1"\r
             android:text="@string/common_cancel" />\r
-\r              <Button\r
+\r
+               <Button\r
                    android:id="@+id/upload_files_btn_upload"\r
                    android:layout_width="wrap_content"\r
                    android:layout_height="wrap_content"\r
index ff27429..60a2111 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
                        android:layout_height="fill_parent" android:divider="@drawable/uploader_list_separator"
                        android:dividerHeight="1dip"></ListView>
        </FrameLayout>
-       <LinearLayout android:id="@+id/linearLayout1"
-               android:layout_width="fill_parent" android:layout_alignParentBottom="true" android:layout_height="wrap_content" android:orientation="vertical">
-               <Button android:layout_gravity="bottom" android:layout_height="wrap_content"
-                       android:layout_width="fill_parent" android:id="@+id/uploader_choose_folder"
-                       android:text="@string/uploader_btn_upload_text"/>
+
+       <LinearLayout
+           android:id="@+id/linearLayout1"
+           android:layout_width="fill_parent"
+           android:layout_height="wrap_content"
+           android:layout_alignParentBottom="true"
+           android:orientation="horizontal" >
+
+               <Button
+                   android:id="@+id/uploader_new_folder"
+                   android:layout_width="fill_parent"
+                   android:layout_height="wrap_content"
+                   android:layout_gravity="bottom"
+                   android:layout_weight="1"
+                   android:text="@string/uploader_btn_new_folder_text" />
+               
+               <Button
+                   android:id="@+id/uploader_choose_folder"
+                   android:layout_width="fill_parent"
+                   android:layout_height="wrap_content"
+                   android:layout_gravity="bottom"
+                   android:layout_weight="1"
+                   android:text="@string/uploader_btn_upload_text" />
+
        </LinearLayout>
 </RelativeLayout>
index 08f9cee..e093269 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 8063ab4..ac0ca6a 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
+
+  Copyright (C) 2015 ownCloud Inc.
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License version 2,
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+-->
 <FrameLayout   xmlns:android="http://schemas.android.com/apk/res/android"
                                android:layout_width="match_parent"
                                android:layout_height="match_parent" >
index b7e2dd3..df83e37 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index b60d542..545f8ea 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index b738322..d35eba0 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
         android:icon="@drawable/ic_action_upload"
         android:orderInCategory="2"
         android:showAsAction="always"
-        android:title="@string/actionbar_upload"/>
+        android:title="@string/actionbar_upload"
+        android:contentDescription="@string/actionbar_upload"/>
     <item
         android:id="@+id/action_create_dir"
         android:icon="@drawable/ic_action_create_dir"
         android:orderInCategory="2"
         android:showAsAction="always"
-        android:title="@string/actionbar_mkdir"/>
+        android:title="@string/actionbar_mkdir"
+        android:contentDescription="@string/actionbar_mkdir"/>
     <item
         android:id="@+id/action_sync_account"
         android:icon="@drawable/ic_action_refresh"
         android:orderInCategory="2"
         android:showAsAction="never"
-        android:title="@string/actionbar_sync"/>
+        android:title="@string/actionbar_sync"
+        android:contentDescription="@string/actionbar_sync"/>
     <item
         android:id="@+id/action_settings"
         android:icon="@drawable/ic_action_settings"
         android:orderInCategory="2"
         android:showAsAction="never"
-        android:title="@string/actionbar_settings"/>
+        android:title="@string/actionbar_settings"
+        android:contentDescription="@string/actionbar_settings"/>
     <item
         android:id="@+id/action_logger"
         android:icon="@drawable/ic_action_settings"
         android:orderInCategory="2"
         android:showAsAction="never"
-        android:title="@string/actionbar_logger"/>
+        android:title="@string/actionbar_logger"
+        android:contentDescription="@string/actionbar_logger"/>
        <item
         android:id="@+id/action_sort"
         android:icon="@android:drawable/ic_menu_sort_alphabetically"
         android:orderInCategory="2"
         android:showAsAction="never"
-        android:title="@string/actionbar_sort"/>
+        android:title="@string/actionbar_sort"
+        android:contentDescription="@string/actionbar_sort"/>
 
     <!-- <item android:id="@+id/search" android:title="@string/actionbar_search" android:icon="@drawable/ic_action_search"></item> -->
 
index a54a664..d651120 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
 -->
        <body>
        <p>
-               Dieses Gerät läuft mit Android 4.1.x.
+               Dieses Ger�t l�uft mit Android 4.1.x.
        </p>
        <p>
-               In dieser Version von Android existiert ein Bug, der nach jedem Neustart eine erneute Eingabe der ownCloud Login-Informationen nötig macht. Um das zu umgehen installieren Sie bitte diese kostenlose Hilfs-App: 
+               In dieser Version von Android existiert ein Bug, der nach jedem Neustart eine erneute Eingabe der ownCloud Login-Informationen ntig macht. Um das zu umgehen installieren Sie bitte diese kostenlose Hilfs-App: 
        </p>
        <p style="text-align:center">
                <a href="http://play.google.com/store/apps/details?id=com.owncloud.android.workaround.accounts">ownCloud Jelly Bean Workaround</a> 
index 9321d52..e8f0e77 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
@@ -21,7 +21,7 @@
                Su dispositivo ejecuta Android 4.1.x. 
        </p>
        <p>
-               Para prevenir la pérdida de las credenciales de sus cuentas ownCloud en cada reinicio, por favor, instale esta app gratuita que evita el problema en Jelly Bean:        
+               Para prevenir la p�rdida de las credenciales de sus cuentas ownCloud en cada reinicio, por favor, instale esta app gratuita que evita el problema en Jelly Bean:      
        </p>
        <p style="text-align:center">
                <a href="http://play.google.com/store/apps/details?id=com.owncloud.android.workaround.accounts">ownCloud Jelly Bean Workaround</a>
index 754cf6f..fd5a20d 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 49d6c3c..f576de4 100644 (file)
   <string name="auth_no_net_conn_title">لا يتوفر اتصال</string>
   <string name="auth_nossl_plain_ok_title">الاتصال الآمن غير متاح</string>
   <string name="auth_connection_established">تم الاتصال</string>
-  <string name="auth_testing_connection">اختبار الاتصال ...</string>
   <string name="auth_not_configured_title">إعداد الخادم غير صحيحة</string>
   <string name="auth_account_not_new">الحساب لنفس المستخدم والخادم موجود مسبقا على الجهاز </string>
   <string name="auth_account_not_the_same">المستخدم المدخل لا يتوافق مع المستخدم الموجود في الحساب </string>
   <string name="saml_authentication_wrong_pass">كلمة مرور خاطئة</string>
   <string name="folder_picker_choose_button_text">اختيار</string>
   <string name="prefs_category_security">الأمان</string>
+  <string name="auth_host_address">عنوان الخادم</string>
 </resources>
index d3a9060..b1c03f5 100644 (file)
   <string name="actionbar_settings">Quraşdırmalar</string>
   <string name="actionbar_see_details">Detallar</string>
   <string name="actionbar_send_file">Göndər</string>
+  <string name="actionbar_sort">Çeşidləmək</string>
+  <string name="actionbar_sort_title">Təyinata görə çeşidləmək </string>
+  <string-array name="actionbar_sortby">
+    <item>A-Z</item>
+    <item>Yenisi - Köhnəsi</item>
+  </string-array>
   <!--TODO re-enable when server-side folder size calculation is available   
        <item>Biggest - Smallest</item>-->
   <string name="prefs_category_general">Ümumi</string>
@@ -32,6 +38,8 @@
   <string name="prefs_recommend">Dostuna məsləhət gör</string>
   <string name="prefs_feedback">Geriyə cavab</string>
   <string name="prefs_imprint">İşarələmək</string>
+  <string name="prefs_remember_last_share_location">Paylaşma ünvanını yadda saxla</string>
+  <string name="prefs_remember_last_upload_location_summary">Son paylaşılmış yüklənmə ünvanını yadda saxla</string>
   <string name="recommend_subject">%1$s-i ağıllı telefonunuzda yoxlayın!</string>
   <string name="recommend_text">Mən sizi öz smartfonunuzda %1$s istifadə etmək üçün dəvət etmək istəyirəm! Burdan endirin: %2$s</string>
   <string name="auth_check_server">Serveri yoxla</string>
   <string name="uploader_wrn_no_content_text">Heç bir kontent gəlmədi. Yukləmək üçün heçnə yoxdur.</string>
   <string name="uploader_error_forbidden_content">%1$s yayımlanmış kontent üçün yetkili deyil</string>
   <string name="uploader_info_uploading">Yüklənmə gedir</string>
+  <string name="file_list_seconds_ago">saniyələr öncə</string>
   <string name="file_list_empty">Burda heçnə yoxdur. Nese yükləyin!</string>
   <string name="file_list_loading">Yüklənir...</string>
   <string name="local_file_list_empty">Bu qovluqda heç bir fayl movcud deyil.</string>
+  <string name="file_list_folder">qovluq</string>
+  <string name="file_list_folders">qovluqlar</string>
+  <string name="file_list_file">fayl</string>
+  <string name="file_list_files">fayllar</string>
   <string name="filedetails_select_file">Faylın üstünə sıxın ki, əlavə məlumat ekrana çıxsın.</string>
   <string name="filedetails_size">Həcm:</string>
   <string name="filedetails_type">Tip:</string>
@@ -151,7 +164,7 @@ Aşağıda göstərilən %5$s-də olan daxili və xarici fayl(lar) link edilmiş
   <string name="auth_no_net_conn_title">Şəbəkə qoşulması yoxdur</string>
   <string name="auth_nossl_plain_ok_title">Təhlükəsiz qoşulma mümkün deyil.</string>
   <string name="auth_connection_established">Əlaqə quruldu</string>
-  <string name="auth_testing_connection">Qoşulma test edilir...</string>
+  <string name="auth_testing_connection">Qoşulma test edilir</string>
   <string name="auth_not_configured_title">Yalnış qurulmuş server konfiqurasiyası</string>
   <string name="auth_account_not_new">Avadanlıqda eyni istifadəçi və server üçün artıq hesab mövcuddur</string>
   <string name="auth_account_not_the_same">Daxil edilən hesab bu hesabla üst-üstə düşmür</string>
@@ -177,6 +190,7 @@ Aşağıda göstərilən %5$s-də olan daxili və xarici fayl(lar) link edilmiş
   <string name="auth_unsupported_multiaccount">%1$s çoxlu hesab dəstəkləmir</string>
   <string name="auth_fail_get_user_name">Sizin server düzgün istifadəçi id-si qaytarmır, xahiş olunur inzibatçı ilə əlaqə saxlayasınız</string>
   <string name="auth_can_not_auth_against_server">Bu serverdə yenidən qeydiyyatdan keçmək olmur</string>
+  <string name="auth_account_does_not_exist">Hesab göstərilən avadanlıqda mövcud deyil</string>
   <string name="fd_keep_in_sync">Faylı gündəmdə saxla</string>
   <string name="common_rename">Adı dəyiş</string>
   <string name="common_remove">Sil</string>
@@ -206,18 +220,92 @@ Aşağıda göstərilən %5$s-də olan daxili və xarici fayl(lar) link edilmiş
   <string name="ssl_validator_reason_cert_not_trusted">Server sertifikati inamlı deyil</string>
   <string name="ssl_validator_reason_cert_expired">- Server sertifikatının vaxtı bitmişdir</string>
   <string name="ssl_validator_reason_cert_not_yet_valid">- Server sertifikatının düzgün tarixi gələcəkdədir</string>
+  <string name="ssl_validator_reason_hostname_not_verified">URL sertifikatda olan host adına uyğun deyil</string>
+  <string name="ssl_validator_question">İstənilən halda bu sertifikata inanmaq istəyirsinizmi?</string>
+  <string name="ssl_validator_not_saved">Sertifikat saxlanıla bilməz</string>
   <string name="ssl_validator_btn_details_see">Detallar</string>
+  <string name="ssl_validator_btn_details_hide">Gizlə</string>
+  <string name="ssl_validator_label_subject">Verilir:</string>
+  <string name="ssl_validator_label_issuer">Tərəfindən verilib:</string>
+  <string name="ssl_validator_label_CN">Ümumi ad:</string>
+  <string name="ssl_validator_label_O">Təşkilat:</string>
+  <string name="ssl_validator_label_OU">Alt təşkilatOrganizational unit:</string>
+  <string name="ssl_validator_label_C">Ölkə:</string>
+  <string name="ssl_validator_label_ST">Dövlət:</string>
+  <string name="ssl_validator_label_L">Ərazi:</string>
+  <string name="ssl_validator_label_validity">Etibarlılıq:</string>
+  <string name="ssl_validator_label_validity_from">Kimdən:</string>
+  <string name="ssl_validator_label_validity_to">Kimə:</string>
+  <string name="ssl_validator_label_signature">İmza:</string>
+  <string name="ssl_validator_label_signature_algorithm">Alqıritm:</string>
+  <string name="ssl_validator_null_cert">Sertifikat görünə bilməz.</string>
+  <string name="ssl_validator_no_info_about_error">- Səhv haqqında məlumat yoxdur</string>
+  <string name="placeholder_sentence">Bu bir yer doldurucusudur</string>
+  <string name="placeholder_filename">yerdoldurucusu.txt</string>
+  <string name="placeholder_filetype">PNG Şəkil</string>
+  <string name="placeholder_filesize">389 KB</string>
+  <string name="placeholder_timestamp">2012/05/18 12:23</string>
+  <string name="placeholder_media_time">12:23:45</string>
+  <string name="instant_upload_on_wifi">Şəkilləri yalnız WiFi üzərindən yüklə</string>
+  <string name="instant_video_upload_on_wifi">Videoları yalnız WiFi üzərindən yüklə</string>
+  <string name="instant_upload_path">/CəldYükləmə</string>
+  <string name="conflict_title">Yüklənmə konflikti</string>
+  <string name="conflict_message">Uzaq fayl %s local faylla sinxronizasiya edilmədi. Faylın kontentinin serverdə dəyişdirilməsinə davam edirik.</string>
+  <string name="conflict_keep_both">Birlikdə saxla</string>
+  <string name="conflict_overwrite">Sil yenidən yaz</string>
+  <string name="conflict_dont_upload">Yükləmə</string>
+  <string name="preview_image_description">Şəkili göstər</string>
+  <string name="preview_image_error_unknown_format">Bu şəkil göstərilə bilməz</string>
+  <string name="error__upload__local_file_not_copied">%1$s nüsxələnə bilməz %2$s local qovluğa</string>
+  <string name="prefs_instant_upload_path_title">Yüklənmə ünvanı</string>
+  <string name="share_link_no_support_share_api">Üzr istəyirik, sizin yerverdə paylaşıma izin verilmir. Xahiş olunur
+inzibatçınızla əlaqə saxlayasınız.</string>
+  <string name="share_link_file_no_exist">Paylaşa bilinmir.</string>
+  <string name="share_link_file_error">Bu faylın yada qovluğun paylaşımı zamanı səhv baş verdi </string>
+  <string name="unshare_link_file_no_exist">Paylaşımı dayandırmaq olmur. Xahiş olunur fayl mövcudluğunu yoxlayasınız</string>
   <string name="unshare_link_file_error">Bu fayl və ya qovluğun yayımlanmasının dayandırılmasında səhv baş verdi</string>
+  <string name="share_link_password_title">Şifrəni daxil et</string>
+  <string name="share_link_empty_password">Siz şifrəni daxil etməlisiniz</string>
   <string name="activity_chooser_send_file_title">Göndər</string>
   <string name="copy_link">linki nüsxələ</string>
   <string name="clipboard_text_copied">Mübadilə buferinə nüsxələndi</string>
+  <string name="error_cant_bind_to_operations_service">Kritik səhv: əməliyyat yerinə yetirilə bilinmir</string>
+  <string name="network_error_socket_exception">Serverlə əlaqəyə girdikdə səhv baş verdi.</string>
+  <string name="network_error_socket_timeout_exception">Serveri gözlədiyimiz müddətdə səhv baş verdi, əməliyyat bitə bilməz</string>
+  <string name="network_error_connect_timeout_exception">Serveri gözlədiyimiz müddətdə səhv baş verdi, əməliyyat bitə bilməz</string>
+  <string name="network_host_not_available">Əməliyyat bitə bilməz, serverə çatmaq mümkün deyil </string>
   <string name="empty"></string>
   <string name="forbidden_permissions">Sizin yetkiniz yoxdur %s</string>
+  <string name="forbidden_permissions_rename">faylın adını dəyişmək</string>
   <string name="forbidden_permissions_delete">bu faylı silmək üçün</string>
   <string name="share_link_forbidden_permissions">bu faylı yayımlamaq üçün</string>
+  <string name="unshare_link_forbidden_permissions">fayl paylaşımını dayandırmaq</string>
   <string name="forbidden_permissions_create">fayl yaratmaq üçün</string>
   <string name="uploader_upload_forbidden_permissions">bu qovluğa yükləmək üçün</string>
+  <string name="downloader_download_file_not_found">Bu fayla serverdə artıq uzun müddətdir ki, çatmaq mümkün deyil</string>
   <string name="prefs_category_accounts">Hesablar</string>
   <string name="prefs_add_account">Hesab əlavə et</string>
+  <string name="auth_redirect_non_secure_connection_title">Təhlükəsiz qoşulma, təhlükəsiz olmayan istiqamətə yönlədirilmişdir</string>
+  <string name="actionbar_logger">Jurnallar</string>
+  <string name="log_send_history_button">Tarixçəni göndər</string>
+  <string name="log_send_no_mail_app">Jurnalların ötürülməsi üçün proqram təminatı tapılmadı!</string>
+  <string name="log_send_mail_subject">%1$s Android proqram jurnalları</string>
+  <string name="log_progress_dialog_text">Data yüklənir...</string>
+  <string name="saml_authentication_required_text">Qeydiyyat tələb edilir</string>
   <string name="saml_authentication_wrong_pass">Yalnış şifrə</string>
+  <string name="actionbar_move">Köçürmək</string>
+  <string name="file_list_empty_moving">Burda heçnə yoxdur. Siz qovluq əlavə edə bilərsiniz!</string>
+  <string name="folder_picker_choose_button_text">Seç</string>
+  <string name="move_file_not_found">Köçürmə mümkün olmur. Xahiş olunur faylın mövcudluğunu yoxlayasınız.</string>
+  <string name="move_file_invalid_into_descendent">Qovluğu bu nəsilə köçürmək mümkün deyil</string>
+  <string name="move_file_invalid_overwrite">Fayl artıq mənsəb qovluğunda mövcuddur</string>
+  <string name="move_file_error">Fayl və ya qovluğun köçürülməsi müddətində səhv baş verdi</string>
+  <string name="forbidden_permissions_move">bu faylı köçürtmək</string>
+  <string name="prefs_category_instant_uploading">Anında yükləmələr</string>
+  <string name="prefs_category_security">Təhlükəsizlik</string>
+  <string name="prefs_instant_video_upload_path_title">Video ünvanını yüklə</string>
+  <string name="download_folder_failed_content">Qovluğun endirilməsinin %1$s hissəsi tamamlana bilməz </string>
+  <string name="subject_token">%1$s paylaşdı \"%2$s\" sizinlə</string>
+  <string name="auth_refresh_button">Qoşulmanı yenilə</string>
+  <string name="auth_host_address">Server ünvanı</string>
 </resources>
index 27178f2..04fe846 100644 (file)
   <string name="auth_no_net_conn_title">Няма интернет връзка</string>
   <string name="auth_nossl_plain_ok_title">Няма сигурна връзка</string>
   <string name="auth_connection_established">Осъществена връзка</string>
-  <string name="auth_testing_connection">Проверка на свързаност...</string>
   <string name="auth_not_configured_title">Неправилно зададена сървърна конфигурация.</string>
   <string name="auth_account_not_new">Профил за същия потребител на същия сървър е вече настроен на устройството.</string>
   <string name="auth_account_not_the_same">Въведният потребител не съвпада с потребителя на профила.</string>
   <string name="auth_redirect_non_secure_connection_title">Сигурна връзка е пренасочена по несигурен път.</string>
   <string name="actionbar_logger">Доклади</string>
   <string name="log_send_history_button">Изпрати История</string>
+  <string name="log_send_no_mail_app">Не са намерени журнали за изпращане от приложението. Инсталирайте приложението за електронна поща!</string>
+  <string name="log_send_mail_subject">%1$s Android журнали на приложенията</string>
+  <string name="log_progress_dialog_text">Зареждане на данни...</string>
   <string name="saml_authentication_required_text">Нужна е идентификация</string>
   <string name="saml_authentication_wrong_pass">Грешна парола</string>
   <string name="actionbar_move">Премести</string>
   <string name="forbidden_permissions_move">за да преместиш този файл</string>
   <string name="prefs_category_instant_uploading">Незабавно качване</string>
   <string name="prefs_category_security">Сигурност</string>
+  <string name="prefs_instant_video_upload_path_title">Качване на видео път</string>
+  <string name="download_folder_failed_content">Свалянето на директорията %1$s не може да бъде завършено</string>
+  <string name="auth_host_address">Адрес на сървъра</string>
 </resources>
index 49e04b4..f74ae50 100644 (file)
   <string name="auth_no_net_conn_title">নেটওয়ার্ক সংযোগ নেই</string>
   <string name="auth_nossl_plain_ok_title">নিরাপদ যোগাযোগ পাওয়া গেলনা</string>
   <string name="auth_connection_established">যোগাযোগ স্থাপিত হয়েছে</string>
-  <string name="auth_testing_connection">যোগাযোগ পরীক্ষা করা হচ্ছে...</string>
   <string name="auth_not_configured_title">সার্ভারের কনফিগারেশনে ভুল রয়েছে</string>
   <string name="auth_account_not_new">এই যন্ত্রে ইতোমধ্যে এই ব্যবহারকারী এবং সার্ভারের নামে একটি একাউন্ট রয়েছে</string>
   <string name="auth_account_not_the_same">এই একাউন্টের ব্যবহারকারীর সঙ্গে প্রদত্ত ব্যবহারকারী মেলেনা</string>
   <string name="folder_picker_choose_button_text">বেছে নিন</string>
   <string name="move_file_not_found">সরাতে ব্যার্থ হলো। ফাইলটি রয়েছে কিনা দেখুন।</string>
   <string name="prefs_category_security">নিরাপত্তা</string>
+  <string name="auth_host_address">সার্ভার ঠিকানা</string>
 </resources>
index 9ab386c..2ce6b08 100644 (file)
@@ -31,4 +31,5 @@
   <string name="saml_authentication_wrong_pass">Pogrešna lozinka</string>
   <string name="folder_picker_choose_button_text">Izaberite</string>
   <string name="prefs_category_security">Sigurnost</string>
+  <string name="auth_host_address">Adresa servera</string>
 </resources>
index d0cd67a..6544ab3 100644 (file)
   <string name="auth_no_net_conn_title">Sense connexió de xarxa</string>
   <string name="auth_nossl_plain_ok_title">La connexió segura no està disponible.</string>
   <string name="auth_connection_established">S\'ha establert la connexió</string>
-  <string name="auth_testing_connection">S\'està comprovant la connexió...</string>
   <string name="auth_not_configured_title">La configuració del servidor està malformada</string>
   <string name="auth_account_not_new">Ja hi ha un compte al dispositiu pel mateix usuari i mateix servidor</string>
   <string name="auth_account_not_the_same">L\'usuari introduït no coincideix amb l\'usuari d\'aquest compte</string>
   <string name="downloader_download_file_not_found">El fitxer ja no està disponible en el servidor</string>
   <string name="prefs_category_accounts">Comptes</string>
   <string name="prefs_add_account">Afegeix compte</string>
+  <string name="log_progress_dialog_text">Carregant dades...</string>
   <string name="saml_authentication_required_text">Es requereix autenticació</string>
   <string name="saml_authentication_wrong_pass">Contrasenya incorrecta</string>
+  <string name="actionbar_move">Moure</string>
   <string name="folder_picker_choose_button_text">Escull</string>
   <string name="prefs_category_security">Seguretat</string>
+  <string name="auth_host_address">Adreça del servidor</string>
 </resources>
index aabb2fe..bf3838c 100644 (file)
@@ -40,7 +40,7 @@
   <string name="prefs_imprint">Imprint</string>
   <string name="prefs_remember_last_share_location">Zapamatovat umístění sdílení</string>
   <string name="prefs_remember_last_upload_location_summary">Zapamatovat poslední umístění pro nahrání sdílených souborů</string>
-  <string name="recommend_subject">Zkuste %1$s na vašem smartphonu!</string>
+  <string name="recommend_subject">Zkuste %1$s na svém chytrém telefonu!</string>
   <string name="recommend_text">Chtěl bych vás pozvat k používání %1$s na vašem chytrém telefonu!\nKe stažení zde: %2$s</string>
   <string name="auth_check_server">Zkontrolovat server</string>
   <string name="auth_host_url">Adresa serveru https://...</string>
   <string name="auth_no_net_conn_title">Žádné síťové spojení</string>
   <string name="auth_nossl_plain_ok_title">Zabezpečené spojení není k dispozici</string>
   <string name="auth_connection_established">Spojení navázáno</string>
-  <string name="auth_testing_connection">Zkouším spojení...</string>
+  <string name="auth_testing_connection">Testuje se připojení</string>
   <string name="auth_not_configured_title">Neplatné nastavení serveru</string>
   <string name="auth_account_not_new">Účet pro stejného uživatele a server již v zařízení existuje</string>
   <string name="auth_account_not_the_same">Zadaný uživatel neodpovídá uživateli tohoto účtu</string>
   <string name="auth_oauth_error">Neúspěšné přihlášení</string>
   <string name="auth_oauth_error_access_denied">Přístup zamítnut autorizačním serverem</string>
   <string name="auth_wtf_reenter_URL">Neočekávaný stav; prosím vložte znovu URL adresu serveru</string>
-  <string name="auth_expired_oauth_token_toast">Vaše přihlášení vypršelo. Přihlašte se, prosím, znovu</string>
+  <string name="auth_expired_oauth_token_toast">Vaše přihlášení vypršelo. Přihlaste se prosím znovu</string>
   <string name="auth_expired_basic_auth_toast">Zadejte prosím aktuální heslo</string>
-  <string name="auth_expired_saml_sso_token_toast">Vaše přihlášení vypršelo. Přihlašte se, prosím, znovu</string>
+  <string name="auth_expired_saml_sso_token_toast">Vaše přihlášení vypršelo. Přihlaste se prosím znovu</string>
   <string name="auth_connecting_auth_server">Připojuji se k přihlašovacímu serveru...</string>
   <string name="auth_unsupported_auth_method">Server nepodporuje tuto přihlašovací metodu</string>
   <string name="auth_unsupported_multiaccount">%1$s nepodporuje více účtů</string>
   <string name="auth_fail_get_user_name">Váš server nevrací správné přihlašovací ID, kontaktujte prosím svého správce systému</string>
   <string name="auth_can_not_auth_against_server">Není možné provést ověření  </string>
+  <string name="auth_account_does_not_exist">V zařízení není zatím nastaven účet</string>
   <string name="fd_keep_in_sync">Udržovat soubor aktuální</string>
   <string name="common_rename">Přejmenovat</string>
   <string name="common_remove">Odstranit</string>
@@ -259,6 +260,8 @@ správce systému.</string>
   <string name="share_link_file_error">Při pokusu o sdílení tohoto souboru či složky nastala chyba</string>
   <string name="unshare_link_file_no_exist">Nelze ukončit sdílení. Zkontrolujte prosím že soubor existuje</string>
   <string name="unshare_link_file_error">Při pokusu o zrušení sdílení tohoto souboru či složky nastala chyba</string>
+  <string name="share_link_password_title">Zadejte heslo</string>
+  <string name="share_link_empty_password">Musíte zadat heslo</string>
   <string name="activity_chooser_send_file_title">Odeslat</string>
   <string name="copy_link">Zkopírovat odkaz</string>
   <string name="clipboard_text_copied">Zkopírováno do schránky</string>
@@ -298,4 +301,7 @@ správce systému.</string>
   <string name="prefs_category_security">Zabezpečení</string>
   <string name="prefs_instant_video_upload_path_title">Cesta pro nahrávání videí</string>
   <string name="download_folder_failed_content">Stažení adresáře %1$s nemohlo být dokončeno</string>
+  <string name="subject_token">%1$s sdílí \"%2$s\" s vámi</string>
+  <string name="auth_refresh_button">Obnovit připojení</string>
+  <string name="auth_host_address">Adresa serveru</string>
 </resources>
index 4852e56..bce96c9 100644 (file)
   <string name="auth_no_net_conn_title">Ingen netværksforbindelse</string>
   <string name="auth_nossl_plain_ok_title">Sikker forbindelse ikke tilgængelig.</string>
   <string name="auth_connection_established">Forbindelse oprettet</string>
-  <string name="auth_testing_connection">Afprøver forbindelse ...</string>
+  <string name="auth_testing_connection">Tester forbindelsen</string>
   <string name="auth_not_configured_title">Misdannet server konfiguration</string>
   <string name="auth_account_not_new">En konto for den samme bruger og server eksisterer allerede på enheden</string>
   <string name="auth_account_not_the_same">Den indtastede bruger passer ikke til brugeren for denne konto</string>
   <string name="auth_unsupported_multiaccount">%1$s understøtter ikke multiple konti</string>
   <string name="auth_fail_get_user_name">Din server retunere ikke et korrekt bruger-id. Kontakt venligst din administrator</string>
   <string name="auth_can_not_auth_against_server">Kan ikke autentificere mod denne server</string>
+  <string name="auth_account_does_not_exist">Kontoen findes endnu ikke på enheden</string>
   <string name="fd_keep_in_sync">Hold filen opdateret</string>
   <string name="common_rename">Omdøb</string>
   <string name="common_remove">Fjern</string>
   <string name="share_link_file_error">Der opstod en fejl ved deling af denne fil eller mappe</string>
   <string name="unshare_link_file_no_exist">Kan ikke fjerne deling. Tjek venligst om filen findes.</string>
   <string name="unshare_link_file_error">Der opstod en fejl ved stopning af deling af denne mappe.</string>
+  <string name="share_link_password_title">Angiv et kodeord</string>
+  <string name="share_link_empty_password">Du skal angive et kodeord</string>
   <string name="activity_chooser_send_file_title">Send</string>
   <string name="copy_link">Kopiér link</string>
   <string name="clipboard_text_copied">Kopieret til udklipsholder</string>
   <string name="prefs_category_security">Sikkerhed</string>
   <string name="prefs_instant_video_upload_path_title">Sti til videoupload</string>
   <string name="download_folder_failed_content">Download af %1$s mappe kunne ikke fuldføres</string>
+  <string name="subject_token">%1$s delt \"%2$s\" med dig</string>
+  <string name="auth_refresh_button">Genopfrisk forbindelsen</string>
+  <string name="auth_host_address">Serveradresse</string>
 </resources>
index 8a65cc1..86f45e3 100644 (file)
@@ -12,4 +12,5 @@
   <string name="common_cancel">Abbrechen</string>
   <string name="common_error">Fehler</string>
   <string name="empty"></string>
+  <string name="auth_host_address">Adresse des Servers</string>
 </resources>
index 04f4f07..6f4d69b 100644 (file)
   <string name="auth_no_net_conn_title">Keine Netzwerkverbindung</string>
   <string name="auth_nossl_plain_ok_title">Sichere Verbindung nicht verfügbar.</string>
   <string name="auth_connection_established">Verbindung hergestellt</string>
-  <string name="auth_testing_connection">Verbindungstest …</string>
+  <string name="auth_testing_connection">Verbindung testen</string>
   <string name="auth_not_configured_title">Fehlerhafte Server Konfiguration</string>
   <string name="auth_account_not_new">Ein Benutzerkonto für den gleichen Benutzer und Server existiert auf diesem Gerät bereits</string>
   <string name="auth_account_not_the_same">Der eingegebene Benutzer passt nicht zu dem Benutzer dieses Benutzerkontos</string>
   <string name="auth_fail_get_user_name">Ihr Server gibt keine richtige Benutzerkennung zurück, bitte kontaktieren Sie einen Administrator
 ⇥</string>
   <string name="auth_can_not_auth_against_server">Die Legitimierung gegenüber dem Server konnte nicht durchgeführt werden</string>
+  <string name="auth_account_does_not_exist">Das Benutzerkonto ist bis jetzt noch nicht auf dem Gerät vorhanden</string>
   <string name="fd_keep_in_sync">Datei aktuell halten</string>
   <string name="common_rename">Umbenennen</string>
   <string name="common_remove">Löschen</string>
   <string name="share_link_file_error">Es ist ein Fehler beim Freigeben der Datei oder des Ordners aufgetreten.</string>
   <string name="unshare_link_file_no_exist">Entfernen der Freigabe nicht möglich. Prüfen Sie, ob die Datei existiert</string>
   <string name="unshare_link_file_error">Es ist ein Fehler beim Entfernen der Freigabe für diese Datei oder den Ordner aufgetreten.</string>
+  <string name="share_link_password_title">Passwort eingeben</string>
+  <string name="share_link_empty_password">Sie müssen ein Passwort eingeben</string>
   <string name="activity_chooser_send_file_title">Senden</string>
   <string name="copy_link">Link kopieren</string>
   <string name="clipboard_text_copied">In die Zwischenablage kopiert</string>
   <string name="prefs_category_security">Sicherheit</string>
   <string name="prefs_instant_video_upload_path_title">Verzeichnis zum Hochladen der Videos</string>
   <string name="download_folder_failed_content">Herunterladen des %1$s - Ordners konnte nicht abgeschlossen werden</string>
+  <string name="subject_token">%1$s hat „%2$s“ mit Ihnen geteilt</string>
+  <string name="auth_refresh_button">Verbindung aktualisieren</string>
+  <string name="auth_host_address">Serveradresse</string>
 </resources>
index d810f60..f44bdf7 100644 (file)
@@ -43,7 +43,7 @@
   <string name="recommend_subject">Probiere %1$s auf Deinem Smartphone!</string>
   <string name="recommend_text">Ich möchte Dich zum Benutzen von %1$s auf Deinem Smartphone einladen!\nLade es hier herunter: %2$s</string>
   <string name="auth_check_server">Überprüfe den Server</string>
-  <string name="auth_host_url">Server-Adresse https://…</string>
+  <string name="auth_host_url">Serveradresse https://…</string>
   <string name="auth_username">Benutzername</string>
   <string name="auth_password">Passwort</string>
   <string name="auth_register">Ist %1$s neu für dich?</string>
@@ -61,7 +61,7 @@
   <string name="uploader_info_uploading">Lade hoch</string>
   <string name="file_list_seconds_ago">Gerade eben</string>
   <string name="file_list_empty">Alles leer. Lade etwas hoch!</string>
-  <string name="file_list_loading">Ladevorgang …</string>
+  <string name="file_list_loading">Laden…</string>
   <string name="local_file_list_empty">Es befinden sich keine Dateien in diesem Ordner.</string>
   <string name="file_list_folder">Ordner</string>
   <string name="file_list_folders">Ordner</string>
@@ -75,7 +75,7 @@
   <string name="filedetails_download">Herunterladen</string>
   <string name="filedetails_sync_file">Datei aktualisieren</string>
   <string name="filedetails_renamed_in_upload_msg">Datei wurde wärend des Uploads zu %1$s umbenannt</string>
-  <string name="action_share_file">Link Teilen</string>
+  <string name="action_share_file">Link teilen</string>
   <string name="action_unshare_file">Link nicht mehr freigeben</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nein</string>
   <string name="common_cancel">Abbrechen</string>
   <string name="common_save_exit">Speichern &amp; schließen</string>
   <string name="common_error">Fehler</string>
-  <string name="common_loading">Lädt ...</string>
+  <string name="common_loading">Lade…</string>
   <string name="common_error_unknown">Unbekannter Fehler</string>
   <string name="about_title">Über</string>
   <string name="change_password">Passwort ändern</string>
   <string name="delete_account">Account löschen</string>
   <string name="create_account">Account erstellen</string>
-  <string name="upload_chooser_title">Dateien hochladen von...</string>
+  <string name="upload_chooser_title">Dateien hochladen von</string>
   <string name="uploader_info_dirname">Ordnername</string>
-  <string name="uploader_upload_in_progress_ticker">Hochladen...</string>
+  <string name="uploader_upload_in_progress_ticker">Hochladen</string>
   <string name="uploader_upload_in_progress_content">%1$d%% Hochladen %2$s</string>
   <string name="uploader_upload_succeeded_ticker">Hochladen erfolgreich</string>
   <string name="uploader_upload_succeeded_content_single">%1$s wurde(n) erfolgreich hochgeladen</string>
   <string name="uploader_upload_failed_ticker">Hochladen fehlgeschlagen</string>
   <string name="uploader_upload_failed_content_single">Hochladen von  %1$s konnte nicht abgeschlossen werden</string>
   <string name="uploader_upload_failed_credentials_error">Hochladen fehlgeschlagen, Du musst dich nochmals anmelden</string>
-  <string name="downloader_download_in_progress_ticker">Herunterladen...</string>
+  <string name="downloader_download_in_progress_ticker">Herunterladen</string>
   <string name="downloader_download_in_progress_content">%1$d%% Herunterladen %2$s</string>
   <string name="downloader_download_succeeded_ticker">Herunterladen erfolgreich</string>
   <string name="downloader_download_succeeded_content">%1$s wurde erfolgreich heruntergeladen</string>
   <string name="media_rewind_description">Zurückspielen Knopf</string>
   <string name="media_play_pause_description">Play-/Pause Knopf</string>
   <string name="media_forward_description">Vorspulen Knopf</string>
-  <string name="auth_getting_authorization">Autorisierung empfangen...</string>
-  <string name="auth_trying_to_login">Anmeldungsversuch...</string>
+  <string name="auth_getting_authorization">Autorisierung empfangen</string>
+  <string name="auth_trying_to_login">Anmeldeversuch…</string>
   <string name="auth_no_net_conn_title">Keine Netzwerkverbindung</string>
   <string name="auth_nossl_plain_ok_title">Sichere Verbindung nicht verfügbar.</string>
   <string name="auth_connection_established">Verbindung hergestellt</string>
-  <string name="auth_testing_connection">Verbindung testen...</string>
+  <string name="auth_testing_connection">Verbindung testen</string>
   <string name="auth_not_configured_title">Fehlerhafte Server Konfiguration</string>
   <string name="auth_account_not_new">Ein Benutzerkonto für den gleichen Benutzer und Server existiert auf diesem Gerät bereits</string>
   <string name="auth_account_not_the_same">Der eingegebene Benutzer passt nicht zu dem Benutzer dieses Benutzerkontos</string>
   <string name="auth_fail_get_user_name">Dein Server gibt keine korrekte Benutzer-ID zurück, bitte kontaktiere einen Administrator
 </string>
   <string name="auth_can_not_auth_against_server">Die Authentifizierung gegenüber dem Server konnte nicht durchgeführt werden</string>
+  <string name="auth_account_does_not_exist">Das Benutzerkonto ist bis jetzt noch nicht auf dem Gerät vorhanden</string>
   <string name="fd_keep_in_sync">Datei aktuell halten</string>
   <string name="common_rename">Umbenennen</string>
   <string name="common_remove">Löschen</string>
   <string name="wait_a_moment">Bitte warte einen Moment.</string>
   <string name="filedisplay_unexpected_bad_get_content">Ein unerwartetes Problem ist aufgetreten. Bitte versuche, die Datei in einer anderen App zu öffnen</string>
   <string name="filedisplay_no_file_selected">Es wurde keine Datei ausgewählt.</string>
-  <string name="activity_chooser_title">Link senden an ...</string>
+  <string name="activity_chooser_title">Link senden an</string>
   <string name="oauth_check_onoff">Anmelden mit oAuth2</string>
   <string name="oauth_login_connection">Verbinde mit dem oAuth2-Server.</string>
   <string name="ssl_validator_header">Die Identität der Website konnte nicht überprüft werden</string>
   <string name="share_link_file_error">Es ist ein Fehler beim Freigeben der Datei oder des Ordners aufgetreten.</string>
   <string name="unshare_link_file_no_exist">Entfernen der Freigabe nicht möglich. Prüfe, dass die Datei existiert</string>
   <string name="unshare_link_file_error">Es ist ein Fehler beim Entfernen der Freigabe für diese Datei oder den Ordner aufgetreten.</string>
+  <string name="share_link_password_title">Passwort eingeben</string>
+  <string name="share_link_empty_password">Du musst ein Passwort eingeben</string>
   <string name="activity_chooser_send_file_title">Senden</string>
   <string name="copy_link">Link kopieren</string>
   <string name="clipboard_text_copied">In die Zwischenablage kopiert</string>
   <string name="prefs_category_security">Sicherheit</string>
   <string name="prefs_instant_video_upload_path_title">Verzeichnis zum Hochladen der Videos</string>
   <string name="download_folder_failed_content">Herunterladen des %1$s - Ordners konnte nicht abgeschlossen werden</string>
+  <string name="subject_token">%1$s hat „%2$s“ mit Dir geteilt</string>
+  <string name="auth_refresh_button">Verbindung aktualisieren</string>
+  <string name="auth_host_address">Serveradresse</string>
 </resources>
index 8fbc0e0..35bb58f 100644 (file)
   <string name="auth_no_net_conn_title">Δεν υπάρχει σύνδεση στο δίκτυο</string>
   <string name="auth_nossl_plain_ok_title">Μη διαθέσιμη ασφαλής σύνδεση.</string>
   <string name="auth_connection_established">Επετεύχθη σύνδεση</string>
-  <string name="auth_testing_connection">Έλεγχος σύνδεσης...</string>
+  <string name="auth_testing_connection">Έλεγχος σύνδεσης</string>
   <string name="auth_not_configured_title">Λανθασμένες ρυθμίσεις διακομιστή</string>
   <string name="auth_account_not_new">Ένας λογαριασμός για τον ίδιο χρήστη και διακομιστή υπάρχει ήδη στη συσκευή</string>
   <string name="auth_account_not_the_same">Ο χρήστης που εισάγατε δεν ταιριάζει με το χρήστη αυτού του λογαριασμού</string>
   <string name="auth_fail_get_user_name">Ο διακομιστής σας δεν επιστρέφει το σωστό αναγνωριστικό χρήστη, παρακαλώ επικοινωνήστε με ένα διαχειριστή
 ⇥</string>
   <string name="auth_can_not_auth_against_server">Δεν είναι δυνατή η πιστοποίηση με αυτόν το διακομιστή</string>
+  <string name="auth_account_does_not_exist">Ο λογαριασμός δεν υπάρχει στη συσκευή ακόμα.</string>
   <string name="fd_keep_in_sync">Διατήρηση αρχείου σε ενημέρωση</string>
   <string name="common_rename">Μετονομασία</string>
   <string name="common_remove">Αφαίρεση</string>
   <string name="share_link_file_error">Ένα σφάλμα προέκυψε κατά την προσπάθεια διαμοιρασμού αυτού του αρχείου ή φακέλου</string>
   <string name="unshare_link_file_no_exist">Αδύνατη η διακοπή κοινής χρήσης.  Παρακαλώ ελέγξτε αν το αρχείο υπάρχει</string>
   <string name="unshare_link_file_error">Ένα σφάλμα προέκυψε κατά τη διάρκεια ακύρωσης διαμοιρασμού αυτού του αρχείου ή φακέλου</string>
+  <string name="share_link_password_title">Εισάγετε ένα κωδικό πρόσβασης.</string>
+  <string name="share_link_empty_password">Πρέπει να εισάγετε ένα κωδικό πρόσβασης.</string>
   <string name="activity_chooser_send_file_title">Αποστολή</string>
   <string name="copy_link">Αντιγραφή συνδέσμου</string>
   <string name="clipboard_text_copied">Αντιγραφθηκε στο πρόχειρο</string>
   <string name="prefs_category_security">Ασφάλεια</string>
   <string name="prefs_instant_video_upload_path_title">Διαδρομή Μεταφόρτωσης Βίντεο</string>
   <string name="download_folder_failed_content">Η λήψη του φακέλου %1$s δεν ολοκληρώθηκε με επιτυχία.</string>
+  <string name="subject_token">%1$s μοιράστηκε \"%2$s\" μαζί σας</string>
+  <string name="auth_refresh_button">Ανανέωση σύνδεσης</string>
+  <string name="auth_host_address">Διεύθυνση διακομιστή</string>
 </resources>
index 9b30321..c28b665 100644 (file)
   <string name="auth_no_net_conn_title">No network connection</string>
   <string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
   <string name="auth_connection_established">Connection established</string>
-  <string name="auth_testing_connection">Testing connection</string>
+  <string name="auth_testing_connection">Testing connection</string>
   <string name="auth_not_configured_title">Malformed server configuration</string>
   <string name="auth_account_not_new">An account for the same user and server already exists on the device</string>
   <string name="auth_account_not_the_same">The entered user does not match the user of this account</string>
   <string name="auth_fail_get_user_name">Your server is not returning a correct user id, please contact an administrator
        </string>
   <string name="auth_can_not_auth_against_server">Cannot authenticate against this server</string>
+  <string name="auth_account_does_not_exist">Account does not exist on the device yet</string>
   <string name="fd_keep_in_sync">Keep file up to date</string>
   <string name="common_rename">Rename</string>
   <string name="common_remove">Remove</string>
   <string name="share_link_file_error">An error occurred while trying to share this file or folder</string>
   <string name="unshare_link_file_no_exist">Unable to unshare. Please check whether the file exists</string>
   <string name="unshare_link_file_error">An error occurred while trying to unshare this file or folder</string>
+  <string name="share_link_password_title">Enter a password</string>
+  <string name="share_link_empty_password">You must enter a password</string>
   <string name="activity_chooser_send_file_title">Send</string>
   <string name="copy_link">Copy link</string>
   <string name="clipboard_text_copied">Copied to clipboard</string>
   <string name="prefs_category_security">Security</string>
   <string name="prefs_instant_video_upload_path_title">Upload Video Path</string>
   <string name="download_folder_failed_content">Download of %1$s folder could not be completed</string>
+  <string name="subject_token">%1$s shared \"%2$s\" with you</string>
+  <string name="auth_refresh_button">Refresh connection</string>
+  <string name="auth_host_address">Server address</string>
 </resources>
index faf4525..26b3dc6 100644 (file)
   <string name="auth_no_net_conn_title">Neniu reta konekto</string>
   <string name="auth_nossl_plain_ok_title">Sekura konekto ne haveblas.</string>
   <string name="auth_connection_established">Konekto stariĝis</string>
-  <string name="auth_testing_connection">Testante konekton...</string>
   <string name="auth_not_configured_title">Malĝuste formita servilo-agordo</string>
   <string name="auth_unknown_error_title">Nekonata eraro okazis</string>
   <string name="auth_unknown_host_title">Ne eblis trovi gastigon</string>
   <string name="saml_authentication_wrong_pass">Malĝusta pasvorto</string>
   <string name="folder_picker_choose_button_text">Elekti</string>
   <string name="prefs_category_security">Sekuro</string>
+  <string name="auth_host_address">Servila adreso</string>
 </resources>
index 3baeea2..5ce747b 100644 (file)
   <string name="actionbar_settings">Configuración</string>
   <string name="actionbar_see_details">Detalles</string>
   <string name="actionbar_send_file">Mandar</string>
+  <string name="actionbar_sort">Orden</string>
+  <string name="actionbar_sort_title">Ordenar por</string>
+  <string-array name="actionbar_sortby">
+    <item>A-Z</item>
+    <item>Nuevos - Viejos</item>
+  </string-array>
   <!--TODO re-enable when server-side folder size calculation is available   
        <item>Biggest - Smallest</item>-->
   <string name="prefs_category_general">General</string>
   <string name="prefs_recommend">Recomendar a un amigo</string>
   <string name="prefs_feedback">Sugerencias</string>
   <string name="prefs_imprint">Imprint</string>
+  <string name="prefs_remember_last_share_location">Recordar compartir ubicación </string>
+  <string name="prefs_remember_last_upload_location_summary">Recordar la ultima ubicación compartida de subida</string>
   <string name="recommend_subject">¡Intento %1$s en tu teléfono inteligente!</string>
+  <string name="recommend_text">Quiero invitarte a usar %1$s en tu teléfono inteligente!\nDescárgalo aquí: %2$s</string>
   <string name="auth_check_server">Verificar Servidor</string>
   <string name="auth_host_url">Dirección del servidor https://...</string>
   <string name="auth_username">Nombre de usuario</string>
   <string name="auth_no_net_conn_title">Sin conexión de red</string>
   <string name="auth_nossl_plain_ok_title">Conexión segura no disponible.</string>
   <string name="auth_connection_established">Conexión establecida</string>
-  <string name="auth_testing_connection">Probando conexión...</string>
   <string name="auth_not_configured_title">Configuración de servidor en formato incorrecto</string>
   <string name="auth_account_not_new">Una cuenta para el mismo usuario y servidor ya existe en el dispositivo</string>
   <string name="auth_account_not_the_same">El usuario ingresado no concuerda con el usuario de esta cuenta</string>
   <string name="conflict_dont_upload">No subir</string>
   <string name="preview_image_description">Previsualización de imagen</string>
   <string name="preview_image_error_unknown_format">Esta imagen no puede ser mostrada</string>
+  <string name="error__upload__local_file_not_copied">%1$s no pudo ser copiado a la carpeta local %2$s </string>
+  <string name="prefs_instant_upload_path_title">Dirección de subida</string>
+  <string name="share_link_no_support_share_api">Lo sentimos, compartir no esta activado en su servidor. Por favor contacte a su
+⇥⇥administrator.</string>
+  <string name="share_link_file_no_exist">Imposible compartir. Por favor revise si el archivo existe</string>
+  <string name="share_link_file_error">Un error ocurrió cuando se intentaba compartir el archivo o carpeta</string>
+  <string name="unshare_link_file_no_exist">Imposible dejar de compartir. Por favor revise si los archivos existen</string>
+  <string name="unshare_link_file_error">Un error ocurrió cuando se intentaba dejar de compartir el archivo o carpeta</string>
   <string name="activity_chooser_send_file_title">Mandar</string>
+  <string name="copy_link">Copiar dirección url</string>
   <string name="clipboard_text_copied">Copiado al portapapeles</string>
+  <string name="error_cant_bind_to_operations_service">Error critico: no se puede realizar operaciones</string>
+  <string name="network_error_socket_exception">Un error ocurrió mientras se conectaba con el Servidor.</string>
+  <string name="network_error_socket_timeout_exception">Un error ocurrió mientras se conectaba con el Servidor. La operación no se realizó </string>
+  <string name="network_error_connect_timeout_exception">Un error ocurrió esperando al Servidor, la operación no se realizó</string>
+  <string name="network_host_not_available">Operación no completada, Servidor no disponible.</string>
   <string name="empty"></string>
+  <string name="forbidden_permissions">Tu no tienes permiso %s</string>
+  <string name="forbidden_permissions_rename">para renombrar este archivo</string>
+  <string name="forbidden_permissions_delete">para borrar este archivo</string>
+  <string name="share_link_forbidden_permissions">para compartir este archivo</string>
+  <string name="unshare_link_forbidden_permissions">para dejar de compartir este archivo</string>
+  <string name="forbidden_permissions_create">para crear el archivo</string>
+  <string name="uploader_upload_forbidden_permissions">para subir en esta carpeta</string>
+  <string name="downloader_download_file_not_found">El archivo no esta mas disponible en este Servidor</string>
   <string name="prefs_category_accounts">Cuentas</string>
+  <string name="prefs_add_account">Añadir cuenta</string>
+  <string name="auth_redirect_non_secure_connection_title">Conexión segura redireccionada a una ruta insegura.</string>
+  <string name="actionbar_logger">Registro</string>
+  <string name="log_send_history_button">Enviar Historial</string>
+  <string name="log_send_no_mail_app">Aplicación para enviar registros no encontrada. Instale una aplicación de correo!</string>
+  <string name="log_send_mail_subject">%1$s Registros de la aplicación Android</string>
+  <string name="log_progress_dialog_text">Cargando datos...</string>
   <string name="saml_authentication_required_text">Autentificación requerida</string>
   <string name="saml_authentication_wrong_pass">Clave incorrecta</string>
+  <string name="actionbar_move">Mover</string>
+  <string name="file_list_empty_moving">Nada aquí. Puedes agregar una carpeta!</string>
   <string name="folder_picker_choose_button_text">Elegir</string>
+  <string name="move_file_not_found">Imposible mover. Por favor revisa si el archivo existe</string>
+  <string name="move_file_invalid_overwrite">El archivo ya existe en la carpeta destino</string>
+  <string name="move_file_error">Un error ocurrió intentando mover el archivo o carpeta</string>
+  <string name="forbidden_permissions_move">para mover este archivo</string>
+  <string name="prefs_category_instant_uploading">Subida Instantánea </string>
   <string name="prefs_category_security">Seguridad</string>
+  <string name="prefs_instant_video_upload_path_title">Dirección de subida del video</string>
+  <string name="download_folder_failed_content">La descarga de la carpeta %1$s no pudo ser completada</string>
+  <string name="auth_host_address">Dirección del servidor</string>
 </resources>
index 16485ea..6a460c9 100644 (file)
   <string name="auth_no_net_conn_title">Sin conexión de red</string>
   <string name="auth_nossl_plain_ok_title">Conexión segura no disponible.</string>
   <string name="auth_connection_established">Conexión establecida</string>
-  <string name="auth_testing_connection">Probando conexión...</string>
   <string name="auth_not_configured_title">La configuración del servidor está mal formada</string>
   <string name="auth_unknown_error_title">Ocurrió un error desconocido</string>
   <string name="auth_unknown_host_title">No se puede encontrar el host</string>
index 69623e1..26dde5f 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <resources>
+  <string name="actionbar_upload_files">Archivos</string>
   <!--TODO re-enable when server-side folder size calculation is available   
        <item>Biggest - Smallest</item>-->
+  <string name="sync_string_files">Archivos</string>
   <string name="empty"></string>
 </resources>
index a760bfe..d9faa7b 100644 (file)
   <string name="auth_no_net_conn_title">Sin conexión de red</string>
   <string name="auth_nossl_plain_ok_title">Conexión segura no disponible.</string>
   <string name="auth_connection_established">Conexión establecida</string>
-  <string name="auth_testing_connection">Probando conexión...</string>
   <string name="auth_not_configured_title">Configuración de servidor en formato incorrecto</string>
   <string name="auth_account_not_new">Una cuenta para el mismo usuario y servidor ya existen en el dispositivo</string>
   <string name="auth_account_not_the_same">El usuario introducido no concuerda con el usuario de esta cuenta</string>
   <string name="saml_authentication_wrong_pass">Contraseña incorrecta</string>
   <string name="folder_picker_choose_button_text">Seleccionar</string>
   <string name="prefs_category_security">Seguridad</string>
+  <string name="auth_host_address">Dirección del servidor</string>
 </resources>
index fd73bb9..8fc55c3 100644 (file)
@@ -7,7 +7,7 @@
   <string name="actionbar_upload_from_apps">Contenido de otras aplicaciones</string>
   <string name="actionbar_upload_files">Archivos</string>
   <string name="actionbar_open_with">Abrir con</string>
-  <string name="actionbar_mkdir">Nueva Carpeta</string>
+  <string name="actionbar_mkdir">Nueva carpeta</string>
   <string name="actionbar_settings">Configuración</string>
   <string name="actionbar_see_details">Detalles</string>
   <string name="actionbar_send_file">Enviar</string>
@@ -40,7 +40,7 @@
   <string name="prefs_imprint">pie de imprenta</string>
   <string name="prefs_remember_last_share_location">Recordar la ubicación de los archivos compartidos</string>
   <string name="prefs_remember_last_upload_location_summary">Recordar la ubicación de los últimos archivos compartidos subidos</string>
-  <string name="recommend_subject">Prueba  %1$s en tu smarthphone!</string>
+  <string name="recommend_subject">¡Prueba  %1$s en su smarthphone!</string>
   <string name="recommend_text">¡Quiero invitarle a usar %1$s en su smartphone!\nDescárguelo aquí: %2$s</string>
   <string name="auth_check_server">Compruebe el servidor.</string>
   <string name="auth_host_url">Dirección del servidor https://…</string>
@@ -52,7 +52,7 @@
   <string name="uploader_btn_upload_text">Subir</string>
   <string name="uploader_top_message">Escoger carpeta de carga:</string>
   <string name="uploader_wrn_no_account_title">No se encontró la cuenta</string>
-  <string name="uploader_wrn_no_account_text">No hay cuentas de %1$s en tu dispositivo. Por favor configura una cuenta primero.</string>
+  <string name="uploader_wrn_no_account_text">No hay cuentas de %1$s en su dispositivo. Por favor, configure una cuenta primero.</string>
   <string name="uploader_wrn_no_account_setup_btn_text">Configuración</string>
   <string name="uploader_wrn_no_account_quit_btn_text">Salir</string>
   <string name="uploader_wrn_no_content_title">No hay contenido para subir</string>
@@ -85,7 +85,7 @@
   <string name="common_cancel">Cancelar</string>
   <string name="common_save_exit">Guardar &amp; Salir</string>
   <string name="common_error">Error</string>
-  <string name="common_loading">Cargando ...</string>
+  <string name="common_loading">Cargando...</string>
   <string name="common_error_unknown">Error desconocido</string>
   <string name="about_title">Acerca de</string>
   <string name="change_password">Cambiar contraseña</string>
   <string name="uploader_upload_failed_ticker">Error en la subida</string>
   <string name="uploader_upload_failed_content_single">La subida de %1$s no se pudo completar</string>
   <string name="uploader_upload_failed_credentials_error">La carga falló, necesita volver a iniciar sesión</string>
-  <string name="downloader_download_in_progress_ticker">Descargando ...</string>
+  <string name="downloader_download_in_progress_ticker">Descargando...</string>
   <string name="downloader_download_in_progress_content">%1$d%% Descargado de %2$s</string>
   <string name="downloader_download_succeeded_ticker">Descarga completa</string>
   <string name="downloader_download_succeeded_content">%1$s se ha descargado con éxito</string>
   <string name="downloader_download_failed_content">La descarga de %1$s no se pudo completar</string>
   <string name="downloader_not_downloaded_yet">No descargado</string>
   <string name="downloader_download_failed_credentials_error">Descarga fallida, necesita reinicar la sesión</string>
-  <string name="common_choose_account">Elige una cuenta</string>
+  <string name="common_choose_account">Elija una cuenta</string>
   <string name="sync_fail_ticker">Falló la sincronización</string>
   <string name="sync_fail_ticker_unauthorized">La sincronización falló, debe reiniciar la sesión</string>
   <string name="sync_fail_content">La sincronización de %1$s s no se pudo completar</string>
   <string name="foreign_files_local_text">Local: %1$s</string>
   <string name="foreign_files_remote_text">Remoto: %1$s</string>
   <string name="upload_query_move_foreign_files">No hay suficiente espacio para copiar los archivos seleccionados a la carpeta %1$s. ¿Desea moverlos en vez de copiarlos?</string>
-  <string name="pincode_enter_pin_code">Por favor, inserta tu PIN de aplicación</string>
+  <string name="pincode_enter_pin_code">Por favor, inserte su PIN de aplicación</string>
   <string name="pincode_configure_your_pin">Introduzca un PIN para la aplicación</string>
   <string name="pincode_configure_your_pin_explanation">Se solicitará el PIN cada vez que se inicie la aplicación</string>
   <string name="pincode_reenter_your_pincode">Repita el PIN para la aplicación, por favor</string>
   <string name="media_err_unknown">El archivo de medios no se puede reproducir con el reproductor de medios por defecto </string>
   <string name="media_err_security_ex">Error de seguridad al intentar reproducir %1$s</string>
   <string name="media_err_io_ex">Error de entrada al intentar reproducir %1$s</string>
-  <string name="media_err_unexpected">Error inesperado intentando reproducir %1$s</string>
-  <string name="media_rewind_description">Botón Rebobinado</string>
+  <string name="media_err_unexpected">Error inesperado al intentar reproducir %1$s</string>
+  <string name="media_rewind_description">Botón de rebobinado</string>
   <string name="media_play_pause_description">Botón de reproducción o pausa </string>
   <string name="media_forward_description">Botón avance rápido</string>
   <string name="auth_getting_authorization">Consiguiendo autorización...</string>
   <string name="auth_no_net_conn_title">Sin conexión de red</string>
   <string name="auth_nossl_plain_ok_title">Conexión segura no disponible.</string>
   <string name="auth_connection_established">Conexión establecida</string>
-  <string name="auth_testing_connection">Probando conexión...</string>
+  <string name="auth_testing_connection">Comprobando la conexión</string>
   <string name="auth_not_configured_title">Configuración de servidor en formato incorrecto</string>
   <string name="auth_account_not_new">Ya existe una cuenta en este dispositivo con los mismos datos de Usuario y Servidor</string>
   <string name="auth_account_not_the_same">El usuario introducido no concuerda con el usuario de esta cuenta</string>
   <string name="auth_fail_get_user_name">Su servidor no está retornando una identificación de usuario correcta; contacte a un administrador
        </string>
   <string name="auth_can_not_auth_against_server">No puede autenticarse en este servidor.</string>
+  <string name="auth_account_does_not_exist">Aún no existe la cuenta en el dispositivo</string>
   <string name="fd_keep_in_sync">Mantener el archivo actualizado</string>
   <string name="common_rename">Renombrar</string>
   <string name="common_remove">Borrar</string>
   <string name="filename_forbidden_characters">Carácteres ilegales: / \\ &lt; &gt; : \" | ? *</string>
   <string name="filename_empty">El nombre de archivo no puede estar vacío</string>
   <string name="wait_a_moment">Espere un momento</string>
-  <string name="filedisplay_unexpected_bad_get_content">Problema inesperado; por favor, prueba otra app para seleccionar el archivo</string>
+  <string name="filedisplay_unexpected_bad_get_content">Problema inesperado; por favor, pruebe otra app para seleccionar el archivo</string>
   <string name="filedisplay_no_file_selected">No hay ficheros seleccionados.</string>
   <string name="activity_chooser_title">Enviar enlace a...</string>
   <string name="oauth_check_onoff">Ingresar con oAuth2</string>
   <string name="ssl_validator_reason_cert_expired">- El certificado del servidor expiró</string>
   <string name="ssl_validator_reason_cert_not_yet_valid">- El certificado del servidor es de una fecha que aún no ha llegado</string>
   <string name="ssl_validator_reason_hostname_not_verified">- La URL no coincide con el nombre de dominio del certificado</string>
-  <string name="ssl_validator_question">¿Confías de todas formas en este certificado?</string>
+  <string name="ssl_validator_question">¿Confía de todas formas en este certificado?</string>
   <string name="ssl_validator_not_saved">El certificado no pudo ser guardado</string>
   <string name="ssl_validator_btn_details_see">Detalles</string>
   <string name="ssl_validator_btn_details_hide">Ocultar</string>
   <string name="share_link_file_error">Ocurrió un error al tratar de compartir este archivo o carpeta</string>
   <string name="unshare_link_file_no_exist">No se puede dejar de compartir. Revise si el archivo existe</string>
   <string name="unshare_link_file_error">Ocurrió un error al tratar de ya no compartir este archivo o carpeta</string>
+  <string name="share_link_password_title">Introduzca una contraseña</string>
+  <string name="share_link_empty_password">Debe introducir una contraseña</string>
   <string name="activity_chooser_send_file_title">Enviar</string>
   <string name="copy_link">Copiar enlace</string>
   <string name="clipboard_text_copied">Copiado al portapapeles</string>
   <string name="saml_authentication_wrong_pass">Contraseña incorrecta</string>
   <string name="actionbar_move">Mover</string>
   <string name="file_list_empty_moving">Aquí no hay nada. ¡Puede agregar una carpeta!</string>
-  <string name="folder_picker_choose_button_text">Seleccionar</string>
+  <string name="folder_picker_choose_button_text">Elegir</string>
   <string name="move_file_not_found">No se puede mover. Revise si el archivo existe</string>
   <string name="move_file_invalid_into_descendent">No se puede mover una carpeta dentro de una de SUS subcarpetas.</string>
   <string name="move_file_invalid_overwrite">El archivo ya existe en la carpeta de destino</string>
   <string name="prefs_category_instant_uploading">Subidas instantáneas</string>
   <string name="prefs_category_security">Seguridad</string>
   <string name="prefs_instant_video_upload_path_title">Guardar videos subidos en la carpeta:</string>
-  <string name="download_folder_failed_content">Descarga de la carpeta %1$s no ha podido ser completada</string>
+  <string name="download_folder_failed_content">La descarga de la carpeta %1$s no ha podido ser completada</string>
+  <string name="subject_token">%1$s compartió \"%2$s\" contigo</string>
+  <string name="auth_refresh_button">Refrescar la conexión</string>
+  <string name="auth_host_address">Dirección del servidor</string>
 </resources>
index e7ac96b..d724107 100644 (file)
@@ -164,7 +164,6 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
   <string name="auth_no_net_conn_title">Võrguühendust pole</string>
   <string name="auth_nossl_plain_ok_title">Turvaline ühendus pole saadaval</string>
   <string name="auth_connection_established">Saadi ühendus</string>
-  <string name="auth_testing_connection">Ühenduse testimine...</string>
   <string name="auth_not_configured_title">Vigases vormingus server seadistus</string>
   <string name="auth_account_not_new">Sama konto  kasutaja ja server on juba selles seadmes olemas</string>
   <string name="auth_account_not_the_same">Sisestatud kasutaja ei kattu selle konto kasutajaga</string>
@@ -298,4 +297,5 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
   <string name="forbidden_permissions_move">selle faili liigutamiseks</string>
   <string name="prefs_category_instant_uploading">Kohesed üleslaadimised</string>
   <string name="prefs_category_security">Turvalisus</string>
+  <string name="auth_host_address">Serveri aadress</string>
 </resources>
index 277682a..31b3c51 100644 (file)
@@ -12,6 +12,7 @@
   <string name="actionbar_see_details">Xehetasunak</string>
   <string name="actionbar_send_file">Bidali</string>
   <string name="actionbar_sort">Ordenatu</string>
+  <string name="actionbar_sort_title">Ordenatu honen arabera</string>
   <string-array name="actionbar_sortby">
     <item>A-Z</item>
     <item>Berrienak - Zaharrenak</item>
@@ -38,6 +39,7 @@
   <string name="prefs_feedback">Oharrak</string>
   <string name="prefs_imprint">Imprint</string>
   <string name="recommend_subject">Probatu %1$s zure telefono adimentsuan!</string>
+  <string name="recommend_text">Nik %1$s zure telefono adimentsuan erabitzera gonbidatu nahi zaitut!\nDeskargatu hemen: %2$s</string>
   <string name="auth_check_server">Egiaztatu zerbitzaria</string>
   <string name="auth_host_url">Zerbitzariaren helbidea https://</string>
   <string name="auth_username">Erabiltzaile izena</string>
   <string name="sync_fail_in_favourites_content">%1$d fitxategien edukiak ezin dira sinkronizatu (%2$d gatazka)</string>
   <string name="sync_foreign_files_forgotten_ticker">Bertako fitxategi batzuk ahaztu dira</string>
   <string name="sync_foreign_files_forgotten_content">%2$s karpetako %1$d fitxategi ezin dira dira kopiatu</string>
+  <string name="sync_foreign_files_forgotten_explanation">1.3.16 bertsioan, gailu honetatik igotzen diren fitxategiak bertako %1$s karpetara mugitzen dira datu galera ekiditeko fitxategi bat kontu ezberdinekin sinkronizatzen denean.\n\n Aldaketa hau dela eta, programa honen aurreko bertsioetan igotako fitxategi guztiak %2$s karpetara kopiatu dira. Hala ere, errore batek hau burutzea ekidin du kontuaren sinkronizazioa egiten ari zen bitartean. Orain fitxategiak dauden bezala utz ditzakezu eta %3$s rako lotura ezabatu, edo fitxategiak %1$s karpetara mugi ditzakezu eta %4$srako lotura mantendu.\n\nBehean bertako fitxategien zerrenda eta %5$s era lotuta zeuden urruneko fitxategiena.</string>
   <string name="sync_current_folder_was_removed">%1$s karpeta dagoeneko ez da existitzen</string>
   <string name="foreign_files_move">Mugitu denak</string>
   <string name="foreign_files_success">Fitxategi guztiak mugitu dira</string>
   <string name="auth_no_net_conn_title">Ez dago sare konexiorik</string>
   <string name="auth_nossl_plain_ok_title">Konexio segurua ez dago eskuragarri</string>
   <string name="auth_connection_established">Konexioa ezarri da</string>
-  <string name="auth_testing_connection">Konexioa probatzen...</string>
   <string name="auth_not_configured_title">gaizki egindako server konfigurazioa</string>
   <string name="auth_account_not_new">Erabiltzaile eta zerbitzari hauendako dagoeneko kontu bat  existitzen da gailu honetan</string>
   <string name="auth_account_not_the_same">Sartutako erabiltzaileak ez du bat egiten kontu honetako erabiltzailearekin</string>
@@ -250,7 +252,9 @@ Mesedez, baimendu berriz</string>
   <string name="error__upload__local_file_not_copied">%1$s ezin da %2$s karpeta lokalera kopiatu</string>
   <string name="prefs_instant_upload_path_title">Igotzetarako Bidea</string>
   <string name="share_link_no_support_share_api">Sentitzen dut, partekatzea ez dago zure zerbitzarian gaituta. Mesedez jarri harremanetan zure administratzailearekin.</string>
+  <string name="share_link_file_no_exist">Ezin izan da partekatu. Mesedez egiaztatu fitxategia existitzen dela</string>
   <string name="share_link_file_error">Errore bat egon da fitxategaia edo karpeta partekatzerakoan</string>
+  <string name="unshare_link_file_no_exist">Ezin izan da partekatzea desegin. Mesedez egiaztatu fitxategia existitzen dela</string>
   <string name="unshare_link_file_error">Errore bat egon da fitxategaia edo karpeta partekatzeari uzterakoan</string>
   <string name="activity_chooser_send_file_title">Bidali</string>
   <string name="copy_link">Lotura kopiatu</string>
@@ -271,12 +275,24 @@ Mesedez, baimendu berriz</string>
   <string name="downloader_download_file_not_found">Fitxategia jadanik ez dago eskuragarri zerbitzarian</string>
   <string name="prefs_category_accounts">Kontuak</string>
   <string name="prefs_add_account">Gehitu kontua</string>
+  <string name="auth_redirect_non_secure_connection_title">Konexio segurua birbideratu da segurua ez den bide batera.</string>
+  <string name="actionbar_logger">Egunkariak</string>
+  <string name="log_send_history_button">Bidali Historia</string>
+  <string name="log_send_no_mail_app">Egunkariak bidaltzeko aplikaziorik ez da aurkitu. Instalatu posta aplikazioa!</string>
   <string name="log_send_mail_subject">%1$s Android aplikazioaren egunerokoak</string>
   <string name="log_progress_dialog_text">Datuak kargatzen...</string>
   <string name="saml_authentication_required_text">Autentikazioa beharrezkoa</string>
   <string name="saml_authentication_wrong_pass">Pasahitz okerra</string>
   <string name="actionbar_move">Mugitu</string>
+  <string name="file_list_empty_moving">Hemen ez dago ezer. Karpeta bat gehi dezakezu!</string>
   <string name="folder_picker_choose_button_text">Aukeratu</string>
+  <string name="move_file_not_found">Ezin izan da mugitu. Mesedez egiaztatu fitxategia existitzen dela</string>
+  <string name="move_file_invalid_overwrite">Fitxategia dagoeneko existitzen da helburuko karpetan</string>
+  <string name="move_file_error">Errore bat gertatu da fitxategi edo karpeta hau mugitzen saiatzerakoan</string>
+  <string name="forbidden_permissions_move">fitxategi hau mugitzeko</string>
   <string name="prefs_category_instant_uploading">Berehalako Igoerak</string>
   <string name="prefs_category_security">Segurtasuna</string>
+  <string name="prefs_instant_video_upload_path_title">Bideo Igoera Bidea</string>
+  <string name="download_folder_failed_content">%1$s karpetaren deskarga ezin izan da burutu</string>
+  <string name="auth_host_address">Zerbitzariaren helbidea</string>
 </resources>
index 0140c07..942a4bf 100644 (file)
   <string name="auth_no_net_conn_title">هیچ ارتباطی به شبکه موجود نیست</string>
   <string name="auth_nossl_plain_ok_title">اتصال امن در دسترس نیست</string>
   <string name="auth_connection_established">اتصال برقرار شد</string>
-  <string name="auth_testing_connection">آزمایش اتصال...</string>
   <string name="auth_not_configured_title">پیکربندی سرور ناقص است</string>
   <string name="auth_account_not_new">یک اکانت با همین نام کاربری و سرور بر روی این دستگاه موجود می‌باشد.</string>
   <string name="auth_account_not_the_same">نام کاربری وارد شده با نام کاربری این اکانت مطابقت ندارد</string>
   <string name="saml_authentication_wrong_pass">رمز عبور اشتباه است</string>
   <string name="folder_picker_choose_button_text">انتخاب کردن</string>
   <string name="prefs_category_security">امنیت</string>
+  <string name="auth_host_address">آدرس سرور</string>
 </resources>
index ae5c485..116b077 100644 (file)
   <string name="auth_no_net_conn_title">Ei verkkoyhteyttä</string>
   <string name="auth_nossl_plain_ok_title">Salattu yhteys ei ole käytettävissä.</string>
   <string name="auth_connection_established">Yhteys muodostettu</string>
-  <string name="auth_testing_connection">Testataan yhteyttä...</string>
   <string name="auth_not_configured_title">Väärin tehdyt palvelin-asetukset</string>
   <string name="auth_account_not_new">Laitteella on jo tili samalle käyttäjälle ja palvelimelle</string>
   <string name="auth_account_not_the_same">Syötetty käyttäjä ei täsmää tämän tilin käyttäjän kanssa</string>
   <string name="auth_unsupported_auth_method">Palvelin ei tue tätä tunnistautumistapaa</string>
   <string name="auth_unsupported_multiaccount">%1$s ei tue useita tilejä</string>
   <string name="auth_can_not_auth_against_server">Tunnistautuminen palvelinta vastaan ei onnistu</string>
+  <string name="auth_account_does_not_exist">Tiliä ei ole olemassa vielä laitteella</string>
   <string name="fd_keep_in_sync">Pidä tiedosto ajan tasalla</string>
   <string name="common_rename">Nimeä uudelleen</string>
   <string name="common_remove">Poista</string>
   <string name="share_link_no_support_share_api">Jakaminen ei ole käytössä palvelimellasi. Ota yhteys
                ylläpitäjään.</string>
   <string name="share_link_file_error">Virhe tiedoston tai kansion jakamista yrittäessä</string>
+  <string name="share_link_password_title">Anna salasana</string>
+  <string name="share_link_empty_password">Salasana on pakko antaa</string>
   <string name="activity_chooser_send_file_title">Lähetä</string>
   <string name="copy_link">Kopioi linkki</string>
   <string name="clipboard_text_copied">Kopioitu leikepöydälle</string>
   <string name="move_file_error">Tämän tiedoston tai kansion siirtoa yrittäessä tapahtui virhe</string>
   <string name="prefs_category_instant_uploading">Välittömät lähetykset</string>
   <string name="prefs_category_security">Tietoturva</string>
+  <string name="subject_token">%1$s jakoi kohteen \"%2$s\" kanssasi</string>
+  <string name="auth_refresh_button">Päivitä yhteys</string>
+  <string name="auth_host_address">Palvelimen osoite</string>
 </resources>
index 6e87f78..4b4cded 100644 (file)
@@ -25,9 +25,9 @@
   <string name="prefs_manage_accounts">Gestion des comptes</string>
   <string name="prefs_pincode">Code de sécurité</string>
   <string name="prefs_pincode_summary">Protéger l\'accès à l\'application</string>
-  <string name="prefs_instant_upload">Envoi instantané des photos</string>
+  <string name="prefs_instant_upload">Téléversement immédiat des photos</string>
   <string name="prefs_instant_upload_summary">Téléverser immédiatement les photos prises par la caméra</string>
-  <string name="prefs_instant_video_upload">Envoi instantané des vidéos</string>
+  <string name="prefs_instant_video_upload">Téléversement immédiat des vidéos</string>
   <string name="prefs_instant_video_upload_summary">Téléverser immédiatement les vidéos prises par la caméra</string>
   <string name="prefs_log_title">Activer les logs</string>
   <string name="prefs_log_summary">Utilisé pour enregistrer les problèmes dans les logs</string>
@@ -39,7 +39,7 @@
   <string name="prefs_feedback">Commentaires</string>
   <string name="prefs_imprint">Empreinte</string>
   <string name="prefs_remember_last_share_location">Mémoriser l\'emplacement de partage</string>
-  <string name="prefs_remember_last_upload_location_summary">Mémoriser le dernier emplacement d\'upload</string>
+  <string name="prefs_remember_last_upload_location_summary">Mémoriser le dernier emplacement de téléversement</string>
   <string name="recommend_subject">Essayez %1$s sur votre smartphone !</string>
   <string name="recommend_text">J\'aimerais vous inviter à utiliser %1$s sur votre smartphone !
 Téléchargez-le ici : %2$s</string>
@@ -54,12 +54,12 @@ Téléchargez-le ici : %2$s</string>
   <string name="uploader_top_message">Sélectionner le dossier d\'envoi :</string>
   <string name="uploader_wrn_no_account_title">Aucun compte n\'a été trouvé</string>
   <string name="uploader_wrn_no_account_text">Aucun compte %1$s n\'a été trouvé. Veuillez commencer par en configurer un.</string>
-  <string name="uploader_wrn_no_account_setup_btn_text">Paramètres</string>
+  <string name="uploader_wrn_no_account_setup_btn_text">Configuration</string>
   <string name="uploader_wrn_no_account_quit_btn_text">Quitter</string>
   <string name="uploader_wrn_no_content_title">Rien à envoyer</string>
   <string name="uploader_wrn_no_content_text">Aucun contenu reçu. Rien à envoyer.</string>
   <string name="uploader_error_forbidden_content">%1$s n\'est pas autorisé à accéder au contenu partagé</string>
-  <string name="uploader_info_uploading">Téléversement</string>
+  <string name="uploader_info_uploading">Téléversement...</string>
   <string name="file_list_seconds_ago">il y a quelques secondes</string>
   <string name="file_list_empty">Il n\'y a rien ici ! Envoyez donc quelque chose :)</string>
   <string name="file_list_loading">Chargement…</string>
@@ -68,7 +68,7 @@ Téléchargez-le ici : %2$s</string>
   <string name="file_list_folders">dossiers</string>
   <string name="file_list_file">fichier</string>
   <string name="file_list_files">fichiers</string>
-  <string name="filedetails_select_file">Effleurez un fichier pour afficher les informations complémentaires</string>
+  <string name="filedetails_select_file">Effleurez un fichier pour afficher les informations complémentaires.</string>
   <string name="filedetails_size">Taille :</string>
   <string name="filedetails_type">Type :</string>
   <string name="filedetails_created">Créé le :</string>
@@ -82,7 +82,7 @@ Téléchargez-le ici : %2$s</string>
   <string name="common_no">Non</string>
   <string name="common_ok">OK</string>
   <string name="common_cancel_download">Annuler le téléchargement</string>
-  <string name="common_cancel_upload">Annuler l\'envoi</string>
+  <string name="common_cancel_upload">Annuler le téléversement</string>
   <string name="common_cancel">Annuler</string>
   <string name="common_save_exit">Sauvegarder &amp; Quitter</string>
   <string name="common_error">Erreur</string>
@@ -90,14 +90,14 @@ Téléchargez-le ici : %2$s</string>
   <string name="common_error_unknown">Erreur inconnue </string>
   <string name="about_title">À propos de</string>
   <string name="change_password">Changer de mot de passe</string>
-  <string name="delete_account">Effacer ce compte</string>
+  <string name="delete_account">Supprimer ce compte</string>
   <string name="create_account">Créer un compte</string>
   <string name="upload_chooser_title">Téléverser un fichier depuis…</string>
   <string name="uploader_info_dirname">Nom du dossier</string>
   <string name="uploader_upload_in_progress_ticker">Téléversement…</string>
   <string name="uploader_upload_in_progress_content">Envoi du fichier %2$s : %1$d%% effectués</string>
   <string name="uploader_upload_succeeded_ticker">Téléversement réussi</string>
-  <string name="uploader_upload_succeeded_content_single">Le fichier %1$s a été envoyé avec succès</string>
+  <string name="uploader_upload_succeeded_content_single">Le fichier %1$s a été téléversé avec succès</string>
   <string name="uploader_upload_failed_ticker">Échec de l\'envoi</string>
   <string name="uploader_upload_failed_content_single">L\'envoi de %1$s a échoué</string>
   <string name="uploader_upload_failed_credentials_error">Le téléversement a échoué, vous devez vous connecter à nouveau</string>
@@ -111,7 +111,7 @@ Téléchargez-le ici : %2$s</string>
   <string name="downloader_download_failed_credentials_error">Le téléchargement a échoué, vous devez vous connecter à nouveau</string>
   <string name="common_choose_account">Choisissez un compte</string>
   <string name="sync_fail_ticker">La synchronisation a échoué</string>
-  <string name="sync_fail_ticker_unauthorized">Échec de la synchronisation, vous devez vous reconnecter à nouveau</string>
+  <string name="sync_fail_ticker_unauthorized">Échec de la synchronisation, vous devez vous reconnecter</string>
   <string name="sync_fail_content">La synchronisation de %1$s n\'a pu être terminée</string>
   <string name="sync_fail_content_unauthorized">Mot de passe non valide pour %1$s</string>
   <string name="sync_conflicts_in_favourites_ticker">Des conflits ont été trouvés</string>
@@ -120,9 +120,9 @@ Téléchargez-le ici : %2$s</string>
   <string name="sync_fail_in_favourites_content">Le contenu de %1$d fichiers n\'a pu être synchronisé (%2$d conflits)</string>
   <string name="sync_foreign_files_forgotten_ticker">Certains fichiers locaux ont été oubliés</string>
   <string name="sync_foreign_files_forgotten_content">%1$d fichiers du dossier %2$s n\'ont pas pu être copiés dans</string>
-  <string name="sync_foreign_files_forgotten_explanation">Depuis la version 1.3.16, les fichiers envoyé depuis ce périphérique sont copiés dans le dossier local %1$s pour éviter une perte de données lorsqu\'un même fichier est synchronisé avec plusieurs comptes.
+  <string name="sync_foreign_files_forgotten_explanation">Depuis la version 1.3.16, les fichiers envoyés depuis ce périphérique sont copiés dans le dossier local %1$s pour éviter une perte de données lorsqu\'un même fichier est synchronisé avec plusieurs comptes.
 
-En raison de cette modification, tous les fichiers envoyés avec des versions antérieures de cette application ont été copiés dans le dossier %2$s. Cependant une erreur a empêché l\'achèvement de cette opération pendant la synchronisation du compte. Vous pouvez soit laisser les fichiers tels quels et supprimer le lien vers %3$s, soit déplacer les fichiers dans le dossier %1$s et garder le lien vers %4$s.
+En raison de cette modification, tous les fichiers envoyés avec des versions antérieures de cette application ont été copiés dans le dossier %2$s. Cependant, une erreur a empêché l\'achèvement de cette opération pendant la synchronisation du compte. Vous pouvez soit laisser les fichiers tels quels et supprimer le lien vers %3$s, soit déplacer les fichiers dans le dossier %1$s et garder le lien vers %4$s.
 
 Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxquels ils étaient liés.</string>
   <string name="sync_current_folder_was_removed">Le dossier %1$s n\'existe plus</string>
@@ -131,11 +131,11 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="foreign_files_fail">Certains fichiers n\'ont pu être déplacés</string>
   <string name="foreign_files_local_text">Local : %1$s</string>
   <string name="foreign_files_remote_text">Distant : %1$s</string>
-  <string name="upload_query_move_foreign_files">Il n\'y a pas assez de place disponible pour copier les fichiers sélectionnés dans le dossier %1$s. Voulez-vous quand même les déplacer ?</string>
+  <string name="upload_query_move_foreign_files">Il n\'y a pas assez de place disponible pour copier les fichiers sélectionnés dans le dossier %1$s. Voulez-vous les déplacer à la place ?</string>
   <string name="pincode_enter_pin_code">Veuillez saisir votre code de sécurité</string>
   <string name="pincode_configure_your_pin">Veuillez saisir votre code de sécurité </string>
-  <string name="pincode_configure_your_pin_explanation">Le code PIN vous sera demandé à chaque lancement de l\'application</string>
-  <string name="pincode_reenter_your_pincode">Veuillez saisir à nouveau votre code de sécurité</string>
+  <string name="pincode_configure_your_pin_explanation">Le code de sécurité vous sera demandé à chaque lancement de l\'application</string>
+  <string name="pincode_reenter_your_pincode">Veuillez saisir de nouveau votre code de sécurité</string>
   <string name="pincode_remove_your_pincode">Retirer le code de sécurité</string>
   <string name="pincode_mismatch">Les deux codes saisis ne concordent pas</string>
   <string name="pincode_wrong">Code de sécurité incorrect</string>
@@ -165,14 +165,14 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="auth_no_net_conn_title">Pas de connexion réseau</string>
   <string name="auth_nossl_plain_ok_title">Connexion sécurisée non disponible</string>
   <string name="auth_connection_established">Connexion établie</string>
-  <string name="auth_testing_connection">Test de la connexion…</string>
+  <string name="auth_testing_connection">Test de connexion</string>
   <string name="auth_not_configured_title">Configuration du serveur erronée</string>
-  <string name="auth_account_not_new">Un compte pour le même utilisateur et serveur existe déjà sur ce périphérique</string>
+  <string name="auth_account_not_new">Un compte pour le même utilisateur et serveur existe déjà sur cet appareil</string>
   <string name="auth_account_not_the_same">L\'utilisateur entré ne correspond pas à l\'utilisateur de ce compte</string>
-  <string name="auth_unknown_error_title">Une erreur inconnue s\'est produite</string>
+  <string name="auth_unknown_error_title">Une erreur inconnue s\'est produite.</string>
   <string name="auth_unknown_host_title">Impossible de trouver l\'hôte</string>
   <string name="auth_incorrect_path_title">Aucune instance du serveur n\'a été trouvée</string>
-  <string name="auth_timeout_title">Le serveur met trop longtemps à répondre</string>
+  <string name="auth_timeout_title">Le serveur a pris trop de temps à répondre</string>
   <string name="auth_incorrect_address_title">Adresse non valide</string>
   <string name="auth_ssl_general_error_title">Échec de l\'initialisation SSL</string>
   <string name="auth_ssl_unverified_server_title">Impossible de vérifier l\'identité du serveur SSL</string>
@@ -192,6 +192,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="auth_fail_get_user_name">Votre serveur a retourné un identifiant d\'utilisateur incorrect. Veuillez prendre contact avec votre administrateur
 </string>
   <string name="auth_can_not_auth_against_server">Impossible de s\'authentifier sur ce serveur</string>
+  <string name="auth_account_does_not_exist">Le compte n\'existe pas encore sur ce périphérique</string>
   <string name="fd_keep_in_sync">Maintenir le fichier à jour</string>
   <string name="common_rename">Renommer</string>
   <string name="common_remove">Supprimer</string>
@@ -249,29 +250,31 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="placeholder_media_time">12:23:45</string>
   <string name="instant_upload_on_wifi">Téléverser les images via une connexion WiFi uniquement</string>
   <string name="instant_video_upload_on_wifi">Téléverser les vidéos via une connexion WiFi uniquement</string>
-  <string name="instant_upload_path">/Instantané</string>
+  <string name="instant_upload_path">/InstantUpload</string>
   <string name="conflict_title">Conflit de mise à jour</string>
-  <string name="conflict_message">Le fichier distant %s n\'est pas synchronisé avec le fichier local. En choisissant de continuer, vous remplacerez le contenu de fichier sur le serveur.</string>
+  <string name="conflict_message">Le fichier distant %s n\'est pas synchronisé avec le fichier local. En choisissant de continuer, vous remplacerez le contenu du fichier sur le serveur.</string>
   <string name="conflict_keep_both">Garder les deux versions</string>
   <string name="conflict_overwrite">Écraser</string>
   <string name="conflict_dont_upload">Ne pas téléverser</string>
   <string name="preview_image_description">Prévisualisation de l\'image</string>
   <string name="preview_image_error_unknown_format">Cette image ne peut pas être affichée</string>
   <string name="error__upload__local_file_not_copied">%1$s n\'a pas pu être copié dans le dossier local %2$s</string>
-  <string name="prefs_instant_upload_path_title">Répertoire d\'envoi</string>
+  <string name="prefs_instant_upload_path_title">Répertoire de téléversement</string>
   <string name="share_link_no_support_share_api">Désolé, le partage n\'est pas disponible sur votre serveur. Veuillez contacter votre administrateur.</string>
   <string name="share_link_file_no_exist">Impossible de partager. Vérifiez que le fichier est bien présent</string>
   <string name="share_link_file_error">Une erreur est survenue lors de la tentative de partage de ce fichier ou répertoire</string>
   <string name="unshare_link_file_no_exist">Impossible de supprimer le partage. Vérifiez que le fichier est bien présent</string>
   <string name="unshare_link_file_error">Une erreur est survenue lors de la tentative d’annulation du partage de ce fichier ou répertoire</string>
+  <string name="share_link_password_title">Saisir un mot de passe</string>
+  <string name="share_link_empty_password">Vous devez saisir un mot de passe</string>
   <string name="activity_chooser_send_file_title">Envoyer</string>
   <string name="copy_link">Copier le lien</string>
   <string name="clipboard_text_copied">Copié dans le presse-papiers</string>
   <string name="error_cant_bind_to_operations_service">Erreur critique : impossible de réaliser des opérations</string>
-  <string name="network_error_socket_exception">Une erreur s\'est produite pendant la connection au serveur</string>
-  <string name="network_error_socket_timeout_exception">Une erreur est survenue pendant l\'attente du serveur. L\'opération n\'a pas pu être effectuée.</string>
-  <string name="network_error_connect_timeout_exception">Une erreur est survenue pendant l\'attente du serveur. L\'opération n\'a pas pu être effectuée.</string>
-  <string name="network_host_not_available">L\'opération n\'a pas pu être terminée, le serveur n\'est pas disponible.</string>
+  <string name="network_error_socket_exception">Une erreur est survenue pendant la connexion au serveur.</string>
+  <string name="network_error_socket_timeout_exception">Une erreur est survenue pendant l\'attente du serveur. L\'opération n\'a pas pu être effectuée</string>
+  <string name="network_error_connect_timeout_exception">Une erreur est survenue pendant l\'attente du serveur. L\'opération n\'a pas pu être effectuée</string>
+  <string name="network_host_not_available">L\'opération n\'a pas pu être terminée, le serveur n\'est pas disponible</string>
   <string name="empty"></string>
   <string name="forbidden_permissions">Vous ne possédez pas les droits suffisants %s</string>
   <string name="forbidden_permissions_rename">afin de renommer ce fichier</string>
@@ -283,12 +286,12 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="downloader_download_file_not_found">Ce fichier n’est plus disponible sur le serveur</string>
   <string name="prefs_category_accounts">Comptes</string>
   <string name="prefs_add_account">Ajouter un compte</string>
-  <string name="auth_redirect_non_secure_connection_title">La connexion sécurisée est redirigée via une route non-sécurisée.</string>
+  <string name="auth_redirect_non_secure_connection_title">Le connexion sécurisée est redirigée vers une route non-sécurisée.</string>
   <string name="actionbar_logger">Journaux</string>
   <string name="log_send_history_button">Envoyer l\'historique</string>
-  <string name="log_send_no_mail_app">Aucune application trouvée pour envoyer les logs. Installez une application de courriel !</string>
+  <string name="log_send_no_mail_app">Aucune application trouvée pour l\'envoi de journaux. Installer une application de courriel !</string>
   <string name="log_send_mail_subject">Journaux de l\'application Android %1$s</string>
-  <string name="log_progress_dialog_text">Chargement des données...</string>
+  <string name="log_progress_dialog_text">Chargement des données</string>
   <string name="saml_authentication_required_text">Authentification requise</string>
   <string name="saml_authentication_wrong_pass">Mot de passe incorrect</string>
   <string name="actionbar_move">Déplacer</string>
@@ -299,8 +302,11 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="move_file_invalid_overwrite">Le fichier existe déjà dans le dossier de destination</string>
   <string name="move_file_error">Une erreur est survenue lors de la tentative de déplacement de ce fichier ou dossier</string>
   <string name="forbidden_permissions_move">de déplacer ce fichier</string>
-  <string name="prefs_category_instant_uploading">Envoi instantané</string>
+  <string name="prefs_category_instant_uploading">Envois immédiats</string>
   <string name="prefs_category_security">Sécurité</string>
-  <string name="prefs_instant_video_upload_path_title">Répertoire d\'envoi des vidéos</string>
-  <string name="download_folder_failed_content">Le téléchargement du dossier %1$s n\'a pas pu être achevé complètement</string>
+  <string name="prefs_instant_video_upload_path_title">Répertoire de téléversement des vidéos</string>
+  <string name="download_folder_failed_content">Le téléchargement du dossier %1$s n\'a pas pu être achevé</string>
+  <string name="subject_token">%1$s a partagé \"%2$s\" avec vous</string>
+  <string name="auth_refresh_button">Actualiser la connexion</string>
+  <string name="auth_host_address">Adresse du serveur</string>
 </resources>
index b5371f8..feb527f 100644 (file)
@@ -8,7 +8,7 @@
   <string name="actionbar_upload_files">Ficheiros</string>
   <string name="actionbar_open_with">Abrir con</string>
   <string name="actionbar_mkdir">Novo cartafol</string>
-  <string name="actionbar_settings">Preferencias</string>
+  <string name="actionbar_settings">Axustes</string>
   <string name="actionbar_see_details">Detalles</string>
   <string name="actionbar_send_file">Enviar</string>
   <string name="actionbar_sort">Ordenar</string>
@@ -161,16 +161,16 @@ Descárgueo de aquí: %2$s</string>
   <string name="auth_no_net_conn_title">Sen conexión de rede</string>
   <string name="auth_nossl_plain_ok_title">Non hai conexión seguras dispoñíbeis.</string>
   <string name="auth_connection_established">Estabeleceuse a conexión</string>
-  <string name="auth_testing_connection">Comprobando a conexión...</string>
+  <string name="auth_testing_connection">Probando a conexión</string>
   <string name="auth_not_configured_title">Configuración errada do servidor</string>
   <string name="auth_account_not_new">Xa existe unha conta do mesmo usuario e servidor neste dispositivo</string>
   <string name="auth_account_not_the_same">O usuario que introduciu non coincide co usuario desta conta</string>
   <string name="auth_unknown_error_title">Produciuse un erro descoñecido!</string>
   <string name="auth_unknown_host_title">Non foi posíbel atopar a máquina</string>
   <string name="auth_incorrect_path_title">Non se atopou unha instancia do servidor</string>
-  <string name="auth_timeout_title">O servidor tardou demasiado en responder</string>
+  <string name="auth_timeout_title">O servidor tardou de máis en responder</string>
   <string name="auth_incorrect_address_title">URL incorrecto</string>
-  <string name="auth_ssl_general_error_title">Produciuse un fallo ao iniciar o SSL</string>
+  <string name="auth_ssl_general_error_title">Produciuse un fallo ao preparar o SSL</string>
   <string name="auth_ssl_unverified_server_title">Non foi posíbel verificar a identidade do servidor SSL</string>
   <string name="auth_bad_oc_version_title">Versión do servidor non recoñecida</string>
   <string name="auth_wrong_connection_title">Non é posíbel estabelecer a conexión</string>
@@ -188,6 +188,7 @@ Descárgueo de aquí: %2$s</string>
   <string name="auth_fail_get_user_name">O seu servidor non devolveu un ID de usuario correcto, contacte cun administrador
        </string>
   <string name="auth_can_not_auth_against_server">Non pode autenticarse neste servidor</string>
+  <string name="auth_account_does_not_exist">Aínda non existe a conta no dispositivo</string>
   <string name="fd_keep_in_sync">Manter actualizado o ficheiro</string>
   <string name="common_rename">Renomear</string>
   <string name="common_remove">Retirar</string>
@@ -261,6 +262,8 @@ Descárgueo de aquí: %2$s</string>
   <string name="share_link_file_error">Produciuse un erro ao tentar compartir este ficheiro ou cartafol.</string>
   <string name="unshare_link_file_no_exist">Non foi posíbel deixar de compartir. Comprobe que existe o ficheiro</string>
   <string name="unshare_link_file_error">Produciuse un erro ao tentar deixar de compartir este ficheiro ou cartafol</string>
+  <string name="share_link_password_title">Escriba un contrasinal</string>
+  <string name="share_link_empty_password">Ten que escribir un contrasinal</string>
   <string name="activity_chooser_send_file_title">Enviar</string>
   <string name="copy_link">Copiar a ligazón</string>
   <string name="clipboard_text_copied">Copiado no portapapeis.</string>
@@ -299,5 +302,8 @@ Descárgueo de aquí: %2$s</string>
   <string name="prefs_category_instant_uploading">Envío instantáneo</string>
   <string name="prefs_category_security">Seguranza</string>
   <string name="prefs_instant_video_upload_path_title">Enviar a ruta do vídeo</string>
-  <string name="download_folder_failed_content">A descarga do cartafol %1$s non se puido completar</string>
+  <string name="download_folder_failed_content">Non foi posíbel completar a descarga do cartafol %1$s</string>
+  <string name="subject_token">%1$s compartiu «%2$s» con vostede</string>
+  <string name="auth_refresh_button">Actualizar a conexión</string>
+  <string name="auth_host_address">Enderezo do servidor</string>
 </resources>
index 120ca55..dd4bfd6 100644 (file)
   <string name="auth_no_net_conn_title">אין חיבור לאינטרנט</string>
   <string name="auth_nossl_plain_ok_title">אין חיבור מוצפן זמין.</string>
   <string name="auth_connection_established">החיבור נוצר</string>
-  <string name="auth_testing_connection">החיבור נבדק…</string>
   <string name="auth_not_configured_title">תצורת השרת פגומה</string>
   <string name="auth_account_not_new">חשבון לאותו משתמש ושרת כבר קיים במכשיר זה</string>
   <string name="auth_account_not_the_same">שם המשתמש שהוכנס לא מתאים לשם המשתמש של חשבון זה</string>
   <string name="prefs_add_account">הוספת חשבון</string>
   <string name="folder_picker_choose_button_text">בחירה</string>
   <string name="prefs_category_security">אבטחה</string>
+  <string name="auth_host_address">כתובת שרת</string>
 </resources>
index eb8bf88..b80c5fc 100644 (file)
@@ -64,4 +64,5 @@
   <string name="saml_authentication_wrong_pass">Pogrešna lozinka</string>
   <string name="folder_picker_choose_button_text">Odaberite</string>
   <string name="prefs_category_security">Sigurnost</string>
+  <string name="auth_host_address">Adresa poslužitelja</string>
 </resources>
index ff42f94..07e2bf9 100644 (file)
   <string name="auth_no_net_conn_title">Nincs hálózati kapcsolat</string>
   <string name="auth_nossl_plain_ok_title">Nem érhető el biztonságos kapcsolat.</string>
   <string name="auth_connection_established">A kapcsolat létrejött</string>
-  <string name="auth_testing_connection">Kapcsolat tesztelése...</string>
   <string name="auth_not_configured_title">Hibás a kiszolgáló beállítása</string>
   <string name="auth_account_not_new">Egy bejelentkezési beállítás már létezik ugyanehhez a kiszolgálóhoz és felhasználóhoz</string>
   <string name="auth_account_not_the_same">A megadott felhasználó nem azonos ezzel a belépési jogosultsággal</string>
   <string name="actionbar_move">Mozgatás</string>
   <string name="folder_picker_choose_button_text">Válasszon</string>
   <string name="prefs_category_security">Biztonság</string>
+  <string name="auth_host_address">A kiszolgáló címe</string>
 </resources>
index 1f8c5b4..b37979e 100644 (file)
@@ -9,25 +9,35 @@
        <item>Biggest - Smallest</item>-->
   <string name="prefs_category_general">General</string>
   <string name="prefs_category_more">Plus</string>
+  <string name="prefs_accounts">Contos</string>
+  <string name="prefs_log_delete_history_button">Deler historia</string>
   <string name="prefs_help">Adjuta</string>
   <string name="auth_username">Nomine de usator</string>
   <string name="auth_password">Contrasigno</string>
   <string name="sync_string_files">Files</string>
   <string name="setup_btn_connect">Connecte</string>
   <string name="uploader_btn_upload_text">Incargar</string>
+  <string name="uploader_wrn_no_account_title">Nulle contos trovate</string>
   <string name="file_list_seconds_ago">secundas passate</string>
   <string name="file_list_empty">Nihil hic. Incarga alcun cosa!</string>
+  <string name="file_list_folder">dossier</string>
+  <string name="filedetails_size">Dimension:</string>
+  <string name="filedetails_type">Typo:</string>
   <string name="filedetails_download">Discargar</string>
   <string name="action_share_file">Compartir ligamine</string>
   <string name="common_yes">Si</string>
   <string name="common_no">No</string>
   <string name="common_ok">Ok</string>
+  <string name="common_cancel_download">Cancellar discarga</string>
   <string name="common_cancel">Cancellar</string>
   <string name="common_error">Error</string>
   <string name="common_error_unknown">Error Incognite</string>
   <string name="change_password">Cambiar contrasigno</string>
+  <string name="delete_account">Deler conto</string>
   <string name="uploader_info_dirname">Nomine de dossier</string>
   <string name="activity_chooser_send_file_title">Invia</string>
   <string name="empty"></string>
+  <string name="prefs_category_accounts">Contos</string>
+  <string name="saml_authentication_wrong_pass">Contrasigno errate</string>
   <string name="folder_picker_choose_button_text">Seliger</string>
 </resources>
index 1b0dd76..7256bb1 100644 (file)
   <string name="auth_no_net_conn_title">Tidak ada koneksi internet</string>
   <string name="auth_nossl_plain_ok_title">Sambungan aman tidak tersedia</string>
   <string name="auth_connection_established">Sambungan dibuat</string>
-  <string name="auth_testing_connection">Pengetesan koneksi ...</string>
   <string name="auth_not_configured_title">Konfigurasi server cacat</string>
   <string name="auth_account_not_new">Akun untuk pengguna dan server yang sama sudah ada dalam perangkat</string>
   <string name="auth_account_not_the_same">Pengguna yang dimasukkan tidak cocok dengan pengguna akun ini</string>
   <string name="forbidden_permissions_move">untuk memindahkan berkas ini</string>
   <string name="prefs_category_instant_uploading">Unggah Cepat</string>
   <string name="prefs_category_security">Keamanan</string>
+  <string name="auth_host_address">Alamat server</string>
 </resources>
index 2811b4c..e222194 100644 (file)
@@ -28,4 +28,5 @@
   <string name="activity_chooser_send_file_title">Senda</string>
   <string name="empty"></string>
   <string name="folder_picker_choose_button_text">Veldu</string>
+  <string name="auth_host_address">Host nafn netþjóns</string>
 </resources>
index a4d161a..32c6d20 100644 (file)
   <string name="auth_no_net_conn_title">Nessuna connessione di rete</string>
   <string name="auth_nossl_plain_ok_title">Connessione sicura disponibile.</string>
   <string name="auth_connection_established">Connessione stabilita</string>
-  <string name="auth_testing_connection">Prova di connessione in corso...</string>
+  <string name="auth_testing_connection">Prova di connessione</string>
   <string name="auth_not_configured_title">Configurazione non corretta di il server</string>
   <string name="auth_account_not_new">Esiste già un account su questo dispositivo per lo stesso utente e server</string>
   <string name="auth_account_not_the_same">L\'utente digitato non corrisponde all\'utente di questo account</string>
   <string name="auth_fail_get_user_name">Il tuo server non ha restituito un id utente corretto, contatta un amministratore
        </string>
   <string name="auth_can_not_auth_against_server">Impossibile eseguire l\'autenticazione su questo server</string>
+  <string name="auth_account_does_not_exist">L\'account non esiste ancora sul dispositivo</string>
   <string name="fd_keep_in_sync">Tieni aggiornato il file</string>
   <string name="common_rename">Rinomina</string>
   <string name="common_remove">Rimuovi</string>
   <string name="share_link_file_error">Si è verificato un errore durante il tentativo di condivisione del file o della cartella</string>
   <string name="unshare_link_file_no_exist">Impossibile rimuovere dalla condivisione. Assicurati che il file esista</string>
   <string name="unshare_link_file_error">Si è verificato un errore durante il tentativo di rimuovere la condivisione del file o della cartella</string>
+  <string name="share_link_password_title">Digita una password</string>
+  <string name="share_link_empty_password">Devi digitare una password</string>
   <string name="activity_chooser_send_file_title">Invia</string>
   <string name="copy_link">Copia collegamento</string>
   <string name="clipboard_text_copied">Copiato negli appunti</string>
   <string name="prefs_category_security">Protezione</string>
   <string name="prefs_instant_video_upload_path_title">Percorso di caricamento video</string>
   <string name="download_folder_failed_content">Lo scaricamento della cartella %1$s non può essere completato</string>
+  <string name="subject_token">%1$s ha condiviso \"%2$s\" con te</string>
+  <string name="auth_refresh_button">Aggiorna la connessione</string>
+  <string name="auth_host_address">Indirizzo del server</string>
 </resources>
index 3e1395f..dc70fd3 100644 (file)
   <string name="auth_no_net_conn_title">ネットワークに接続されていません</string>
   <string name="auth_nossl_plain_ok_title">暗号化通信が利用できません。</string>
   <string name="auth_connection_established">接続が確立しました</string>
-  <string name="auth_testing_connection">接続をテスト中...</string>
   <string name="auth_not_configured_title">サーバー設定が間違っています</string>
   <string name="auth_account_not_new">同じユーザーとサーバーのアカウントがデバイス上にすでに存在します</string>
   <string name="auth_account_not_the_same">入力されたユーザーはこのアカウントのユーザーと一致しません</string>
   <string name="auth_connecting_auth_server">認証サーバーに接続中 ...</string>
   <string name="auth_unsupported_auth_method">サーバーはこの認証方式をサポートしていません</string>
   <string name="auth_unsupported_multiaccount">%1$s は複数アカウントをサポートしていません</string>
-  <string name="auth_fail_get_user_name">サーバーが正しいユーザーIDを返しませんでした。管理者にご連絡ください。
+  <string name="auth_fail_get_user_name">サーバーが正しいユーザーIDを返しませんでした。管理者に連絡してください。
        </string>
   <string name="auth_can_not_auth_against_server">このサーバーに対して認証できません</string>
+  <string name="auth_account_does_not_exist">デバイス上にまだアカウントが存在しません</string>
   <string name="fd_keep_in_sync">ファイルを最新に保つ</string>
   <string name="common_rename">名前を変更</string>
   <string name="common_remove">削除</string>
   <string name="placeholder_filesize">389 KB</string>
   <string name="placeholder_timestamp">2012/05/18 12:23 PM</string>
   <string name="placeholder_media_time">12:23:45</string>
-  <string name="instant_upload_on_wifi">WiFi経由でのみ写真をアップロード</string>
+  <string name="instant_upload_on_wifi">WiFi経由でのみ画像をアップロード</string>
   <string name="instant_video_upload_on_wifi">WiFi経由でのみ動画をアップロード</string>
   <string name="instant_upload_path">/InstantUpload</string>
   <string name="conflict_title">更新が競合</string>
   <string name="preview_image_error_unknown_format">この画像は表示できません</string>
   <string name="error__upload__local_file_not_copied">%1$s は、ローカルフォルダー %2$s  にコピーできませんでした。</string>
   <string name="prefs_instant_upload_path_title">アップロードパス</string>
-  <string name="share_link_no_support_share_api">申し訳ございません。共有がサーバー上で有効になっていません。 管理者に
-               ご連絡ください。</string>
+  <string name="share_link_no_support_share_api">すみませんが、サーバーで共有が有効になっていません。
+               管理者に連絡してください。</string>
   <string name="share_link_file_no_exist">共有できません。ファイルがあるか確認してください。</string>
   <string name="share_link_file_error">このファイルまたはフォルダーを共有する際にエラーが発生しました</string>
   <string name="unshare_link_file_no_exist">共有を解除できません。ファイルがあるか確認してください。</string>
   <string name="unshare_link_file_error">このファイルまたはフォルダーの共有を解除する際にエラーが発生しました</string>
+  <string name="share_link_password_title">パスワードを入力</string>
+  <string name="share_link_empty_password">パスワードを入力しなければなりません</string>
   <string name="activity_chooser_send_file_title">送信</string>
   <string name="copy_link">リンクをコピー</string>
   <string name="clipboard_text_copied">クリップボードにコピー</string>
   <string name="prefs_category_security">セキュリティ</string>
   <string name="prefs_instant_video_upload_path_title">動画のアップロードパス</string>
   <string name="download_folder_failed_content">%1$s のフォルダのダウンロードが完了しませんでした。</string>
+  <string name="subject_token">%1$sがあなたと\"%2$s\"を共有しました</string>
+  <string name="auth_host_address">サーバーアドレス</string>
 </resources>
index 7836c23..b8176d5 100644 (file)
   <string name="prefs_category_accounts">ანგარიში</string>
   <string name="folder_picker_choose_button_text">არჩევა</string>
   <string name="prefs_category_security">უსაფრთხოება</string>
+  <string name="auth_host_address">სერვერის მისამართი</string>
 </resources>
index 535f76b..e794bc1 100644 (file)
@@ -2,7 +2,9 @@
 <resources>
   <string name="about_android">%1$s កម្មវិធីអានដ្រយ</string>
   <string name="about_version">ជំនាន់ %1$s</string>
+  <string name="actionbar_sync">គណនីឱ្យថ្មីឡើងវិញ</string>
   <string name="actionbar_upload">ផ្ទុក​ឡើង</string>
+  <string name="actionbar_upload_from_apps">មាតិការ​ពីកម្មវិធីផ្សេងទៀត</string>
   <string name="actionbar_upload_files">ឯកសារ</string>
   <string name="actionbar_open_with">បើកជាមួយ</string>
   <string name="actionbar_mkdir">ថត​ថ្មី</string>
   <string name="prefs_accounts">គណនី</string>
   <string name="prefs_manage_accounts">គ្រប់គ្រង​គណនី</string>
   <string name="prefs_pincode">ភីន​កូដ កម្មវិធី</string>
+  <string name="prefs_log_title">ដំណើរការការចូលទៅកាន់</string>
+  <string name="prefs_log_summary">នេះជាបញ្ហា​សម្រាប់​អ្នក​ដែល​បាន​ចូលទៅកាន់</string>
+  <string name="prefs_log_title_history">ប្រវត្តិនៃការចូលទៅកាន់</string>
+  <string name="prefs_log_summary_history">នៅទីនេះ​គឺបង្ហាញការដែលបាន​ចូលទៅកាន់</string>
+  <string name="prefs_log_delete_history_button">លុប​ប្រវត្តិ</string>
   <string name="prefs_help">ជំនួយ</string>
+  <string name="prefs_recommend">ផ្ដល់អនុសាសន៍ទៅកាន់មិត្តភក្ដិ</string>
+  <string name="prefs_feedback">មតិត្រឡប់</string>
   <string name="auth_username">ឈ្មោះ​អ្នកប្រើ</string>
   <string name="auth_password">ពាក្យសម្ងាត់</string>
   <string name="sync_string_files">ឯកសារ</string>
@@ -75,7 +84,6 @@
   <string name="pincode_stored">App PIN បាន​យក​មកវិញ</string>
   <string name="auth_trying_to_login">កំពុង​​តែ​ព្យាយាម​ដើម្បី​ចូល...</string>
   <string name="auth_no_net_conn_title">គ្មានបណ្តាញ​តភ្ជាប់ទេ</string>
-  <string name="auth_testing_connection">ការតភ្ជាប់កំពុង​តែធ្វើតេស្ត...</string>
   <string name="auth_unknown_error_title">មិនស្គាល់កំហុសបានកើតឡើង!</string>
   <string name="fd_keep_in_sync">រក្សាឯកសាររហូតដល់កាលបរិច្ឆេទ</string>
   <string name="common_rename">ប្ដូរ​ឈ្មោះ</string>
   <string name="saml_authentication_wrong_pass">ខុស​ពាក្យ​សម្ងាត់</string>
   <string name="folder_picker_choose_button_text">ជ្រើស</string>
   <string name="prefs_category_security">សុវត្ថិភាព</string>
+  <string name="auth_host_address">អាសយដ្ឋាន​ម៉ាស៊ីន​បម្រើ</string>
 </resources>
index f55428e..667e517 100644 (file)
@@ -32,4 +32,5 @@
   <string name="saml_authentication_wrong_pass">ದುರ್ಬಲ ಗುಪ್ತಪದ</string>
   <string name="folder_picker_choose_button_text">ಆಯ್ಕೆ</string>
   <string name="prefs_category_security">ಭದ್ರತೆ</string>
+  <string name="auth_host_address">ಪರಿಚಾರಕ ಗಣಕಯಂತ್ರದ ವಿಳಾಸ</string>
 </resources>
index f1ad81e..a6bd3d5 100644 (file)
   <string name="auth_no_net_conn_title">네트워크에 연결할 수 없습니다</string>
   <string name="auth_nossl_plain_ok_title">암호화된 연결을 사용할 수 없습니다.</string>
   <string name="auth_connection_established">연결됨</string>
-  <string name="auth_testing_connection">연결 테스트 중...</string>
   <string name="auth_not_configured_title">서버 설정이 잘못됨</string>
   <string name="auth_account_not_new">같은 사용자와 서버에 대한 계정이 이미 존재합니다</string>
   <string name="auth_account_not_the_same">입력된 사용자가 이 계정의 사용자와 일치하지 않습니다</string>
   <string name="auth_fail_get_user_name">서버에서 올바른 사용자 ID를 반환하지 않았습니다. 관리자에게 연락하십시오
        </string>
   <string name="auth_can_not_auth_against_server">이 서버에 인증할 수 없음</string>
+  <string name="auth_account_does_not_exist">장치에 아직 계정이 존재하지 않습니다.</string>
   <string name="fd_keep_in_sync">파일을 최신 정보로 유지</string>
   <string name="common_rename">이름 바꾸기</string>
   <string name="common_remove">삭제</string>
   <string name="share_link_file_error">이 파일이나 폴더를 공유하는 중 오류 발생</string>
   <string name="unshare_link_file_no_exist">공유를 해제할 수 없습니다. 파일이 있는지 확인하십시오</string>
   <string name="unshare_link_file_error">이 파일이나 폴더의 공유를 해제하는 중 오류 발생</string>
+  <string name="share_link_password_title">비밀번호를 입력하십시요.</string>
+  <string name="share_link_empty_password">비밀번호를 입력해야만 합니다.</string>
   <string name="activity_chooser_send_file_title">보내기</string>
   <string name="copy_link">링크 주소 복사</string>
   <string name="clipboard_text_copied">클립보드로 복사됨</string>
   <string name="prefs_category_security">보안</string>
   <string name="prefs_instant_video_upload_path_title">동영상 업로드 경로</string>
   <string name="download_folder_failed_content">%1$s 폴더를 다운로드할 수 없습니다</string>
+  <string name="subject_token">%1$s에서 \"%2$s\"를 당신과 공유하였습니다.</string>
+  <string name="auth_host_address">서버 주소</string>
 </resources>
index c342c64..13c023b 100644 (file)
@@ -31,4 +31,5 @@
   <string name="uploader_info_dirname">ناوی بوخچه</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">هەژمارەکان</string>
+  <string name="auth_host_address">ناونیشانی ڕاژه</string>
 </resources>
index 9feccd8..09b11cc 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 826c0a2..8518d69 100644 (file)
@@ -92,4 +92,5 @@
   <string name="empty"></string>
   <string name="prefs_category_accounts">Accounten</string>
   <string name="folder_picker_choose_button_text">Auswielen</string>
+  <string name="auth_host_address">Server Adress</string>
 </resources>
index 69623e1..dc11d0f 100644 (file)
@@ -2,5 +2,6 @@
 <resources>
   <!--TODO re-enable when server-side folder size calculation is available   
        <item>Biggest - Smallest</item>-->
+  <string name="common_error_unknown">ຂໍ້ຜິດພາດທີ່ບໍ່ຮູ້ສາເຫດ</string>
   <string name="empty"></string>
 </resources>
index 76e0e52..6446f30 100644 (file)
   <string name="auth_no_net_conn_title">Nėra tinklo ryšio</string>
   <string name="auth_nossl_plain_ok_title">Saugus prisijungimas negalimas.</string>
   <string name="auth_connection_established">Ryšys užmegztas</string>
-  <string name="auth_testing_connection">Išbandomas prisijungimas...</string>
   <string name="auth_not_configured_title">Sugadinta serverio konfigūracija</string>
   <string name="auth_account_not_new">To paties vartotojo ir serverio paskyra jau egzistuoja šiame įrenginyje</string>
   <string name="auth_unknown_error_title">Įvyko nežinoma klaida!</string>
   <string name="saml_authentication_wrong_pass">Neteisingas slaptažodis</string>
   <string name="folder_picker_choose_button_text">Pasirinkite</string>
   <string name="prefs_category_security">Saugumas</string>
+  <string name="auth_host_address">Serverio adresas</string>
 </resources>
index 0895ca9..e749454 100644 (file)
@@ -3,9 +3,12 @@
   <string name="actionbar_upload">Augšupielādēt</string>
   <string name="actionbar_upload_from_apps">Saturs no citām lietotnēm</string>
   <string name="actionbar_upload_files">Datnes</string>
+  <string name="actionbar_open_with">Atvērt ar</string>
   <string name="actionbar_mkdir">Jauna mape</string>
   <string name="actionbar_settings">Iestatījumi</string>
   <string name="actionbar_send_file">Sūtīt</string>
+  <string name="actionbar_sort">Kārtot</string>
+  <string name="actionbar_sort_title">Kārtot pēc</string>
   <!--TODO re-enable when server-side folder size calculation is available   
        <item>Biggest - Smallest</item>-->
   <string name="prefs_category_general">Vispārīgi</string>
@@ -89,7 +92,6 @@
   <string name="auth_no_net_conn_title">Nav tīkla savienojumu</string>
   <string name="auth_nossl_plain_ok_title">Nav pieejams drošs savienojums.</string>
   <string name="auth_connection_established">Savienojums ir izveidots</string>
-  <string name="auth_testing_connection">Testē savienojumu...</string>
   <string name="auth_not_configured_title">Slikti formatēta servera konfigurācija</string>
   <string name="auth_unknown_error_title">Gadījās nezināma kļūda!</string>
   <string name="auth_unknown_host_title">Nevarēja atrast datoru</string>
   <string name="saml_authentication_wrong_pass">Nepareiza parole</string>
   <string name="folder_picker_choose_button_text">Izvēlieties</string>
   <string name="prefs_category_security">Drošība</string>
+  <string name="auth_host_address">Servera adrese</string>
 </resources>
index 2ce829c..0b7dd1f 100644 (file)
@@ -75,7 +75,6 @@
   <string name="auth_no_net_conn_title">Нема мрежна конекција</string>
   <string name="auth_nossl_plain_ok_title">Нема безбедна конекција.</string>
   <string name="auth_connection_established">Конекцијата е воспоставена</string>
-  <string name="auth_testing_connection">Ја тестирам врската...</string>
   <string name="auth_unknown_error_title">Се појави непознаа грешка!</string>
   <string name="auth_unknown_host_title">Не можев да го најдам хостот</string>
   <string name="auth_incorrect_path_title">Серверската инстанца не е пронајдена</string>
   <string name="saml_authentication_wrong_pass">Погрешна лозинка</string>
   <string name="folder_picker_choose_button_text">Избери</string>
   <string name="prefs_category_security">Безбедност</string>
+  <string name="auth_host_address">Адреса на сервер</string>
 </resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
new file mode 100644 (file)
index 0000000..69623e1
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<resources>
+  <!--TODO re-enable when server-side folder size calculation is available   
+       <item>Biggest - Smallest</item>-->
+  <string name="empty"></string>
+</resources>
index 9e24a59..6746b6f 100644 (file)
@@ -52,4 +52,5 @@
   <string name="confirmation_remove_local">Lokal sahaja</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">Akaun</string>
+  <string name="auth_host_address">Alamat pelayan</string>
 </resources>
index 0889d62..4cefd16 100644 (file)
@@ -12,7 +12,7 @@
   <string name="actionbar_see_details">Detaljer</string>
   <string name="actionbar_send_file">Send</string>
   <string name="actionbar_sort">Sorter</string>
-  <string name="actionbar_sort_title">Sorter </string>
+  <string name="actionbar_sort_title">Sorter etter</string>
   <string-array name="actionbar_sortby">
     <item>A-Z</item>
     <item>Nyeste - Eldste</item>
   <string name="auth_no_net_conn_title">Ingen nettverkstilkobling</string>
   <string name="auth_nossl_plain_ok_title">Sikker tilkobling ikke tilgjengelig.</string>
   <string name="auth_connection_established">Tilkobling opprettet</string>
-  <string name="auth_testing_connection">Tester tilgang...</string>
   <string name="auth_not_configured_title">Feil i server konfigurasjon</string>
   <string name="auth_account_not_new">En konto for samme bruker og server finnes allerede på enheten</string>
   <string name="auth_account_not_the_same">Den innskrevne brukeren matcher ikke brukeren av denne kontoen</string>
   <string name="auth_fail_get_user_name">Tjeneren din svarer ikke med korrekt bruker-ID, vennligst ta kontakt med en administrator
        </string>
   <string name="auth_can_not_auth_against_server">Kan ikke autentisere mot denne serveren</string>
+  <string name="auth_account_does_not_exist">Kontoen eksisterer ikke på enheten enda</string>
   <string name="fd_keep_in_sync">Hold filen oppdatert</string>
   <string name="common_rename">Endre navn</string>
   <string name="common_remove">Fjern</string>
   <string name="share_link_file_error">Det skjedde en feil under deling av denne filen eller mappen</string>
   <string name="unshare_link_file_no_exist">Kan ikke fjerne deling. Sjekk om filen eksisterer.</string>
   <string name="unshare_link_file_error">En feil oppstod ved avslutting av delingen av denne filen eller mappen</string>
+  <string name="share_link_password_title">Skriv inn ett passord</string>
+  <string name="share_link_empty_password">Du må skrive inn ett passord</string>
   <string name="activity_chooser_send_file_title">Send</string>
   <string name="copy_link">Kopier lenke</string>
   <string name="clipboard_text_copied">Kopiert til utklippstavlen</string>
   <string name="prefs_category_instant_uploading">Umiddelbare opplastinger</string>
   <string name="prefs_category_security">Sikkerhet</string>
   <string name="prefs_instant_video_upload_path_title">Sti til video-opplasting</string>
+  <string name="download_folder_failed_content">Nedlasting av %1$s mappen kunne ikke fullføres</string>
+  <string name="subject_token">%1$s har delt \"%2$s\" med deg</string>
+  <string name="auth_host_address">Server-adresse</string>
 </resources>
index 240a713..ee15ae9 100644 (file)
@@ -163,7 +163,7 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="auth_no_net_conn_title">Geen netwerkverbinding</string>
   <string name="auth_nossl_plain_ok_title">Veilige verbinding niet beschikbaar.</string>
   <string name="auth_connection_established">Verbinding tot stand gebracht</string>
-  <string name="auth_testing_connection">Probeer verbinding...</string>
+  <string name="auth_testing_connection">Testen verbinding</string>
   <string name="auth_not_configured_title">Foutieve server configuratie</string>
   <string name="auth_account_not_new">Er bestaat al een account voor deze gebruiker en server op dit apparaat.</string>
   <string name="auth_account_not_the_same">De opgegeven gebruiker komt niet overeen met de gebruiker van dit account</string>
@@ -190,6 +190,7 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="auth_fail_get_user_name">Uw server geeft geen goede userid terug, neem contact op met uw beheerder
        </string>
   <string name="auth_can_not_auth_against_server">Kan niet authenticeren tegen deze server</string>
+  <string name="auth_account_does_not_exist">Het account bestaat nog niet in dit apparaat</string>
   <string name="fd_keep_in_sync">Houd bestand actueel</string>
   <string name="common_rename">Hernoemen</string>
   <string name="common_remove">Verwijderen</string>
@@ -263,6 +264,8 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="share_link_file_error">Er trad een fout op bij uw poging dit bestand of deze map te delen</string>
   <string name="unshare_link_file_no_exist">Kan delen niet beëindigen. Ga na of het bestand bestaat</string>
   <string name="unshare_link_file_error">Er trad een fout op bij uw poging het delen van dit bestand of deze map te beëindigen</string>
+  <string name="share_link_password_title">Vul het wachtwoord in</string>
+  <string name="share_link_empty_password">U moet een wachtwoord opgeven</string>
   <string name="activity_chooser_send_file_title">Versturen</string>
   <string name="copy_link">Link kopiëren</string>
   <string name="clipboard_text_copied">Gekopieerd naar het klembord</string>
@@ -303,4 +306,6 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="prefs_instant_video_upload_path_title">Upload Video Pad</string>
   <string name="download_folder_failed_content">Download van %1$s map kon niet worden voltooid</string>
   <string name="subject_token">%1$s deelde \"%2$s\" met u</string>
+  <string name="auth_refresh_button">Verversen verbinding</string>
+  <string name="auth_host_address">Serveradres</string>
 </resources>
index 930ff33..68d4d2e 100644 (file)
@@ -97,7 +97,6 @@
   <string name="auth_no_net_conn_title">Inga nettilkopling</string>
   <string name="auth_nossl_plain_ok_title">Trygg tilkopling ikkje tilgjengeleg.</string>
   <string name="auth_connection_established">Tilkopling oppretta</string>
-  <string name="auth_testing_connection">Testar tilkopling...</string>
   <string name="auth_not_configured_title">Ugyldig tenarkonfigurasjon</string>
   <string name="auth_unknown_error_title">Ein ukjend feil oppstod!</string>
   <string name="auth_unknown_host_title">Klarte ikkje å finna tenaren</string>
   <string name="saml_authentication_wrong_pass">Feil passord</string>
   <string name="folder_picker_choose_button_text">Vel</string>
   <string name="prefs_category_security">Tryggleik</string>
+  <string name="auth_host_address">Tenaradresse</string>
 </resources>
index 05d612d..7e67719 100644 (file)
@@ -77,7 +77,6 @@
   <string name="auth_no_net_conn_title">ਕੋਈ ਨੈੱਟਵਰਕ ਕੁਨੈਕਸ਼ਨ ਨਹੀਂ ਹੈ</string>
   <string name="auth_nossl_plain_ok_title">ਸੁਰੱਖਿਅਤ ਕੁਨੈਕਸ਼ਨ ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।</string>
   <string name="auth_connection_established">ਕੁਨੈਕਸ਼ਨ ਬਣਾਇਆ ਗਿਆ ਹੈ</string>
-  <string name="auth_testing_connection">...ਕੁਨੈਕਸ਼ਨ ਟੈਸਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ</string>
   <string name="auth_unknown_error_title">ਅਣਜਾਣ ਗਲਤੀ ਆਈ ਹੈ!</string>
   <string name="auth_unknown_host_title">ਹੋਸਟ ਨਹੀਂ ਲੱਭਿਆ ਜਾ ਸਕਿਆ</string>
   <string name="auth_ssl_general_error_title">SSL ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਫੇਲ੍ਹ ਹੈ</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">ਅਕਾਊਂਟ</string>
   <string name="folder_picker_choose_button_text">ਚੁਣੋ</string>
+  <string name="auth_host_address">ਸਰਵਰ ਐਡਰੈਸ</string>
 </resources>
index 2049b35..f81f1dd 100644 (file)
@@ -39,6 +39,7 @@
   <string name="prefs_feedback">Wsparcie</string>
   <string name="prefs_imprint">Stopka</string>
   <string name="prefs_remember_last_share_location">Zapamiętaj położenie udostępnienia</string>
+  <string name="prefs_remember_last_upload_location_summary">Zapamiętaj ostatnią lokalizację wgrywania</string>
   <string name="recommend_subject">Wypróbuj %1$s na swoim smartphonie!</string>
   <string name="recommend_text">Chciałbym zaprosić Cię do używania %1$s na swoim smartfonie!\nŚciągnij tutaj: %2$s</string>
   <string name="auth_check_server">Sprawdź serwer</string>
   <string name="auth_no_net_conn_title">Brak połączenia sieciowego</string>
   <string name="auth_nossl_plain_ok_title">Nie można nawiązać bezpiecznego połączenia.</string>
   <string name="auth_connection_established">Połączenie nawiązane</string>
-  <string name="auth_testing_connection">Testowanie połączenia…</string>
   <string name="auth_not_configured_title">Uszkodzona konfiguracja serwera</string>
   <string name="auth_account_not_new">Konto tego samego użytkownika i serwera już istnieje na tym urządzeniu</string>
   <string name="auth_account_not_the_same">Podany login nie pasuje do użytkowników </string>
   <string name="auth_redirect_non_secure_connection_title">Bezpieczne połączenie jest przekierowywane przez niezabezpieczone trasy.</string>
   <string name="actionbar_logger">Logi</string>
   <string name="log_send_history_button">Wyślij historię</string>
+  <string name="log_send_no_mail_app">Brak aplikacji do wysyłania logów. Zainstaluj klienta poczty!</string>
   <string name="log_send_mail_subject">%1$s Logi aplikacji Android</string>
   <string name="log_progress_dialog_text">Ładuję dane...</string>
   <string name="saml_authentication_required_text">Wymagana autoryzacja</string>
   <string name="prefs_category_instant_uploading">Automatyczne wysyłanie</string>
   <string name="prefs_category_security">Bezpieczeństwo</string>
   <string name="prefs_instant_video_upload_path_title">Katalog wysyłania dla wideo</string>
+  <string name="download_folder_failed_content">Pobieranie %1$s katalogu nie może zostać ukończone</string>
+  <string name="auth_host_address">Adres Serwera</string>
 </resources>
index 5135951..cd8efe6 100644 (file)
   <string name="auth_no_net_conn_title">Sem conexão de rede</string>
   <string name="auth_nossl_plain_ok_title">Conexão segura indisponível.</string>
   <string name="auth_connection_established">Conexão estabelecida</string>
-  <string name="auth_testing_connection">Testando conexão...</string>
   <string name="auth_not_configured_title">Configuração do servidor mal formada</string>
   <string name="auth_account_not_new">Uma conta para o mesmo usuário e servidor já existe no dispositivo</string>
   <string name="auth_account_not_the_same">As informações que o usuário digitou não correspondem ao usuário da conta</string>
   <string name="auth_fail_get_user_name">Seu servidor não está retornando um ID de usuário correto, por favor, entre em contato com um administrador
 ⇥</string>
   <string name="auth_can_not_auth_against_server">Não foi possível autenticar neste servidor</string>
+  <string name="auth_account_does_not_exist">Conta ainda não existe no dispositivo</string>
   <string name="fd_keep_in_sync">Manter arquivo atualizado</string>
   <string name="common_rename">Renomear</string>
   <string name="common_remove">Remover</string>
   <string name="share_link_file_error">Ocorreu um erro durante a tentativa de compartilhar esse arquivo ou pasta</string>
   <string name="unshare_link_file_no_exist">Não é possível cancelar o compartilhamento. Por favor verifique se o arquivo existe</string>
   <string name="unshare_link_file_error">Ocorreu um erro ao tentar descompartilhar este arquivo ou pasta</string>
+  <string name="share_link_password_title">Digite uma senha</string>
+  <string name="share_link_empty_password">Você deve digitar uma senha</string>
   <string name="activity_chooser_send_file_title">Enviar</string>
   <string name="copy_link">Copiar o link</string>
   <string name="clipboard_text_copied">Copiado para área de transferência</string>
   <string name="prefs_category_security">Segurança</string>
   <string name="prefs_instant_video_upload_path_title">Enviar o Caminho do Vídeo</string>
   <string name="download_folder_failed_content">Baixar %1$s da pasta não pode ser completado</string>
+  <string name="subject_token">%1$s compartilhou \"%2$s\" com você</string>
+  <string name="auth_host_address">Endereço do servidor</string>
 </resources>
index 6d5a5db..d39cf25 100644 (file)
   <string name="auth_no_net_conn_title">Sem ligação à rede</string>
   <string name="auth_nossl_plain_ok_title">Ligação segura indisponível.</string>
   <string name="auth_connection_established">Ligação estabelecida</string>
-  <string name="auth_testing_connection">A testar a ligação...</string>
+  <string name="auth_testing_connection">A testar a ligação</string>
   <string name="auth_not_configured_title">Configuração do servidor incorrecta.</string>
   <string name="auth_account_not_new">Uma conta para este utilizador e servidor já existe no dispositivo</string>
   <string name="auth_account_not_the_same">O utilizador que escreveu não coincide com o nome de utilizador desta conta</string>
   <string name="auth_unsupported_multiaccount">%1$s não suporta contas múltiplas</string>
   <string name="auth_fail_get_user_name">O seu servidor não transmite o ID correcto. Por favor contacte o administrador.</string>
   <string name="auth_can_not_auth_against_server">Não foi possível autenticar no servidor</string>
+  <string name="auth_account_does_not_exist">Conta ainda não existe no dispositivo</string>
   <string name="fd_keep_in_sync">manter ficheiro actualizado</string>
   <string name="common_rename">Renomear</string>
   <string name="common_remove">Remover</string>
   <string name="share_link_file_error">Ocorreu um erro enquanto tentava partilhar este ficheiro ou pasta</string>
   <string name="unshare_link_file_no_exist">Não é possível retirar a partilha. Verifique se o ficheiro existe</string>
   <string name="unshare_link_file_error">Ocorreu um erro enquanto retirava a partilha deste ficheiro ou pasta</string>
+  <string name="share_link_password_title">Introduza uma palavra-passe</string>
+  <string name="share_link_empty_password">Você deve introduzir uma palavra-passe</string>
   <string name="activity_chooser_send_file_title">Enviar</string>
   <string name="copy_link">Copiar hiperligação</string>
   <string name="clipboard_text_copied">Copiado para a área de transferência</string>
   <string name="prefs_category_instant_uploading">Envios Instantâneos</string>
   <string name="prefs_category_security">Segurança</string>
   <string name="prefs_instant_video_upload_path_title">Envio do Caminho do Vídeo</string>
+  <string name="download_folder_failed_content">Não foi possível completar o download da pasta %1$s</string>
+  <string name="subject_token">%1$s partilhou \"%2$s\" consigo</string>
+  <string name="auth_refresh_button">Recarregar ligação</string>
+  <string name="auth_host_address">Endereço do servidor</string>
 </resources>
index 74c1b55..ece0797 100644 (file)
   <string name="prefs_recommend">Recomandati unui prieten</string>
   <string name="prefs_feedback">Feedback</string>
   <string name="prefs_imprint">Imprint</string>
+  <string name="prefs_remember_last_share_location">Reține contribuie locația</string>
+  <string name="prefs_remember_last_upload_location_summary">Reține locația fișierului încărcat precedent</string>
   <string name="recommend_subject">Încearcă %1$s pe smartphone-ul tău!</string>
+  <string name="recommend_text">Te invit sa folosești %1$s pe smartfonul tău!\nDescarcă aici: %2$s</string>
   <string name="auth_check_server">Verificaţi Serverul</string>
   <string name="auth_host_url">Adresa serverului https://...</string>
   <string name="auth_username">Nume utilizator</string>
   <string name="sync_fail_in_favourites_content">Conținutul a%1$d fișiere nu a putut fi sincronizat (conflicte %2$d)</string>
   <string name="sync_foreign_files_forgotten_ticker">Unele fisiere locale au fost uitate</string>
   <string name="sync_foreign_files_forgotten_content">%1$d fisiere din  dosarul  %2$s nu a putut fi copiat in</string>
+  <string name="sync_foreign_files_forgotten_explanation">Conform ediției 1.3.16, fișierele încărcate de pe această platformă sunt copiate în dosarul local %1$s pentru a preveni pierderi de date atunci cînd un singur fișier este sincronizat cu mai multe conturi.\n\nDin cauza acestei schimbări, toate fișierele încărcate în edițiile precedente ale acestui app au fost încărcate in dosarul %2$s. Însă acest proces nu fost completat in timpul sincronizării contului din cauza unei erori. Ai opțiunea de a lăsa fișierul intact (fișierele intacte) și de a transfera sursa în dosarul %3$s sau de a schimba locația fișierului(-elor) în dosarul %1$s și de a păstra sursa în %4$s.\n\nMai jos găsești enumerate fișierul local(fișierele locale) și fișierul separat(fișierele separate) în %5$s cu sursa respectivă.</string>
   <string name="sync_current_folder_was_removed">Folderul %1$s nu mai există</string>
   <string name="foreign_files_move">Muta tot/toate</string>
   <string name="foreign_files_success">Toate fişierele au fost mutate</string>
   <string name="auth_no_net_conn_title">Nu exista conexiune</string>
   <string name="auth_nossl_plain_ok_title">Conexiune securizată indisponibilă</string>
   <string name="auth_connection_established">Conexiune stabilită</string>
-  <string name="auth_testing_connection">Se testează conexiunea...</string>
   <string name="auth_not_configured_title">Configurație serverului incorectă</string>
   <string name="auth_account_not_new">Un cont pentru același utilizator și server există deja în dispozitiv</string>
   <string name="auth_account_not_the_same">Utilizatorul introdus nu se potrivește cu utilizatorul acestui cont</string>
   <string name="auth_unsupported_multiaccount">%1$s nu suporta conturi multiple</string>
   <string name="auth_fail_get_user_name">Server-ul dvs. nu  întoarce un ID de utilizator corect, vă rugăm să contactați un administrator </string>
   <string name="auth_can_not_auth_against_server">Nu se poate autentifica cu acest server</string>
+  <string name="auth_account_does_not_exist">Contul nu există încă în dispozitiv</string>
   <string name="fd_keep_in_sync">Păstrează fișierul actualizat</string>
   <string name="common_rename">Redenumește</string>
   <string name="common_remove">Elimină</string>
   <string name="preview_image_description">Previzualizare imagine</string>
   <string name="preview_image_error_unknown_format">Aceasta imagine nu poate fi arătată</string>
   <string name="error__upload__local_file_not_copied">%1$s nu a putut fi copiat in dosarul local %2$s </string>
+  <string name="prefs_instant_upload_path_title">Calea de încărcare</string>
   <string name="share_link_no_support_share_api">Ne pare rău, partajarea nu este activată pe server. Vă rugăm să contactați administratorul dvs.</string>
   <string name="share_link_file_error">A apărut o eroare în timp ce încerca să partajeze acest fișier sau folder</string>
   <string name="unshare_link_file_error">A apărut o eroare în timp ce încerca să departajeze sau unshare acest fișier sau folder</string>
   <string name="downloader_download_file_not_found">Fișierul nu mai este disponibil pe server</string>
   <string name="prefs_category_accounts">Conturi</string>
   <string name="prefs_add_account">Adaugă cont</string>
+  <string name="auth_redirect_non_secure_connection_title">Conexiunea securizată este redirecționată către un traseu neasigurat.</string>
+  <string name="actionbar_logger">Înregistrări</string>
+  <string name="log_send_history_button">Trimite Istoria</string>
+  <string name="log_send_no_mail_app">App-ul de trimitere a inregistrărilor nu a fost găsit. Instalează mail app-ul!</string>
+  <string name="log_send_mail_subject">%1$s înregistrările app-ului Android</string>
+  <string name="log_progress_dialog_text">Datele se încarcă...</string>
   <string name="saml_authentication_required_text">Autentificare necesară</string>
   <string name="saml_authentication_wrong_pass">Parolă greșită</string>
   <string name="actionbar_move">Mutare</string>
   <string name="file_list_empty_moving">Nu este nimic aici. Poți adăuga un director!</string>
   <string name="folder_picker_choose_button_text">Alege</string>
+  <string name="move_file_not_found">Incapabil de trasfer. Verifică existența fișierului</string>
+  <string name="move_file_invalid_overwrite">Fișierul există deja în dosarul de destinație</string>
+  <string name="move_file_error">O eroare apare la transferarea acestui fișier sau dosar</string>
   <string name="forbidden_permissions_move">pentru a muta acest fișier</string>
   <string name="prefs_category_instant_uploading">Încărcări instante</string>
   <string name="prefs_category_security">Securitate</string>
+  <string name="prefs_instant_video_upload_path_title">Calea de încărcare Video</string>
+  <string name="download_folder_failed_content">Descărcarea fișierului %1$s nu s-a finisat</string>
+  <string name="auth_host_address">Adresa server-ului</string>
 </resources>
index a9bb306..ac53bd9 100644 (file)
@@ -28,7 +28,7 @@
   <string name="prefs_instant_upload">Мгновенная загрузка фотографий</string>
   <string name="prefs_instant_upload_summary">Немедленно загружать фотографии сделанные камерой</string>
   <string name="prefs_instant_video_upload">Мгновенная загрузка видео</string>
-  <string name="prefs_instant_video_upload_summary">Немедленно загружать видео сделанные камерой</string>
+  <string name="prefs_instant_video_upload_summary">Немедленно загружать видео, сделанные камерой</string>
   <string name="prefs_log_title">Включить журналирование</string>
   <string name="prefs_log_summary">Используется для регистрации ошибок</string>
   <string name="prefs_log_title_history">Журнал</string>
@@ -53,7 +53,7 @@
   <string name="uploader_btn_upload_text">Загрузить</string>
   <string name="uploader_top_message">Выберите каталог для загрузки</string>
   <string name="uploader_wrn_no_account_title">Учётная запись не найдена</string>
-  <string name="uploader_wrn_no_account_text">На вашем устройстве нет учётных записей %1$s. Пожалуйста настройте учётную запись.</string>
+  <string name="uploader_wrn_no_account_text">На вашем устройстве нет учётных записей %1$s. Пожалуйста, настройте учётную запись.</string>
   <string name="uploader_wrn_no_account_setup_btn_text">Настройка</string>
   <string name="uploader_wrn_no_account_quit_btn_text">Выход</string>
   <string name="uploader_wrn_no_content_title">Нет содержимого для загрузки</string>
   <string name="auth_no_net_conn_title">Нет подключения к сети</string>
   <string name="auth_nossl_plain_ok_title">Защищённое соединение недоступно.</string>
   <string name="auth_connection_established">Соединение установлено</string>
-  <string name="auth_testing_connection">ТеÑ\81Ñ\82иÑ\80ование Ñ\81оединениÑ\8f...</string>
+  <string name="auth_testing_connection">Ð\9fÑ\80овеÑ\80ка Ñ\81оединениÑ\8f</string>
   <string name="auth_not_configured_title">Конфигурация сервера задана неверно</string>
   <string name="auth_account_not_new">Учётная запись такого пользователя и сервера уже существует на устройстве</string>
   <string name="auth_account_not_the_same">Введённый пользователь не соответствует этой учётной записи</string>
   <string name="auth_fail_get_user_name">Сервер вернул некорректный пользовательский идентификатор. Пожалуйста, свяжитесь с вашим администратором
 ⇥</string>
   <string name="auth_can_not_auth_against_server">Невозможно авторизоваться на этом сервере</string>
+  <string name="auth_account_does_not_exist">Аккаунт не существует на устройстве ещё</string>
   <string name="fd_keep_in_sync">Обновлять файл</string>
   <string name="common_rename">Переименовать</string>
   <string name="common_remove">Удалить</string>
   <string name="share_link_file_error">При попытке поделиться этим файлом или каталогом произошла ошибка</string>
   <string name="unshare_link_file_no_exist">Невозможно закрыть доступ. Убедитесь что файл существует</string>
   <string name="unshare_link_file_error">При попытке закрыть доступ к этому файлу или каталогу произошла ошибка</string>
+  <string name="share_link_password_title">Введите пароль</string>
+  <string name="share_link_empty_password">Вы должны ввести пароль</string>
   <string name="activity_chooser_send_file_title">Отправить</string>
   <string name="copy_link">Копировать ссылку</string>
   <string name="clipboard_text_copied">Скопировано в буфер обмена</string>
   <string name="prefs_category_security">Безопасность</string>
   <string name="prefs_instant_video_upload_path_title">Путь для загрузки Видео</string>
   <string name="download_folder_failed_content">Загрузка папки %1$s не может быть завершена</string>
+  <string name="subject_token">%1$s предоставил вам доступ к \"%2$s\"</string>
+  <string name="auth_refresh_button">Обновить соединение</string>
+  <string name="auth_host_address">Адрес сервера</string>
 </resources>
index 6eeb4f0..969daa4 100644 (file)
@@ -55,7 +55,6 @@
   <string name="auth_no_net_conn_title">ජාල සම්බන්ධතාවක් නොමැත</string>
   <string name="auth_nossl_plain_ok_title">ආරක්ෂිත සම්බන්ධතාවක් නොලැබුණි</string>
   <string name="auth_connection_established">සම්බන්ධතාවක් සාදන ලදී</string>
-  <string name="auth_testing_connection">සම්බන්ධතාව පරීක්ෂා කෙරේ</string>
   <string name="auth_not_configured_title">විකෘතිවු හැඩගැසුමක්</string>
   <string name="auth_unknown_error_title">නොදන්නා දෝෂයක් ඇතිවිය</string>
   <string name="auth_unknown_host_title">සේවාදායකයා සොයාගත නොහැක</string>
@@ -81,4 +80,5 @@
   <string name="empty"></string>
   <string name="prefs_category_accounts">ගිණුම්</string>
   <string name="folder_picker_choose_button_text">තෝරන්න</string>
+  <string name="auth_host_address">සේවාදායකයේ ලිපිනය</string>
 </resources>
index 8e993d7..0ef385d 100644 (file)
   <string name="auth_no_net_conn_title">Bez sieťového pripojenia</string>
   <string name="auth_nossl_plain_ok_title">Nie je k dispozícii bezpečné pripojenie</string>
   <string name="auth_connection_established">Pripojenie vytvorené</string>
-  <string name="auth_testing_connection">Testovane pripojenia...</string>
   <string name="auth_not_configured_title">Nesprávna konfigurácia servera</string>
   <string name="auth_account_not_new">Účet pre tohoto používateľa a tento server už v tomto zariadení existuje</string>
   <string name="auth_account_not_the_same">Zadané prihlasovacie údaje používateľa sú nesprávne</string>
   <string name="auth_fail_get_user_name">Váš server nevracia správne používateľské id, kontaktujte prosím správcu systému
        </string>
   <string name="auth_can_not_auth_against_server">Nie je možné vykonať autentifikáciu na server</string>
+  <string name="auth_account_does_not_exist">Účet zatiaľ v zariadení neexistuje</string>
   <string name="fd_keep_in_sync">Udržiavať súbor aktuálny.</string>
   <string name="common_rename">Premenuj</string>
   <string name="common_remove">Odober</string>
   <string name="prefs_category_security">Zabezpečenie</string>
   <string name="prefs_instant_video_upload_path_title">Cesta pre nahrávanie videí</string>
   <string name="download_folder_failed_content">Sťahovanie %1$s priečinka nebolo dokončené</string>
+  <string name="subject_token">%1$s vám zdieľa „%2$s“</string>
+  <string name="auth_host_address">Adresa servera</string>
 </resources>
index 731bd67..c0e3f6a 100644 (file)
   <string name="auth_no_net_conn_title">Ni omrežne povezave</string>
   <string name="auth_nossl_plain_ok_title">Varna povezava ni na voljo.</string>
   <string name="auth_connection_established">Povezava je vzpostavljena</string>
-  <string name="auth_testing_connection">Preizkušanje povezave ...</string>
   <string name="auth_not_configured_title">Napačno oblikovane nastavitve strežnika</string>
   <string name="auth_account_not_new">Na napravi račun za istega uporabnika in strežnik že obstaja</string>
   <string name="auth_account_not_the_same">Vpisan uporabnik ni lastnik tega računa</string>
   <string name="auth_fail_get_user_name">Strežnik ne vrača ustreznega ID uporabnika. Stopite v stik s skrbnikom sistema.
        </string>
   <string name="auth_can_not_auth_against_server">Ni mogoče preveriti pristnosti strežnika</string>
+  <string name="auth_account_does_not_exist">Račun na napravi še ne obstaja.</string>
   <string name="fd_keep_in_sync">Datoteka naj bo posodobljena</string>
   <string name="common_rename">Preimenuj</string>
   <string name="common_remove">Odstrani</string>
   <string name="share_link_file_error">Prišlo je do napake med poskusom omogočanja souporabe te datoteke ali mape</string>
   <string name="unshare_link_file_no_exist">Ni mogoče prekiniti souporabe. Preverite, ali datoteka obstaja.</string>
   <string name="unshare_link_file_error">Prišlo je do napake med poskusom odstranjevanja souporabe te datoteke ali mape</string>
+  <string name="share_link_password_title">Vpis gesla</string>
+  <string name="share_link_empty_password">Vpisati je treba geslo.</string>
   <string name="activity_chooser_send_file_title">Pošlji</string>
   <string name="copy_link">Kopiraj povezavo</string>
   <string name="clipboard_text_copied">Kopirano v odložišče</string>
   <string name="prefs_category_instant_uploading">Takojšnje pošiljanje v oblak</string>
   <string name="prefs_category_security">Varnost</string>
   <string name="prefs_instant_video_upload_path_title">Pot videa za pošiljanje</string>
+  <string name="download_folder_failed_content">Imenika %1$s  ni mogoče prejeti v celoti</string>
+  <string name="subject_token">Uporabnik %1$s je omogočil souporabo \"%2$s\".</string>
+  <string name="auth_host_address">Naslov strežnika</string>
 </resources>
index 02918e8..b13395b 100644 (file)
@@ -67,7 +67,6 @@
   <string name="pincode_stored">PIN-i u ruajt</string>
   <string name="auth_no_net_conn_title">Nuk ka lidhje ne Rrjet</string>
   <string name="auth_connection_established">Lidhja u vendos</string>
-  <string name="auth_testing_connection">Duke testuar lidhjen</string>
   <string name="auth_secure_connection">Lidhja e Sigurt vendos</string>
   <string name="common_rename">Riemërto</string>
   <string name="common_remove">Hiq</string>
@@ -77,4 +76,5 @@
   <string name="saml_authentication_wrong_pass">Fjalëkalim i gabuar</string>
   <string name="folder_picker_choose_button_text">Zgjidh</string>
   <string name="prefs_category_security">Siguria</string>
+  <string name="auth_host_address">Adresa e serverit</string>
 </resources>
index b9235ad..d89e7b4 100644 (file)
 <?xml version='1.0' encoding='UTF-8'?>
 <resources>
+  <string name="about_android">%1$s Андроид апликација</string>
+  <string name="about_version">верзија %1$s</string>
+  <string name="actionbar_sync">Освежи налог</string>
   <string name="actionbar_upload">Отпреми</string>
-  <string name="actionbar_upload_from_apps">Садржај са других апликација</string>
-  <string name="actionbar_upload_files">Датотеке</string>
+  <string name="actionbar_upload_from_apps">Садржај из других апликација</string>
+  <string name="actionbar_upload_files">Фајлови</string>
+  <string name="actionbar_open_with">Отвори помоћу</string>
+  <string name="actionbar_mkdir">Нова фасцикла</string>
   <string name="actionbar_settings">Поставке</string>
+  <string name="actionbar_see_details">Детаљи</string>
   <string name="actionbar_send_file">Пошаљи</string>
+  <string name="actionbar_sort">Разврстај</string>
+  <string name="actionbar_sort_title">Разврставање</string>
+  <string-array name="actionbar_sortby">
+    <item>A-Z</item>
+    <item>новији - старији</item>
+  </string-array>
   <!--TODO re-enable when server-side folder size calculation is available   
        <item>Biggest - Smallest</item>-->
   <string name="prefs_category_general">Опште</string>
   <string name="prefs_category_more">Више</string>
   <string name="prefs_accounts">Налози</string>
+  <string name="prefs_manage_accounts">Управљање налозима</string>
+  <string name="prefs_pincode">ПИБ апликације</string>
+  <string name="prefs_pincode_summary">Заштитите програм</string>
+  <string name="prefs_instant_upload">Тренутно отпремање фотографија</string>
+  <string name="prefs_instant_upload_summary">Тренутно отпремај фотографије сликане камером</string>
+  <string name="prefs_instant_video_upload">Тренутно отпремање видеа</string>
+  <string name="prefs_instant_video_upload_summary">Тренутно отпремај видео снимљен камером</string>
+  <string name="prefs_log_title">Укључи бележење</string>
+  <string name="prefs_log_summary">Ово се користи за бележење проблема</string>
+  <string name="prefs_log_title_history">Историјат бележења</string>
+  <string name="prefs_log_summary_history">Ово приказује сачуване записнике</string>
+  <string name="prefs_log_delete_history_button">Обриши историјат</string>
   <string name="prefs_help">Помоћ</string>
+  <string name="prefs_recommend">Препоручи пријатељу</string>
+  <string name="prefs_feedback">Ваше мишљење</string>
+  <string name="prefs_imprint">Жиг</string>
+  <string name="prefs_remember_last_share_location">Упамти локацију дељења</string>
+  <string name="prefs_remember_last_upload_location_summary">Памти последњу локацију отпремања дељења</string>
+  <string name="recommend_subject">Пробајте %1$s на вашем телефону!</string>
+  <string name="recommend_text">Предлажем вам да пробате %1$s на вашем телефону!\nПреузмите овде: %2$s</string>
+  <string name="auth_check_server">Провери сервер</string>
+  <string name="auth_host_url">Адреса сервера https://…</string>
   <string name="auth_username">Корисничко име</string>
   <string name="auth_password">Лозинка</string>
+  <string name="auth_register">Нов вам је %1$s?</string>
   <string name="sync_string_files">Фајлови</string>
-  <string name="setup_btn_connect">Повежи ме</string>
+  <string name="setup_btn_connect">Повежи се</string>
   <string name="uploader_btn_upload_text">Отпреми</string>
+  <string name="uploader_top_message">Изаберите фасциклу отпремања:</string>
   <string name="uploader_wrn_no_account_title">Нема налога</string>
+  <string name="uploader_wrn_no_account_text">Нема %1$s налога на вашем уређају. Прво подесите налог.</string>
   <string name="uploader_wrn_no_account_setup_btn_text">Подеси</string>
-  <string name="uploader_wrn_no_account_quit_btn_text">Ð\98заÑ\92и</string>
+  <string name="uploader_wrn_no_account_quit_btn_text">Ð\9dапÑ\83Ñ\81Ñ\82и</string>
   <string name="uploader_wrn_no_content_title">Нема садржаја за отпремање</string>
-  <string name="uploader_wrn_no_content_text">Садржај није примљен. Нема ништа да се отпреми.</string>
+  <string name="uploader_wrn_no_content_text">Садржај није примљен. Нема шта да се отпреми.</string>
+  <string name="uploader_error_forbidden_content">%1$s није дозвољен приступ дељеном садржају</string>
   <string name="uploader_info_uploading">Отпремање</string>
-  <string name="file_list_seconds_ago">пÑ\80е Ð½ÐµÐºÐ¾Ð»Ð¸ÐºÐ¾ секунди</string>
+  <string name="file_list_seconds_ago">пÑ\80е Ð¿Ð°Ñ\80 секунди</string>
   <string name="file_list_empty">Овде нема ничег. Отпремите нешто!</string>
-  <string name="filedetails_select_file">Додирните датотеку ради приказа додатних информација.</string>
+  <string name="file_list_loading">Учитавам</string>
+  <string name="local_file_list_empty">Нема фајлова у овој фасцикли.</string>
+  <string name="file_list_folder">фасцикла</string>
+  <string name="file_list_folders">фасцикле</string>
+  <string name="file_list_file">фајл</string>
+  <string name="file_list_files">фајлови</string>
+  <string name="filedetails_select_file">Тапните на фајл ради приказа додатних информација.</string>
   <string name="filedetails_size">Величина:</string>
   <string name="filedetails_type">Врста:</string>
-  <string name="filedetails_created">Направљено:</string>
-  <string name="filedetails_modified">Измењено:</string>
+  <string name="filedetails_created">Направљен:</string>
+  <string name="filedetails_modified">Измењен:</string>
   <string name="filedetails_download">Преузми</string>
-  <string name="filedetails_sync_file">Освежи датотеку</string>
+  <string name="filedetails_sync_file">Освежи фајл</string>
+  <string name="filedetails_renamed_in_upload_msg">Фајл је преименован у %1$s током отпремања</string>
+  <string name="action_share_file">Веза дељења</string>
+  <string name="action_unshare_file">Не дели везом</string>
   <string name="common_yes">Да</string>
   <string name="common_no">Не</string>
   <string name="common_ok">У реду</string>
-  <string name="common_cancel_download">Обустави преузимање</string>
-  <string name="common_cancel_upload">Ð\9fÑ\80екини Ñ\81лање</string>
+  <string name="common_cancel_download">Откажи преузимање</string>
+  <string name="common_cancel_upload">Ð\9eÑ\82кажи Ð¾Ñ\82пÑ\80емање</string>
   <string name="common_cancel">Откажи</string>
   <string name="common_save_exit">Сачувај и изађи</string>
   <string name="common_error">Грешка</string>
+  <string name="common_loading">Учитавам...</string>
+  <string name="common_error_unknown">Непозната грешка</string>
   <string name="about_title">О програму</string>
   <string name="change_password">Измени лозинку</string>
   <string name="delete_account">Обриши налог</string>
   <string name="create_account">Отвори налог</string>
   <string name="upload_chooser_title">Отпреми из…</string>
+  <string name="uploader_info_dirname">Назив фасцикле</string>
   <string name="uploader_upload_in_progress_ticker">Отпремам…</string>
   <string name="uploader_upload_in_progress_content">%1$d%% Отпремам %2$s</string>
   <string name="uploader_upload_succeeded_ticker">Отпремање је успело</string>
+  <string name="uploader_upload_succeeded_content_single">%1$s је успешно отпремљен</string>
   <string name="uploader_upload_failed_ticker">Отпремање није успело</string>
-  <string name="uploader_upload_failed_content_single">Не могу да довршим отпремање датотеке %1$s</string>
+  <string name="uploader_upload_failed_content_single">Не могу да довршим отпремање %1$s</string>
+  <string name="uploader_upload_failed_credentials_error">Отпремање неуспешно. Поново се пријавите.</string>
   <string name="downloader_download_in_progress_ticker">Преузимам…</string>
   <string name="downloader_download_in_progress_content">%1$d%% Преузимам %2$s</string>
   <string name="downloader_download_succeeded_ticker">Преузимање успешно</string>
   <string name="downloader_download_succeeded_content">%1$s је успешно преузет</string>
   <string name="downloader_download_failed_ticker">Преузимање није успело</string>
-  <string name="downloader_download_failed_content">Не могу да довршим преузимање датотеке %1$s</string>
+  <string name="downloader_download_failed_content">Не могу да довршим преузимање %1$s</string>
   <string name="downloader_not_downloaded_yet">Још увек није преузето</string>
-  <string name="common_choose_account">Изабери налог</string>
+  <string name="downloader_download_failed_credentials_error">Преузимање неуспешно. Пријавите се поново</string>
+  <string name="common_choose_account">Изаберите налог</string>
   <string name="sync_fail_ticker">Синхронизовање није успело</string>
-  <string name="sync_fail_content">Не могу да довршим синхронизацију датотеке %1$s</string>
-  <string name="foreign_files_success">Све датотеке су померене</string>
-  <string name="foreign_files_fail">Неке датотеке нису могле бити померене</string>
-  <string name="pincode_enter_pin_code">Унесите PIN апликације</string>
-  <string name="pincode_configure_your_pin_explanation">Са сваким покретањем апликације мораћете да унесете PIN</string>
+  <string name="sync_fail_ticker_unauthorized">Синхронизовање неуспешно. Пријавите се поново</string>
+  <string name="sync_fail_content">Не могу да довршим синхронизацију %1$s</string>
+  <string name="sync_fail_content_unauthorized">Неисправна лозинка за %1$s</string>
+  <string name="sync_conflicts_in_favourites_ticker">Постоје сукоби</string>
+  <string name="sync_conflicts_in_favourites_content">%1$d држи-синх фајлови нису синхронизовани</string>
+  <string name="sync_fail_in_favourites_ticker">Синхронизација није успела</string>
+  <string name="sync_fail_in_favourites_content">Садржај %1$d фајлова не може бити синхронизован (%2$d сукоба)</string>
+  <string name="sync_foreign_files_forgotten_ticker">Неки локални фајлови нису обрађени</string>
+  <string name="sync_foreign_files_forgotten_content">%1$d фајлова из фасцикле %2$s није се могло копирати у</string>
+  <string name="sync_foreign_files_forgotten_explanation">Од верзије 1.3.16, фајлови отпремљени са уређаја се копирају у локалну фасциклу %1$s да би се спречио губитак података када се исти фајл синхронизује са више налога.\n\nЗбог ове измене, сви фајлови отпремљени са претходним верзијама ове апликације се копирају у фасциклу %2$s. Међутим, грешка је онемогућила довршавање ове радње током синхронизације налога. Можете или оставити фајлове како јесу и уклонити линк до %3$s или преместити фајлове у фасциклу %1$s и задржати везу до %4$s.\n\nИспод су наведени локални фајлови и удаљени фајлови у %5$s са којима су повезани.</string>
+  <string name="sync_current_folder_was_removed">Фасцикла %1$s више не постоји</string>
+  <string name="foreign_files_move">Премести све</string>
+  <string name="foreign_files_success">Сви фајлови су премештени</string>
+  <string name="foreign_files_fail">Неки фајлови нису могли бити премештени</string>
+  <string name="foreign_files_local_text">Локално: %1$s</string>
+  <string name="foreign_files_remote_text">Удаљено: %1$s</string>
+  <string name="upload_query_move_foreign_files">Нема довољно простора да би се изабрани фајлови копирали у фасциклу %1$s. Желите ли да их преместите? </string>
+  <string name="pincode_enter_pin_code">Унесите ПИБ апликације</string>
+  <string name="pincode_configure_your_pin">Унесите ПИБ за апликацију</string>
+  <string name="pincode_configure_your_pin_explanation">Са сваким покретањем апликације мораћете да унесете ПИБ</string>
+  <string name="pincode_reenter_your_pincode">Унесите ПИБ поново</string>
+  <string name="pincode_remove_your_pincode">Уклоните ПИБ апликације</string>
+  <string name="pincode_mismatch">Бројеви се не поклапају</string>
+  <string name="pincode_wrong">Неисправан ПИБ</string>
+  <string name="pincode_removed">ПИБ је уклоњен</string>
+  <string name="pincode_stored">ПИБ је упамћен</string>
+  <string name="media_notif_ticker">%1$s музички плејер</string>
+  <string name="media_state_playing">%1$s (пуштам)</string>
+  <string name="media_state_loading">%1$s (учитавам)</string>
+  <string name="media_event_done">%1$s пуштање завршено</string>
+  <string name="media_err_nothing_to_play">Нема медијских фајлова</string>
+  <string name="media_err_no_account">Није наведен налог</string>
+  <string name="media_err_not_in_owncloud">Фајл није у исправном налогу</string>
+  <string name="media_err_unsupported">Неподржан кодек</string>
+  <string name="media_err_io">Медијски фајл се не може читати</string>
+  <string name="media_err_malformed">Медијски фајл није исправно кодиран</string>
+  <string name="media_err_timeout">Време истекло у покушавању пуштања</string>
+  <string name="media_err_invalid_progressive_playback">Медијски фајл се не може пустити</string>
+  <string name="media_err_unknown">Медијски фајл се не може пустити са системским плејером</string>
+  <string name="media_err_security_ex">Безбедносна грешка при покушају пуштања %1$s</string>
+  <string name="media_err_io_ex">Улазна грешка при покушају пуштања %1$s</string>
+  <string name="media_err_unexpected">Неочекивана грешка при покушају пуштања %1$s</string>
+  <string name="media_rewind_description">Уназад</string>
+  <string name="media_play_pause_description">Пуштање-пауза</string>
+  <string name="media_forward_description">Унапред</string>
+  <string name="auth_getting_authorization">Тражим ауторизацију...</string>
+  <string name="auth_trying_to_login">Покушавам пријављивање...</string>
   <string name="auth_no_net_conn_title">Нема мрежне везе</string>
   <string name="auth_nossl_plain_ok_title">Безбедна веза није доступна.</string>
   <string name="auth_connection_established">Веза је успостављена</string>
-  <string name="auth_unknown_error_title">Дошло је до непознате грешке.</string>
+  <string name="auth_testing_connection">Провера везе</string>
+  <string name="auth_not_configured_title">Лоше подешавање сервера</string>
+  <string name="auth_account_not_new">Налог са истим корисником и сервером већ постоји на уређају</string>
+  <string name="auth_account_not_the_same">Унесени корисник се не поклапа са корисником овог налога</string>
+  <string name="auth_unknown_error_title">Дошло је до непознате грешке!</string>
   <string name="auth_unknown_host_title">Не могу да пронађем домаћина</string>
   <string name="auth_incorrect_path_title">Не могу да пронађем примерак сервера</string>
   <string name="auth_timeout_title">Серверу је требало предуго да се одазове</string>
   <string name="auth_incorrect_address_title">Погрешно уобличена адреса</string>
-  <string name="auth_ssl_general_error_title">Покретање SSL-а није успело</string>
+  <string name="auth_ssl_general_error_title">ССЛ иницијализација није успела</string>
+  <string name="auth_ssl_unverified_server_title">Не могу да проверим ССЛ идентитет сервера</string>
+  <string name="auth_bad_oc_version_title">Непозната верзија сервера</string>
   <string name="auth_wrong_connection_title">Не могу да успоставим везу</string>
   <string name="auth_secure_connection">Безбедна веза је успостављена</string>
-  <string name="fd_keep_in_sync">Редовно ажурирај датотеку</string>
+  <string name="auth_unauthorized">Погрешно име или лозинка</string>
+  <string name="auth_oauth_error">Неуспешна ауторизација</string>
+  <string name="auth_oauth_error_access_denied">Сервер ауторизације је одбио приступ</string>
+  <string name="auth_wtf_reenter_URL">Неочекивано стање. Унесите поново адресу сервера</string>
+  <string name="auth_expired_oauth_token_toast">Ауторизација је истекла. Урадите је поново</string>
+  <string name="auth_expired_basic_auth_toast">Унесите тренутну лозинку</string>
+  <string name="auth_expired_saml_sso_token_toast">Сесија је истекла. Повежите се поново</string>
+  <string name="auth_connecting_auth_server">Повезујем се на сервер аутентификације...</string>
+  <string name="auth_unsupported_auth_method">Сервер не подржава овај начин аутентификације</string>
+  <string name="auth_unsupported_multiaccount">%1$s не подржава вишеструке налоге</string>
+  <string name="auth_fail_get_user_name">Сервер не враћа исправан ИД корисника. Контактирајте администратора
+       </string>
+  <string name="auth_can_not_auth_against_server">Не могу да аутентификујем са овим сервером</string>
+  <string name="auth_account_does_not_exist">Не постоји налог на уређају</string>
+  <string name="fd_keep_in_sync">Редовно ажурирај фајл</string>
   <string name="common_rename">Преименуј</string>
   <string name="common_remove">Уклони</string>
+  <string name="confirmation_remove_alert">Желите да уклоните %1$s?</string>
+  <string name="confirmation_remove_folder_alert">Желите да уклоните %1$s и њен садржај?</string>
   <string name="confirmation_remove_local">Само локално</string>
+  <string name="confirmation_remove_folder_local">Само локални садржај</string>
   <string name="confirmation_remove_remote">Уклони са сервера</string>
   <string name="confirmation_remove_remote_and_local">Удаљено и локално</string>
-  <string name="rename_dialog_title">Унесите ново име</string>
+  <string name="remove_success_msg">Уклањање успешно</string>
+  <string name="remove_fail_msg">Уклањање неуспешно</string>
+  <string name="rename_dialog_title">Унесите нов назив</string>
+  <string name="rename_local_fail_msg">Локална копија се не може преименовати. Покушајте други назив</string>
   <string name="rename_server_fail_msg">Не могу да довршим преименовање</string>
-  <string name="sync_file_fail_msg">Удаљена датотека се не може проверити</string>
+  <string name="sync_file_fail_msg">Удаљени фајл се не може проверити</string>
+  <string name="sync_file_nothing_to_do_msg">Садржај је већ синхронизован</string>
+  <string name="create_dir_fail_msg">Фасцикла се не може направити</string>
+  <string name="filename_forbidden_characters">Забрањени знакови: / \\ &lt; &gt; : \" | ? *</string>
+  <string name="filename_empty">Назив фајла не може бити празан</string>
   <string name="wait_a_moment">Сачекајте тренутак</string>
-  <string name="filedisplay_no_file_selected">Нисте изабрали датотеку</string>
+  <string name="filedisplay_unexpected_bad_get_content">Неочекивани проблем. Изаберите фајл другом апликацијом</string>
+  <string name="filedisplay_no_file_selected">Нисте изабрали фајл</string>
+  <string name="activity_chooser_title">Пошаљи везу ...</string>
+  <string name="oauth_check_onoff">Пријави се помоћу „oAuth2“</string>
+  <string name="oauth_login_connection">Повезујем се на „oAuth2“ сервер...</string>
   <string name="ssl_validator_header">Не могу да проверим идентитет сајта</string>
-  <string name="ssl_validator_reason_cert_not_trusted">â\80\93 Ð¡ÐµÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\81еÑ\80веÑ\80а Ð½Ð¸Ñ\98е Ð¿Ð¾Ð²ÐµÑ\80Ñ\99ив</string>
+  <string name="ssl_validator_reason_cert_not_trusted">â\80\93 Ð¡ÐµÑ\80Ñ\82иÑ\84икаÑ\82 Ñ\81еÑ\80веÑ\80а Ð½Ð¸Ñ\98е Ð¾Ð´ Ð¿Ð¾Ð²ÐµÑ\80еÑ\9aа</string>
   <string name="ssl_validator_reason_cert_expired">– Сертификат сервера је истекао</string>
+  <string name="ssl_validator_reason_cert_not_yet_valid">- Датуми важења сертификата су у будућности</string>
   <string name="ssl_validator_reason_hostname_not_verified">– Адреса се не поклапа са именом домаћина у сертификату</string>
-  <string name="ssl_validator_question">Ð\96елиÑ\82е Ð»Ð¸ Ð¸Ð¿Ð°Ðº Ð´Ð° Ð¾Ð·Ð½Ð°Ñ\87иÑ\82е Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82 ÐºÐ°Ð¾ Ð¿Ð¾Ð²ÐµÑ\80Ñ\99ив?</string>
+  <string name="ssl_validator_question">Ð\96елиÑ\82е Ð»Ð¸ Ð¸Ð¿Ð°Ðº Ð´Ð° Ð²ÐµÑ\80Ñ\83Ñ\98еÑ\82е Ñ\81еÑ\80Ñ\82иÑ\84икаÑ\82Ñ\83?</string>
   <string name="ssl_validator_not_saved">Не могу да сачувам сертификат</string>
   <string name="ssl_validator_btn_details_see">Подаци</string>
   <string name="ssl_validator_btn_details_hide">Сакриј</string>
   <string name="ssl_validator_label_subject">Издато за:</string>
-  <string name="ssl_validator_label_issuer">Ð\98здао/ла:</string>
+  <string name="ssl_validator_label_issuer">Ð\98здаваÑ\87:</string>
   <string name="ssl_validator_label_CN">Уобичајено име:</string>
   <string name="ssl_validator_label_O">Организација:</string>
   <string name="ssl_validator_label_OU">Организациона јединица:</string>
-  <string name="ssl_validator_label_C">Ð\97емÑ\99а:</string>
-  <string name="ssl_validator_label_ST">Ð\94Ñ\80жава:</string>
+  <string name="ssl_validator_label_C">Ð\94Ñ\80жава:</string>
+  <string name="ssl_validator_label_ST">Ð\9fокÑ\80аÑ\98ина:</string>
   <string name="ssl_validator_label_L">Локација:</string>
   <string name="ssl_validator_label_validity">Ваљаност:</string>
   <string name="ssl_validator_label_validity_from">Од:</string>
   <string name="ssl_validator_label_validity_to">За:</string>
   <string name="ssl_validator_label_signature">Потпис:</string>
   <string name="ssl_validator_label_signature_algorithm">Алгоритам:</string>
+  <string name="ssl_validator_null_cert">Сертификат се не може приказати.</string>
+  <string name="ssl_validator_no_info_about_error">- Нема података о грешци</string>
+  <string name="placeholder_sentence">Ово је местодржач</string>
+  <string name="placeholder_filename">чувамместо.txt</string>
+  <string name="placeholder_filetype">ПНГ слика</string>
+  <string name="placeholder_filesize">389 KB</string>
+  <string name="placeholder_timestamp">2012/05/18 12:23 ПоП</string>
+  <string name="placeholder_media_time">12:23:45</string>
   <string name="instant_upload_on_wifi">Отпремај слике само путем бежичне мреже</string>
+  <string name="instant_video_upload_on_wifi">Отпремај видео само путем бежичне мреже</string>
+  <string name="instant_upload_path">/InstantUpload</string>
   <string name="conflict_title">Ажурирај сукоб</string>
+  <string name="conflict_message">Удаљени фајл %s није синхронизован са локалним. Ако наставите, заменићете фајл на серверу.</string>
+  <string name="conflict_keep_both">Задржи оба</string>
+  <string name="conflict_overwrite">Пребриши</string>
+  <string name="conflict_dont_upload">Не отпремај</string>
+  <string name="preview_image_description">Преглед слике</string>
+  <string name="preview_image_error_unknown_format">Слика се не може приказати</string>
+  <string name="error__upload__local_file_not_copied">%1$s се не може копирати у локалну фасциклу %2$s</string>
+  <string name="prefs_instant_upload_path_title">Путања отпремања</string>
+  <string name="share_link_no_support_share_api">Дељење није укључено на вашем серверу. Контактирајте
+               администратора.</string>
+  <string name="share_link_file_no_exist">Не могу да делим. Проверите да ли фајл постоји</string>
+  <string name="share_link_file_error">Дошло је до грешке приликом покушаја дељења овог фајла или фасцикле</string>
+  <string name="unshare_link_file_no_exist">Не могу да прекинем дељење. Проверите да ли фајл постоји</string>
+  <string name="unshare_link_file_error">Дошло је до грешке приликом покушаја укидања дељења овог фајла или фасцикле</string>
+  <string name="share_link_password_title">Унесите лозинку</string>
+  <string name="share_link_empty_password">Морате унети лозинку</string>
   <string name="activity_chooser_send_file_title">Пошаљи</string>
+  <string name="copy_link">Копирај везу</string>
+  <string name="clipboard_text_copied">Копирано у клипборд</string>
+  <string name="error_cant_bind_to_operations_service">Критична грешка: не могу да радим</string>
+  <string name="network_error_socket_exception">Дошло је до грешке при повезивању са сервером.</string>
+  <string name="network_error_socket_timeout_exception">Дошло је до грешке при чекању на сервер. Радња није могла бити урађена</string>
+  <string name="network_error_connect_timeout_exception">Дошло је до грешке при чекању на сервер. Радња није могла бити урађена</string>
+  <string name="network_host_not_available">Радња није могла бити довршена. Сервер је недоступан</string>
   <string name="empty"></string>
+  <string name="forbidden_permissions">Немате дозволу %s</string>
+  <string name="forbidden_permissions_rename">да преименујете овај фајл</string>
+  <string name="forbidden_permissions_delete">да обришете овај фајл</string>
+  <string name="share_link_forbidden_permissions">да делите овај фајл</string>
+  <string name="unshare_link_forbidden_permissions">да укинете дељење овог фајла</string>
+  <string name="forbidden_permissions_create">да направите фајл</string>
+  <string name="uploader_upload_forbidden_permissions">да отпремате у ову фасциклу</string>
+  <string name="downloader_download_file_not_found">Фајл није више доступан на серверу</string>
   <string name="prefs_category_accounts">Налози</string>
+  <string name="prefs_add_account">Додај налог</string>
+  <string name="auth_redirect_non_secure_connection_title">Безбедна веза је преусмерена на небезбедну руту</string>
+  <string name="actionbar_logger">Записници</string>
+  <string name="log_send_history_button">Историјат слања</string>
+  <string name="log_send_no_mail_app">Нема начина за слање записника. Инсталирајте апликацију е-поште!</string>
+  <string name="log_send_mail_subject">Записници %1$s Андроид апликације</string>
+  <string name="log_progress_dialog_text">Учитавам податке...</string>
+  <string name="saml_authentication_required_text">Неопходна аутентификација</string>
+  <string name="saml_authentication_wrong_pass">Погрешна лозинка</string>
+  <string name="actionbar_move">Премести</string>
+  <string name="file_list_empty_moving">Овде нема ничега. Можете додати фасциклу!</string>
   <string name="folder_picker_choose_button_text">Одабери</string>
+  <string name="move_file_not_found">Не могу да преместим. Проверите да ли фајл постоји</string>
+  <string name="move_file_invalid_into_descendent">Није могуће преместити фасциклу у њену потфасциклу</string>
+  <string name="move_file_invalid_overwrite">Фајл већ постоји у одредишној фасцикли</string>
+  <string name="move_file_error">Дошло је до грешке при премештању фајла или фасцикле</string>
+  <string name="forbidden_permissions_move">да преместите овај фајл</string>
+  <string name="prefs_category_instant_uploading">Тренутна отпремања</string>
   <string name="prefs_category_security">Безбедност</string>
+  <string name="prefs_instant_video_upload_path_title">Путања отпремања видеа</string>
+  <string name="download_folder_failed_content">Преузимање фасцикле %1$s не може бити довршено</string>
+  <string name="subject_token">%1$s подели „%2$s“ са вама</string>
+  <string name="auth_refresh_button">Освежавање везе</string>
+  <string name="auth_host_address">Адреса сервера</string>
 </resources>
index f44afac..9953b16 100644 (file)
   <string name="auth_no_net_conn_title">Ingen nätverksanslutning</string>
   <string name="auth_nossl_plain_ok_title">Säker anslutning inte tillgänglig.</string>
   <string name="auth_connection_established">Anslutning etablerad</string>
-  <string name="auth_testing_connection">Testar anslutning...</string>
   <string name="auth_not_configured_title">Felaktig konfiguration</string>
   <string name="auth_account_not_new">En användare med samma namn och server finns redan i denna aparat</string>
   <string name="auth_account_not_the_same">Den angivna användaren matchar inte användaren för detta konto</string>
   <string name="prefs_category_instant_uploading">Direktuppladning</string>
   <string name="prefs_category_security">Säkerhet</string>
   <string name="prefs_instant_video_upload_path_title">Uppladdnings-sökväg för video</string>
+  <string name="auth_host_address">Serveradress</string>
 </resources>
index 42fc1b6..b7690fa 100644 (file)
@@ -80,7 +80,6 @@
   <string name="auth_no_net_conn_title">வ​லைய​மைப்பு இணைப்பு இல்லை</string>
   <string name="auth_nossl_plain_ok_title">பாதுகாப்பான இணைப்பு காணப்படவில்லை.</string>
   <string name="auth_connection_established">இணைப்பு நிறுவப்பட்டது</string>
-  <string name="auth_testing_connection">இணைப்பு சோதிக்கப்படுகிறது.....</string>
   <string name="auth_not_configured_title">பிறழ்வான தகவமைப்பு</string>
   <string name="auth_unknown_error_title">அறியப்படாத வழு ஏற்பட்டுள்ளது!</string>
   <string name="auth_unknown_host_title">ஓம்புனரை கண்டுப்பிடிக்கமுடியவில்லை</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">கணக்குகள்</string>
   <string name="folder_picker_choose_button_text">தெரிவுசெய்க </string>
+  <string name="auth_host_address">சேவையக முகவரி</string>
 </resources>
index fdebfa7..5a89023 100644 (file)
@@ -18,4 +18,5 @@
   <string name="uploader_info_dirname">సంచయం పేరు</string>
   <string name="activity_chooser_send_file_title">పంపించు</string>
   <string name="empty"></string>
+  <string name="auth_host_address">సేవకి చిరునామా</string>
 </resources>
index 0f2a409..0c4d7dd 100644 (file)
@@ -95,7 +95,6 @@
   <string name="auth_no_net_conn_title">ไม่มีการเชื่อมต่อเครือข่ายใดๆ</string>
   <string name="auth_nossl_plain_ok_title">การเชื่อมต่อแบบรักษาความปลอดภัยไม่สามารถใช้งานได้</string>
   <string name="auth_connection_established">ติดตั้งการเชื่อมต่อแล้ว</string>
-  <string name="auth_testing_connection">กำลังทดสอบการเชื่อมต่อ...</string>
   <string name="auth_not_configured_title">การกำหนดค่า Malformed เซิร์ฟเวอร์</string>
   <string name="auth_unknown_error_title">เกิดข้อผิดพลาดที่ไม่ทราบสาเหตุ!</string>
   <string name="auth_unknown_host_title">ไม่พบโฮสต์ที่ต้องการ</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">บัญชี</string>
   <string name="folder_picker_choose_button_text">เลือก</string>
+  <string name="auth_host_address">ที่อยู่เซิร์ฟเวอร์</string>
 </resources>
index 3b1ac5e..9612c43 100644 (file)
@@ -64,9 +64,9 @@
   <string name="file_list_loading">Yükleniyor...</string>
   <string name="local_file_list_empty">Bu klasörde dosya yok.</string>
   <string name="file_list_folder">klasör</string>
-  <string name="file_list_folders">klasörler</string>
+  <string name="file_list_folders">klasör</string>
   <string name="file_list_file">dosya</string>
-  <string name="file_list_files">dosyalar</string>
+  <string name="file_list_files">dosya</string>
   <string name="filedetails_select_file">Ek bilgileri görmek için dosyaya dokunun.</string>
   <string name="filedetails_size">Boyut:</string>
   <string name="filedetails_type">Tür:</string>
   <string name="auth_no_net_conn_title">Ağ bağlantısı yok</string>
   <string name="auth_nossl_plain_ok_title">Güvenli bağlantı mevcut değil.</string>
   <string name="auth_connection_established">Bağlantı kuruldu</string>
-  <string name="auth_testing_connection">Bağlantı kontrol ediliyor...</string>
+  <string name="auth_testing_connection">Bağlantı sınanıyor</string>
   <string name="auth_not_configured_title">Hatalı sunucu yapılandırması</string>
   <string name="auth_account_not_new">Cihazda aynı kullanıcı adı ve sunucu için bir hesap zaten mevcut</string>
   <string name="auth_account_not_the_same">Girilen kullanıcı bu hesabın kullanıcısı ile eşleşmiyor</string>
   <string name="auth_fail_get_user_name">Sunucunuz geçerli bir kullanıcı kimliği döndürmüyor, lütfen yöneticinizle iletişime geçin
         </string>
   <string name="auth_can_not_auth_against_server">Bu sunucuya karşı kimlik doğrulama yapılamaz</string>
+  <string name="auth_account_does_not_exist">Hesap henüz cihazda mevcut değil</string>
   <string name="fd_keep_in_sync">Dosyayı güncel tut</string>
   <string name="common_rename">Yeniden adlandır</string>
   <string name="common_remove">Kaldır</string>
   <string name="share_link_file_error">Bu dosya veya klasörü paylaşmaya çalışılırken bir hata oluştu</string>
   <string name="unshare_link_file_no_exist">Paylaşımı kaldırma başarısız. Lütfen dosyanın mevcut olup olmadığını denetleyin</string>
   <string name="unshare_link_file_error">Bu dosya veya klasör paylaşımı kaldırılmaya çalışılırken bir hata oluştu</string>
+  <string name="share_link_password_title">Bir parola girin</string>
+  <string name="share_link_empty_password">Bir parola girmelisiniz</string>
   <string name="activity_chooser_send_file_title">Gönder</string>
   <string name="copy_link">Bağlantıyı kopyala</string>
   <string name="clipboard_text_copied">Panoya kopyalandı</string>
   <string name="prefs_category_security">Güvenlik</string>
   <string name="prefs_instant_video_upload_path_title">Video Yükleme Yolu</string>
   <string name="download_folder_failed_content">%1$s klasörün indirilmesi tamamlanamadı</string>
-  <string name="subject_token">%1$s sizinle \"%2$s\" paylaştı</string>
+  <string name="subject_token">%1$s sizinle \"%2$s\" paylaşımını yaptı</string>
+  <string name="auth_refresh_button">Bağlantıyı yenile</string>
+  <string name="auth_host_address">Sunucu adresi</string>
 </resources>
index 12a5492..d2f2063 100644 (file)
@@ -44,4 +44,5 @@
   <string name="empty"></string>
   <string name="prefs_category_accounts">ھېساباتلار</string>
   <string name="prefs_category_security">بىخەتەرلىك</string>
+  <string name="auth_host_address">مۇلازىمېتىر ئادرىسى</string>
 </resources>
index 1a48961..2089f82 100644 (file)
   <string name="uploader_upload_failed_ticker">Помилка завантаження</string>
   <string name="uploader_upload_failed_content_single">Завантаження %1$s не може завершитись</string>
   <string name="uploader_upload_failed_credentials_error">Завантажити не вдалося, необхідно повторити вхід</string>
-  <string name="downloader_download_in_progress_ticker">Ð\97качування …</string>
+  <string name="downloader_download_in_progress_ticker">Скачування …</string>
   <string name="downloader_download_in_progress_content">%1$d%% Зкачування %2$s</string>
   <string name="downloader_download_succeeded_ticker">Успішно зкачано</string>
   <string name="downloader_download_succeeded_content">%1$s успішно завантажено</string>
   <string name="auth_no_net_conn_title">Відсутнє підключення до мережі</string>
   <string name="auth_nossl_plain_ok_title">Безпечне з\'єднання не доступне.</string>
   <string name="auth_connection_established">З\'єднання встановлено</string>
-  <string name="auth_testing_connection">Перевірка з\'єднання</string>
+  <string name="auth_testing_connection">Перевірка з\'єднання</string>
   <string name="auth_not_configured_title">Не вірні налаштування сервер </string>
   <string name="auth_account_not_new">Такий обліковий запис вже існує на пристрої</string>
   <string name="auth_account_not_the_same">Введений користувач не відповідає обліковому запису</string>
   <string name="auth_fail_get_user_name">Ваш сервер не повертає коректний ідентифікатор користувача, будь ласка зверніться до адміністратора
 ⇥</string>
   <string name="auth_can_not_auth_against_server">Аутентифікація на цьому сервері неможлива</string>
+  <string name="auth_account_does_not_exist">Користвача в пристрої не існуе</string>
   <string name="fd_keep_in_sync">Оновлювати файл</string>
   <string name="common_rename">Перейменувати</string>
   <string name="common_remove">Видалити</string>
   <string name="share_link_file_error">Виникла помилка при спробі поділитися файлом або текою</string>
   <string name="unshare_link_file_no_exist">Неможливо заборонити доступ. Будь ласка, перевірте, чи існує файл</string>
   <string name="unshare_link_file_error">Виникла помилка при спробі заборонити доступ до файлу або теки</string>
+  <string name="share_link_password_title">Ввести пароль</string>
+  <string name="share_link_empty_password">Ви повинні ввести пароль</string>
   <string name="activity_chooser_send_file_title">Надіслати</string>
   <string name="copy_link">Копіювати посилання</string>
   <string name="clipboard_text_copied">Скопійовано в буфер обміну</string>
   <string name="prefs_category_instant_uploading">Миттєво завантаження</string>
   <string name="prefs_category_security">Безпека</string>
   <string name="prefs_instant_video_upload_path_title">Шлях завантаження відео</string>
+  <string name="download_folder_failed_content">Скачування теки %1$s не може бути завершено</string>
+  <string name="subject_token">%1$s розшарено \"%2$s\" з вами</string>
+  <string name="auth_refresh_button">Оновити з\'єднання</string>
+  <string name="auth_host_address">Ареса серверу</string>
 </resources>
index d2517eb..7325c70 100644 (file)
   <string name="auth_no_net_conn_title">Không có kết nối mạng</string>
   <string name="auth_nossl_plain_ok_title">Bảo mật kết nối không có giá trị.</string>
   <string name="auth_connection_established">Kết nối đã thiết lập</string>
-  <string name="auth_testing_connection">Đang kiểm tra kết nối...</string>
   <string name="auth_not_configured_title">Thay đổi cấu hình máy chủ </string>
   <string name="auth_account_not_new">Một tài khoản với cùng tên người dùng và máy chủ đã tồn tại trong thiết bị</string>
   <string name="auth_account_not_the_same">Tên người dùng đã nhập không đúng với tên người dùng của tài khoản này</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">Tài khoản</string>
   <string name="folder_picker_choose_button_text">Chọn</string>
+  <string name="auth_host_address">Địa chỉ máy chủ</string>
 </resources>
index 28123e0..4333bc4 100644 (file)
   <string name="auth_no_net_conn_title">没有网络连接</string>
   <string name="auth_nossl_plain_ok_title">安全连接不可用。</string>
   <string name="auth_connection_established">连接已建立。</string>
-  <string name="auth_testing_connection">测试连接……</string>
   <string name="auth_not_configured_title">服务器配置不正确</string>
   <string name="auth_account_not_new">此设备中已经存在同名同服务器的帐号</string>
   <string name="auth_account_not_the_same">输入用户与此帐户的用户不符</string>
   <string name="prefs_category_security">安全</string>
   <string name="prefs_instant_video_upload_path_title">视频上传路径</string>
   <string name="download_folder_failed_content">%1$s 文件夹的下载无法完成</string>
+  <string name="auth_host_address">服务器地址</string>
 </resources>
index 892944e..302f20f 100644 (file)
@@ -72,4 +72,5 @@
   <string name="prefs_category_accounts">帳號</string>
   <string name="saml_authentication_wrong_pass">密碼錯誤</string>
   <string name="prefs_category_security">安全</string>
+  <string name="auth_host_address">伺服器地址</string>
 </resources>
index 45ccd3f..1e54e60 100644 (file)
   <string name="auth_no_net_conn_title">沒有網際網路連線</string>
   <string name="auth_nossl_plain_ok_title">安全連線不可用。</string>
   <string name="auth_connection_established">連線已建立</string>
-  <string name="auth_testing_connection">測試連線中…</string>
   <string name="auth_not_configured_title">伺服器設定有問題</string>
   <string name="auth_account_not_new">已經有相同使用者與伺服器的帳號存在於這個裝置</string>
   <string name="auth_account_not_the_same">輸入的使用者與這個帳戶的使用者不一致</string>
   <string name="prefs_category_instant_uploading">即時上傳</string>
   <string name="prefs_category_security">安全性</string>
   <string name="prefs_instant_video_upload_path_title">影片上傳路徑</string>
+  <string name="download_folder_failed_content">%1$s 目錄的下載未完成</string>
+  <string name="auth_host_address">伺服器位址</string>
 </resources>
index 1c8d68c..c2ca673 100644 (file)
@@ -2,7 +2,7 @@
 <!--
   ownCloud Android client application
 
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 9577e5e..6aeb6ac 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 6c1a67a..0c341bd 100644 (file)
@@ -9,6 +9,7 @@
     <string name ="data_folder">owncloud</string>
     <string name ="log_name">Owncloud_</string>
     <string name ="default_display_name_for_root_folder">ownCloud</string>
+    <string name ="user_agent">Mozilla/5.0 (Android) ownCloud</string>
     
     <!-- URLs and flags related -->
     <string name="server_url"></string>
index 296a8e0..abf48d3 100644 (file)
@@ -53,6 +53,7 @@
     <string name="sync_string_files">Files</string>
     <string name="setup_btn_connect">Connect</string>
     <string name="uploader_btn_upload_text">Upload</string>
+    <string name="uploader_btn_new_folder_text">New folder</string>
     <string name="uploader_top_message">Choose upload folder:</string>
     <string name="uploader_wrn_no_account_title">No account found</string>
     <string name="uploader_wrn_no_account_text">There are no %1$s accounts on your device. Please setup an account first.</string>
        <string name="auth_no_net_conn_title">No network connection</string>
        <string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
        <string name="auth_connection_established">Connection established</string>
-       <string name="auth_testing_connection">Testing connection&#8230;</string>
+       <string name="auth_testing_connection">Testing connection</string>
        <string name="auth_not_configured_title">Malformed server configuration</string>
        <string name="auth_account_not_new">An account for the same user and server already exists in the device</string>
        <string name="auth_account_not_the_same">The entered user does not match the user of this account</string>
        <string name="auth_fail_get_user_name">Your server is not returning a correct user id, please contact an administrator
        </string>
        <string name="auth_can_not_auth_against_server">Cannot authenticate against this server</string>
+    <string name="auth_account_does_not_exist">Account does not exist in the device yet</string>
     
     <string name="fd_keep_in_sync">Keep file up to date</string>
     <string name="common_rename">Rename</string>
        <string name="share_link_file_error">An error occurred while trying to share this file or folder</string>
        <string name="unshare_link_file_no_exist">Unable to unshare. Please check whether the file exists</string>
        <string name="unshare_link_file_error">An error occurred while trying to unshare this file or folder</string>
+    <string name="share_link_password_title">Enter a password</string>
+    <string name="share_link_empty_password">You must enter a password</string>
 
        <string name="activity_chooser_send_file_title">Send</string>
 
 
        <string name="subject_token">%1$s shared \"%2$s\" with you</string>
 
+    <string name="auth_refresh_button">Refresh connection</string>
+    <string name="auth_host_address">Server address</string>
+
 </resources>
index c65cbad..5996281 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index eb25005..d0e8244 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index b674cbc..ac36984 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index 8c8d8b3..805b53e 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2012-2013 ownCloud Inc.
+  Copyright (C) 2015 ownCloud Inc.
 
   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2,
index c2a4c68..76ecc5e 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -18,6 +22,8 @@ package com.owncloud.android;
 
 import android.app.Application;
 import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
@@ -28,12 +34,11 @@ import com.owncloud.android.lib.common.utils.Log_OC;
  * 
  * Contains methods to build the "static" strings. These strings were before constants in different
  * classes
- * 
- * @author masensio
- * @author David A. Velasco
  */
 public class MainApp extends Application {
-    
+
+    private static final String TAG = MainApp.class.getSimpleName();
+
     private static final String AUTH_ON = "on";
     
     @SuppressWarnings("unused")
@@ -48,10 +53,10 @@ public class MainApp extends Application {
         MainApp.mContext = getApplicationContext();
         
         boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
-        
-        if (isSamlAuth) {   
+
+        OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
+        if (isSamlAuth) {
             OwnCloudClientManagerFactory.setDefaultPolicy(Policy.SINGLE_SESSION_PER_ACCOUNT);
-            
         } else {
             OwnCloudClientManagerFactory.setDefaultPolicy(Policy.ALWAYS_NEW_CLIENT);
         }
@@ -116,4 +121,25 @@ public class MainApp extends Application {
         return getAppContext().getResources().getString(R.string.log_name);
     }
 
+    // user agent
+    public static String getUserAgent() {
+        String appString = getAppContext().getResources().getString(R.string.user_agent);
+        String packageName = getAppContext().getPackageName();
+        String version = "";
+
+        PackageInfo pInfo = null;
+        try {
+            pInfo = getAppContext().getPackageManager().getPackageInfo(packageName, 0);
+            if (pInfo != null) {
+                version = "/" + pInfo.versionName;
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            Log_OC.e(TAG, "Trying to get packageName", e.getCause());
+        }
+
+       // Mozilla/5.0 (Android) ownCloud /1.7.0
+        String userAgent = appString + version;
+
+        return userAgent;
+    }
 }
index 1d52fd0..a40b7dd 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2012  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -38,9 +41,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
  *  Controller class accessed from the system AccountManager, providing integration of ownCloud accounts with the Android system.
  * 
  *  TODO - better separation in operations for OAuth-capable and regular ownCloud accounts.
- *  TODO - review completeness 
- * 
- * @author David A. Velasco
+ *  TODO - review completeness
  */
 public class AccountAuthenticator extends AbstractAccountAuthenticator {
     
@@ -122,39 +123,39 @@ public class AccountAuthenticator extends AbstractAccountAuthenticator {
         return bundle;
     }
 
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public Bundle confirmCredentials(AccountAuthenticatorResponse response,\r
-            Account account, Bundle options) throws NetworkErrorException {\r
-        try {\r
-            validateAccountType(account.type);\r
-        } catch (AuthenticatorException e) {\r
-            Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "\r
-                    + e.getMessage());\r
-            e.printStackTrace();\r
-            return e.getFailureBundle();\r
-        }\r
-        Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
-                response);\r
-        intent.putExtra(KEY_ACCOUNT, account);\r
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
-\r
-        setIntentFlags(intent);\r
-\r
-        Bundle resultBundle = new Bundle();\r
-        resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
-        return resultBundle;\r
-    }\r
-\r
-    @Override\r
-    public Bundle editProperties(AccountAuthenticatorResponse response,\r
-            String accountType) {\r
-        return null;\r
-    }\r
-\r
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Bundle confirmCredentials(AccountAuthenticatorResponse response,
+            Account account, Bundle options) throws NetworkErrorException {
+        try {
+            validateAccountType(account.type);
+        } catch (AuthenticatorException e) {
+            Log_OC.e(TAG, "Failed to validate account type " + account.type + ": "
+                    + e.getMessage());
+            e.printStackTrace();
+            return e.getFailureBundle();
+        }
+        Intent intent = new Intent(mContext, AuthenticatorActivity.class);
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
+                response);
+        intent.putExtra(KEY_ACCOUNT, account);
+        intent.putExtra(KEY_LOGIN_OPTIONS, options);
+
+        setIntentFlags(intent);
+
+        Bundle resultBundle = new Bundle();
+        resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
+        return resultBundle;
+    }
+
+    @Override
+    public Bundle editProperties(AccountAuthenticatorResponse response,
+            String accountType) {
+        return null;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -253,69 +254,69 @@ public class AccountAuthenticator extends AbstractAccountAuthenticator {
         }
     }
 
-    private void validateAuthTokenType(String authTokenType)\r
-            throws UnsupportedAuthTokenTypeException {\r
-        if (!authTokenType.equals(MainApp.getAuthTokenType()) &&\r
-            !authTokenType.equals(AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType())) &&\r
-            !authTokenType.equals(AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType())) &&\r
+    private void validateAuthTokenType(String authTokenType)
+            throws UnsupportedAuthTokenTypeException {
+        if (!authTokenType.equals(MainApp.getAuthTokenType()) &&
+            !authTokenType.equals(AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType())) &&
+            !authTokenType.equals(AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType())) &&
             !authTokenType.equals(AccountTypeUtils.getAuthTokenTypeRefreshToken(MainApp.getAccountType())) &&
-            !authTokenType.equals(AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()))) {\r
-            throw new UnsupportedAuthTokenTypeException();\r
-        }\r
-    }\r
-\r
-    public static class AuthenticatorException extends Exception {\r
-        private static final long serialVersionUID = 1L;\r
-        private Bundle mFailureBundle;\r
-\r
-        public AuthenticatorException(int code, String errorMsg) {\r
-            mFailureBundle = new Bundle();\r
-            mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);\r
-            mFailureBundle\r
-                    .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);\r
-        }\r
-\r
-        public Bundle getFailureBundle() {\r
-            return mFailureBundle;\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedAccountTypeException extends\r
-            AuthenticatorException {\r
-        private static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedAccountTypeException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
-                    "Unsupported account type");\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedAuthTokenTypeException extends\r
-            AuthenticatorException {\r
-        private static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedAuthTokenTypeException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
-                    "Unsupported auth token type");\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedFeaturesException extends\r
-            AuthenticatorException {\r
-        public static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedFeaturesException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
-                    "Unsupported features");\r
-        }\r
-    }\r
-\r
-    public static class AccessDeniedException extends AuthenticatorException {\r
-        public AccessDeniedException(int code, String errorMsg) {\r
-            super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");\r
-        }\r
-\r
-        private static final long serialVersionUID = 1L;\r
-\r
-    }\r
-}\r
+            !authTokenType.equals(AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()))) {
+            throw new UnsupportedAuthTokenTypeException();
+        }
+    }
+
+    public static class AuthenticatorException extends Exception {
+        private static final long serialVersionUID = 1L;
+        private Bundle mFailureBundle;
+
+        public AuthenticatorException(int code, String errorMsg) {
+            mFailureBundle = new Bundle();
+            mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
+            mFailureBundle
+                    .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
+        }
+
+        public Bundle getFailureBundle() {
+            return mFailureBundle;
+        }
+    }
+
+    public static class UnsupportedAccountTypeException extends
+            AuthenticatorException {
+        private static final long serialVersionUID = 1L;
+
+        public UnsupportedAccountTypeException() {
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+                    "Unsupported account type");
+        }
+    }
+
+    public static class UnsupportedAuthTokenTypeException extends
+            AuthenticatorException {
+        private static final long serialVersionUID = 1L;
+
+        public UnsupportedAuthTokenTypeException() {
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+                    "Unsupported auth token type");
+        }
+    }
+
+    public static class UnsupportedFeaturesException extends
+            AuthenticatorException {
+        public static final long serialVersionUID = 1L;
+
+        public UnsupportedFeaturesException() {
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
+                    "Unsupported features");
+        }
+    }
+
+    public static class AccessDeniedException extends AuthenticatorException {
+        public AccessDeniedException(int code, String errorMsg) {
+            super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
+        }
+
+        private static final long serialVersionUID = 1L;
+
+    }
+}
index c479cea..915b015 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index dc02344..bd3a8e7 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
  *   Copyright (C) 2012  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
index 8d7182d..1e4e8b4 100644 (file)
@@ -1,6 +1,11 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
+ *   @author David A. Velasco\r
+ *   @author masensio\r
  *   Copyright (C) 2012  Bartek Przybylski\r
- *   Copyright (C) 2012-2014 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -64,7 +69,10 @@ import com.actionbarsherlock.app.SherlockDialogFragment;
 import com.owncloud.android.MainApp;\r
 import com.owncloud.android.R;\r
 import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;\r
+import com.owncloud.android.lib.common.OwnCloudCredentials;\r
+import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;\r
 import com.owncloud.android.lib.common.accounts.AccountTypeUtils;\r
+import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;\r
 import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;\r
 import com.owncloud.android.lib.common.network.CertificateCombinedException;\r
 import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;\r
@@ -72,7 +80,6 @@ import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;\r
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;\r
 import com.owncloud.android.lib.common.utils.Log_OC;\r
-import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;\r
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;\r
 import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation;\r
 import com.owncloud.android.operations.DetectAuthenticationMethodOperation.AuthenticationMethod;\r
@@ -89,14 +96,11 @@ import com.owncloud.android.utils.DisplayUtils;
 \r
 /**\r
  * This Activity is used to add an ownCloud account to the App\r
- * \r
- * @author Bartek Przybylski\r
- * @author David A. Velasco\r
- * @author masensio\r
  */\r
 public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
-implements  OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener, \r
-SsoWebViewClientListener, OnSslUntrustedCertListener {\r
+        implements  OnRemoteOperationListener, OnFocusChangeListener, OnEditorActionListener,\r
+        SsoWebViewClientListener, OnSslUntrustedCertListener,\r
+        AuthenticatorAsyncTask.OnAuthenticatorTaskListener {\r
 \r
     private static final String TAG = AuthenticatorActivity.class.getSimpleName();\r
 \r
@@ -132,6 +136,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     private static final String CREDENTIALS_DIALOG_TAG = "CREDENTIALS_DIALOG";\r
     private static final String KEY_AUTH_IS_FIRST_ATTEMPT_TAG = "KEY_AUTH_IS_FIRST_ATTEMPT";\r
 \r
+    private static final String KEY_USERNAME = "USERNAME";\r
+    private static final String KEY_PASSWORD = "PASSWORD";\r
+    private static final String KEY_ASYNC_TASK_IN_PROGRESS = "AUTH_IN_PROGRESS";\r
     \r
     /// parameters from EXTRAs in starter Intent\r
     private byte mAction;\r
@@ -175,14 +182,19 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     private int mAuthStatusText = 0, mAuthStatusIcon = 0;\r
     \r
     private String mAuthToken = "";\r
+    private AuthenticatorAsyncTask mAsyncTask;\r
 \r
     private boolean mIsFirstAuthAttempt;\r
-\r
     \r
     /// Identifier of operation in progress which result shouldn't be lost \r
     private long mWaitingForOpId = Long.MAX_VALUE;\r
 \r
-    \r
+    private final String BASIC_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());\r
+    private final String OAUTH_TOKEN_TYPE = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());\r
+    private final String SAML_TOKEN_TYPE =\r
+            AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());\r
+\r
+\r
     /**\r
      * {@inheritDoc}\r
      * \r
@@ -227,7 +239,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         setContentView(R.layout.account_setup);\r
         \r
         /// initialize general UI elements\r
-        initOverallUi(savedInstanceState);\r
+        initOverallUi();\r
         \r
         mOkButton = findViewById(R.id.buttonOK);\r
 \r
@@ -265,21 +277,19 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \r
     private String chooseAuthTokenType(boolean oauth, boolean saml) {\r
         if (saml) {\r
-            return AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());\r
+            return SAML_TOKEN_TYPE;\r
         } else if (oauth) {\r
-             return AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());\r
+             return OAUTH_TOKEN_TYPE;\r
         } else {\r
-            return AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());\r
+            return BASIC_TOKEN_TYPE;\r
         }\r
     }\r
 \r
     \r
     /**\r
      * Configures elements in the user interface under direct control of the Activity.\r
-     * \r
-     * @param savedInstanceState        Saved activity state, as in {{@link #onCreate(Bundle)}\r
      */\r
-    private void initOverallUi(Bundle savedInstanceState) {\r
+    private void initOverallUi() {\r
         \r
         /// step 1 - load and process relevant inputs (resources, intent, savedInstanceState)\r
         boolean isWelcomeLinkVisible = getResources().getBoolean(R.bool.show_welcome_link);\r
@@ -415,9 +425,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
                     if (\r
                             AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(\r
                                     MainApp.getAccountType()\r
-                                    ).equals(mAuthTokenType) &&\r
-                            mHostUrlInput.hasFocus()\r
-                    ) {\r
+                            ).equals(mAuthTokenType) &&\r
+                                    mHostUrlInput.hasFocus()\r
+                            ) {\r
                         checkOcServer();\r
                     }\r
                 }\r
@@ -549,7 +559,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      * intended to defer the processing of the redirection caught in \r
      * {@link #onNewIntent(Intent)} until {@link #onResume()} \r
      * \r
-     * See {@link #loadSavedInstanceState(Bundle)}\r
+     * See {@link #onSaveInstanceState(Bundle)}\r
      */\r
     @Override\r
     protected void onSaveInstanceState(Bundle outState) {\r
@@ -581,9 +591,42 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         /// authentication\r
         outState.putBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG, mIsFirstAuthAttempt);\r
 \r
+        /// AsyncTask (User and password)\r
+        outState.putString(KEY_USERNAME, mUsernameInput.getText().toString());\r
+        outState.putString(KEY_PASSWORD, mPasswordInput.getText().toString());\r
+\r
+        if (mAsyncTask != null) {\r
+            mAsyncTask.cancel(true);\r
+            outState.putBoolean(KEY_ASYNC_TASK_IN_PROGRESS, true);\r
+        } else {\r
+            outState.putBoolean(KEY_ASYNC_TASK_IN_PROGRESS, false);\r
+        }\r
+        mAsyncTask = null;\r
+\r
         //Log_OC.wtf(TAG, "onSaveInstanceState end" );\r
     }\r
 \r
+    @Override\r
+    public void onRestoreInstanceState(Bundle savedInstanceState) {\r
+        super.onRestoreInstanceState(savedInstanceState);\r
+\r
+        // AsyncTask\r
+        boolean inProgress = savedInstanceState.getBoolean(KEY_ASYNC_TASK_IN_PROGRESS);\r
+        if (inProgress){\r
+            String username = savedInstanceState.getString(KEY_USERNAME);\r
+            String password = savedInstanceState.getString(KEY_PASSWORD);\r
+\r
+            OwnCloudCredentials credentials = null;\r
+            if (BASIC_TOKEN_TYPE.equals(mAuthTokenType)) {\r
+                credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);\r
+\r
+            } else if (OAUTH_TOKEN_TYPE.equals(mAuthTokenType)) {\r
+                credentials = OwnCloudCredentialsFactory.newBearerCredentials(mAuthToken);\r
+\r
+            }\r
+            accessRootFolder(credentials);\r
+        }\r
+    }\r
 \r
     /**\r
      * The redirection triggered by the OAuth authentication server as response to the \r
@@ -608,7 +651,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      */\r
     @Override\r
     protected void onResume() {\r
-        //Log_OC.wtf(TAG, "onResume init" );\r
         super.onResume();\r
         \r
         // bound here to avoid spurious changes triggered by Android on device rotations\r
@@ -623,15 +665,12 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             doOnResumeAndBound();\r
         }\r
         \r
-        //Log_OC.wtf(TAG, "onResume end" );\r
     }\r
 \r
     \r
     @Override\r
     protected void onPause() {\r
-        //Log_OC.wtf(TAG, "onPause init" );\r
         if (mOperationsServiceBinder != null) {\r
-            //Log_OC.wtf(TAG, "unregistering to listen for operation callbacks" );\r
             mOperationsServiceBinder.removeOperationListener(this);\r
         }\r
         \r
@@ -639,7 +678,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         mHostUrlInput.setOnFocusChangeListener(null);\r
         \r
         super.onPause();\r
-        //Log_OC.wtf(TAG, "onPause end" );\r
     }\r
     \r
     @Override\r
@@ -695,14 +733,14 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     public void onFocusChange(View view, boolean hasFocus) {\r
         if (view.getId() == R.id.hostUrlInput) {   \r
             if (!hasFocus) {\r
-                onUrlInputFocusLost((TextView) view);\r
+                onUrlInputFocusLost();\r
             }\r
             else {\r
                 showRefreshButton(false);\r
             }\r
 \r
         } else if (view.getId() == R.id.account_password) {\r
-            onPasswordFocusChanged((TextView) view, hasFocus);\r
+            onPasswordFocusChanged(hasFocus);\r
         }\r
     }\r
 \r
@@ -715,10 +753,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      * started. \r
      * \r
      * When hasFocus:    user 'comes back' to write again the server URL.\r
-     * \r
-     * @param hostInput     TextView with the URL input field receiving the change of focus.\r
      */\r
-    private void onUrlInputFocusLost(TextView hostInput) {\r
+    private void onUrlInputFocusLost() {\r
         if (!mServerInfo.mBaseUrl.equals(\r
                 normalizeUrl(mHostUrlInput.getText().toString(), mServerInfo.mIsSslConn))) {\r
             // check server again only if the user changed something in the field\r
@@ -772,10 +808,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      * \r
      * When (!hasFocus), the button is made invisible and the password is hidden.\r
      * \r
-     * @param passwordInput    TextView with the password input field receiving the change of focus.\r
      * @param hasFocus          'True' if focus is received, 'false' if is lost\r
      */\r
-    private void onPasswordFocusChanged(TextView passwordInput, boolean hasFocus) {\r
+    private void onPasswordFocusChanged(boolean hasFocus) {\r
         if (hasFocus) {\r
             showViewPasswordButton();\r
         } else {\r
@@ -840,7 +875,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             mServerStatusText = R.string.auth_wtf_reenter_URL;\r
             showServerStatus();\r
             mOkButton.setEnabled(false);\r
-            //Log_OC.wtf(TAG,  "The user was allowed to click 'connect' to an unchecked server!!");\r
             return;\r
         }\r
 \r
@@ -873,25 +907,17 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);\r
 \r
         /// validate credentials accessing the root folder\r
-        accessRootFolderRemoteOperation(username, password);\r
-        \r
+        OwnCloudCredentials credentials = OwnCloudCredentialsFactory.newBasicCredentials(username, password);\r
+        accessRootFolder(credentials);\r
     }\r
 \r
-    private void accessRootFolderRemoteOperation(String username, String password) {\r
-        Intent existenceCheckIntent = new Intent();\r
-        existenceCheckIntent.setAction(OperationsService.ACTION_EXISTENCE_CHECK);\r
-        existenceCheckIntent.putExtra(OperationsService.EXTRA_SERVER_URL, mServerInfo.mBaseUrl);\r
-        existenceCheckIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, "/");\r
-        existenceCheckIntent.putExtra(OperationsService.EXTRA_USERNAME, username);\r
-        existenceCheckIntent.putExtra(OperationsService.EXTRA_PASSWORD, password);\r
-        existenceCheckIntent.putExtra(OperationsService.EXTRA_AUTH_TOKEN, mAuthToken);\r
-        \r
-        if (mOperationsServiceBinder != null) {\r
-            //Log_OC.wtf(TAG, "starting existenceCheckRemoteOperation..." );\r
-            mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(existenceCheckIntent);\r
-        }\r
+    private void accessRootFolder(OwnCloudCredentials credentials) {\r
+        mAsyncTask = new AuthenticatorAsyncTask(this);\r
+        Object[] params = { mServerInfo.mBaseUrl, credentials };\r
+        mAsyncTask.execute(params);\r
     }\r
 \r
+\r
     /**\r
      * Starts the OAuth 'grant type' flow to get an access token, with \r
      * a GET AUTHORIZATION request to the BUILT-IN authorization server. \r
@@ -929,17 +955,16 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      * in the server.\r
      */\r
     private void startSamlBasedFederatedSingleSignOnAuthorization() {\r
-        // be gentle with the user\r
+        /// be gentle with the user\r
         mAuthStatusIcon = R.drawable.progress_small;\r
         mAuthStatusText = R.string.auth_connecting_auth_server;\r
         showAuthStatus();\r
-        IndeterminateProgressDialog dialog = \r
-                IndeterminateProgressDialog.newInstance(R.string.auth_trying_to_login, true);\r
-        dialog.show(getSupportFragmentManager(), WAIT_DIALOG_TAG);\r
-\r
-        /// validate credentials accessing the root folder\r
-        accessRootFolderRemoteOperation("", "");\r
 \r
+        /// Show SAML-based SSO web dialog\r
+        String targetUrl = mServerInfo.mBaseUrl\r
+                + AccountUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType);\r
+        SamlWebViewDialog dialog = SamlWebViewDialog.newInstance(targetUrl, targetUrl);\r
+        dialog.show(getSupportFragmentManager(), SAML_DIALOG_TAG);\r
     }\r
 \r
     /**\r
@@ -959,15 +984,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         } else if (operation instanceof OAuth2GetAccessToken) {\r
             onGetOAuthAccessTokenFinish(result);\r
 \r
-        } else if (operation instanceof ExistenceCheckRemoteOperation)  {\r
-            //Log_OC.wtf(TAG, "received detection response through callback" );\r
-            if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).\r
-                    equals(mAuthTokenType)) {\r
-                onSamlBasedFederatedSingleSignOnAuthorizationStart(result);\r
-\r
-            } else {\r
-                onAuthorizationCheckFinish(result);\r
-            }\r
         } else if (operation instanceof GetRemoteUserNameOperation) {\r
             onGetUserNameFinish(result);\r
         }\r
@@ -988,20 +1004,20 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
                 if (!mUsernameInput.getText().toString().equals(username)) {\r
                     // fail - not a new account, but an existing one; disallow\r
                     result = new RemoteOperationResult(ResultCode.ACCOUNT_NOT_THE_SAME);\r
-                    /*\r
-                    OwnCloudClientManagerFactory.getDefaultSingleton().removeClientFor(\r
-                            new OwnCloudAccount(\r
-                                    Uri.parse(mServerInfo.mBaseUrl),\r
-                                    OwnCloudCredentialsFactory.newSamlSsoCredentials(mAuthToken))\r
-                            );\r
-                            */\r
                     mAuthToken = "";\r
                     updateAuthStatusIconAndText(result);\r
                     showAuthStatus();\r
                     Log_OC.d(TAG, result.getLogMessage());\r
                 } else {\r
-                    updateToken();\r
-                    success = true;\r
+                    try {\r
+                        updateAccountAuthentication();\r
+                        success = true;\r
+\r
+                    } catch (AccountNotFoundException e) {\r
+                        Log_OC.e(TAG, "Account " + mAccount + " was removed!", e);\r
+                        Toast.makeText(this, R.string.auth_account_does_not_exist, Toast.LENGTH_SHORT).show();\r
+                        finish();\r
+                    }\r
                 }\r
             }\r
 \r
@@ -1015,35 +1031,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \r
     }\r
 \r
-    private void onSamlBasedFederatedSingleSignOnAuthorizationStart(RemoteOperationResult result) {\r
-        mWaitingForOpId = Long.MAX_VALUE;\r
-        dismissDialog(WAIT_DIALOG_TAG);\r
-
-        if (result.isIdPRedirection()) {
-            String targetUrl = mServerInfo.mBaseUrl \r
-                    + AccountUtils.getWebdavPath(mServerInfo.mVersion, mAuthTokenType);\r
-\r
-            // Show dialog\r
-            SamlWebViewDialog dialog = SamlWebViewDialog.newInstance(targetUrl, targetUrl);            \r
-            dialog.show(getSupportFragmentManager(), SAML_DIALOG_TAG);\r
-\r
-            mAuthStatusIcon = 0;\r
-            mAuthStatusText = 0;\r
-\r
-        } else {\r
-            mAuthStatusIcon = R.drawable.common_error;\r
-            mAuthStatusText = R.string.auth_unsupported_auth_method;\r
-\r
-        }\r
-        showAuthStatus();\r
-    }\r
-\r
-\r
     /**\r
      * Processes the result of the server check performed when the user finishes the enter of the\r
      * server URL.\r
-     * \r
-     * @param operation     Server check performed.\r
+     *\r
      * @param result        Result of the check.\r
      */\r
     private void onGetServerInfoFinish(RemoteOperationResult result) {\r
@@ -1088,16 +1079,12 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \r
 \r
     private boolean authSupported(AuthenticationMethod authMethod) {\r
-        String basic = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());\r
-        String oAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());\r
-        String saml =  AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType());\r
-        \r
-        return (( mAuthTokenType.equals(basic) && \r
-                    authMethod.equals(AuthenticationMethod.BASIC_HTTP_AUTH) ) ||\r
-                ( mAuthTokenType.equals(oAuth) && \r
-                    authMethod.equals(AuthenticationMethod.BEARER_TOKEN)) ||\r
-                ( mAuthTokenType.equals(saml)  && \r
-                    authMethod.equals(AuthenticationMethod.SAML_WEB_SSO))\r
+        return (( BASIC_TOKEN_TYPE.equals(mAuthTokenType) &&\r
+                    AuthenticationMethod.BASIC_HTTP_AUTH.equals(authMethod) ) ||\r
+                ( OAUTH_TOKEN_TYPE.equals(mAuthTokenType) &&\r
+                    AuthenticationMethod.BEARER_TOKEN.equals(authMethod)) ||\r
+                ( SAML_TOKEN_TYPE.equals(mAuthTokenType)  &&\r
+                    AuthenticationMethod.SAML_WEB_SSO.equals(authMethod))\r
         );\r
     }\r
 \r
@@ -1338,8 +1325,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             Map<String, String> tokens = (Map<String, String>)(result.getData().get(0));\r
             mAuthToken = tokens.get(OAuth2Constants.KEY_ACCESS_TOKEN);\r
             Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken);\r
-            \r
-            accessRootFolderRemoteOperation("", "");\r
+\r
+            /// validate token accessing to root folder / getting session\r
+            OwnCloudCredentials credentials = OwnCloudCredentialsFactory.newBearerCredentials(mAuthToken);\r
+            accessRootFolder(credentials);\r
 \r
         } else {\r
             updateAuthStatusIconAndText(result);\r
@@ -1353,11 +1342,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
      * Processes the result of the access check performed to try the user credentials.\r
      * \r
      * Creates a new account through the AccountManager.\r
-     * \r
-     * @param operation     Access check performed.\r
+     *\r
      * @param result        Result of the operation.\r
      */\r
-    private void onAuthorizationCheckFinish(RemoteOperationResult result) {\r
+    @Override\r
+    public void onAuthenticatorTaskCallback(RemoteOperationResult result) {\r
         mWaitingForOpId = Long.MAX_VALUE;\r
         dismissDialog(WAIT_DIALOG_TAG);\r
 \r
@@ -1369,15 +1358,22 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
                 success = createAccount();\r
 \r
             } else {\r
-                updateToken();\r
-                success = true;\r
+                try {\r
+                    updateAccountAuthentication();\r
+                    success = true;\r
+\r
+                } catch (AccountNotFoundException e) {\r
+                    Log_OC.e(TAG, "Account " + mAccount + " was removed!", e);\r
+                    Toast.makeText(this, R.string.auth_account_does_not_exist, Toast.LENGTH_SHORT).show();\r
+                    finish();\r
+                }\r
             }\r
 \r
             if (success) {\r
                 finish();\r
             }\r
             \r
-        } else if (result.isServerFail() || result.isException()) {
+        } else if (result.isServerFail() || result.isException()) {\r
             /// server errors or exceptions in authorization take to requiring a new check of \r
             /// the server\r
             mServerIsChecked = true;\r
@@ -1411,10 +1407,16 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
 \r
 \r
     /**\r
-     * Sets the proper response to get that the Account Authenticator that started this activity \r
+     * Updates the authentication token.\r
+     *\r
+     * Sets the proper response so that the AccountAuthenticator that started this activity\r
      * saves a new authorization token for mAccount.\r
+     *\r
+     * Kills the session kept by OwnCloudClientManager so that a new one will created with\r
+     * the new credentials when needed.\r
      */\r
-    private void updateToken() {\r
+    private void updateAccountAuthentication() throws AccountNotFoundException {\r
+        \r
         Bundle response = new Bundle();\r
         response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);\r
         response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);\r
@@ -1500,21 +1502,19 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             final Intent intent = new Intent();       \r
             intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,    MainApp.getAccountType());\r
             intent.putExtra(AccountManager.KEY_ACCOUNT_NAME,    mAccount.name);\r
-            /*if (!isOAuth)\r
-                intent.putExtra(AccountManager.KEY_AUTHTOKEN,   MainApp.getAccountType()); */\r
             intent.putExtra(AccountManager.KEY_USERDATA,        username);\r
             if (isOAuth || isSaml) {\r
                 mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);\r
             }\r
             /// add user data to the new account; TODO probably can be done in the last parameter \r
-            //      addAccountExplicitly, or in KEY_USERDATA
+            //      addAccountExplicitly, or in KEY_USERDATA\r
             mAccountMgr.setUserData(\r
                     mAccount, Constants.KEY_OC_VERSION,    mServerInfo.mVersion.getVersion()\r
             );\r
             mAccountMgr.setUserData(\r
                     mAccount, Constants.KEY_OC_BASE_URL,   mServerInfo.mBaseUrl\r
             );\r
-
+\r
             if (isSaml) {\r
                 mAccountMgr.setUserData(mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE"); \r
             } else if (isOAuth) {\r
@@ -1546,9 +1546,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     /**\r
      * Updates the content and visibility state of the icon and text associated\r
      * to the last check on the ownCloud server.\r
-     * \r
-     * @param serverStatusText      Resource identifier of the text to show.\r
-     * @param serverStatusIcon      Resource identifier of the icon to show.\r
+     *\r
      */\r
     private void showServerStatus() {\r
         if (mServerStatusIcon == 0 && mServerStatusText == 0) {\r
@@ -1626,9 +1624,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     public void onCheckClick(View view) {\r
         CheckBox oAuth2Check = (CheckBox)view;\r
         if (oAuth2Check.isChecked()) {\r
-            mAuthTokenType = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType());\r
+            mAuthTokenType = OAUTH_TOKEN_TYPE;\r
         } else {\r
-            mAuthTokenType = AccountTypeUtils.getAuthTokenTypePass(MainApp.getAccountType());\r
+            mAuthTokenType = BASIC_TOKEN_TYPE;\r
         }\r
         updateAuthenticationPreFragmentVisibility();\r
     }\r
@@ -1702,7 +1700,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
         getUserNameIntent.putExtra(OperationsService.EXTRA_COOKIE, sessionCookie);\r
         \r
         if (mOperationsServiceBinder != null) {\r
-            //Log_OC.wtf(TAG, "starting getRemoteUserNameOperation..." );\r
             mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getUserNameIntent);\r
         }\r
     }\r
@@ -1835,7 +1832,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
             if (component.equals(\r
                     new ComponentName(AuthenticatorActivity.this, OperationsService.class)\r
                 )) {\r
-                //Log_OC.wtf(TAG, "Operations service connected");\r
                 mOperationsServiceBinder = (OperationsServiceBinder) service;\r
                 \r
                 doOnResumeAndBound();\r
@@ -1891,4 +1887,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
     public void doNegativeAuthenticatioDialogClick(){\r
         mIsFirstAuthAttempt = true;\r
     }\r
+\r
+\r
 }\r
diff --git a/src/com/owncloud/android/authentication/AuthenticatorAsyncTask.java b/src/com/owncloud/android/authentication/AuthenticatorAsyncTask.java
new file mode 100644 (file)
index 0000000..4b2aed5
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio on 09/02/2015.
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package com.owncloud.android.authentication;
+
+import android.app.Activity;
+import android.content.Context;
+import android.net.Uri;
+import android.os.AsyncTask;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
+
+import java.lang.ref.WeakReference;
+
+
+/**
+ * Async Task to verify the credentials of a user
+ */
+public class AuthenticatorAsyncTask  extends AsyncTask<Object, Void, RemoteOperationResult> {
+
+    private static String REMOTE_PATH = "/";
+    private static boolean SUCCESS_IF_ABSENT = false;
+
+    private Context mContext;
+    private final WeakReference<OnAuthenticatorTaskListener> mListener;
+    protected Activity mActivity;
+
+    public AuthenticatorAsyncTask(Activity activity) {
+        mContext = activity.getApplicationContext();
+        mListener = new WeakReference<OnAuthenticatorTaskListener>((OnAuthenticatorTaskListener)activity);
+    }
+
+    @Override
+    protected RemoteOperationResult doInBackground(Object... params) {
+
+        RemoteOperationResult result;
+        if (params!= null && params.length==2) {
+            String url = (String)params[0];
+            OwnCloudCredentials credentials = (OwnCloudCredentials)params[1];
+
+            // Client
+            Uri uri = Uri.parse(url);
+            OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(uri, mContext, true);
+
+            client.setCredentials(credentials);
+
+            // Operation
+            ExistenceCheckRemoteOperation operation = new ExistenceCheckRemoteOperation(
+                    REMOTE_PATH,
+                    mContext,
+                    SUCCESS_IF_ABSENT
+            );
+            result = operation.execute(client);
+
+        } else {
+            result = new RemoteOperationResult(RemoteOperationResult.ResultCode.UNKNOWN_ERROR);
+        }
+
+        return result;
+    }
+
+    @Override
+    protected void onPostExecute(RemoteOperationResult result) {
+
+        if (result!= null)
+        {
+            OnAuthenticatorTaskListener listener = mListener.get();
+            if (listener!= null)
+            {
+                listener.onAuthenticatorTaskCallback(result);
+            }
+        }
+    }
+    /*
+     * Interface to retrieve data from recognition task
+     */
+    public interface OnAuthenticatorTaskListener{
+
+        void onAuthenticatorTaskCallback(RemoteOperationResult result);
+    }
+}
index f96b627..f6bd664 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -21,8 +24,6 @@ package com.owncloud.android.authentication;
  * Constant values for OAuth 2 protocol.
  * 
  * Includes required and optional parameter NAMES used in the 'authorization code' grant type.
- *  
- * @author David A. Velasco
  */
 
 public class OAuth2Constants {
index 2aaecb4..46a980b 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2015 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -50,8 +53,6 @@ import android.webkit.WebViewClient;
  * 
  * Assumes that the single-sign-on is kept thanks to a cookie set at the end of the
  * authentication process.
- *   
- * @author David A. Velasco
  */
 public class SsoWebViewClient extends WebViewClient {
         
index 816c676..a197e08 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012  Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 78bdc84..2c9c53b 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 3cd9b3f..c375f8d 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Tobias Kaminsky
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -49,10 +53,7 @@ import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.DisplayUtils;
 
 /**
- * Manager for concurrent access to thumbnails cache. 
- *  
- * @author Tobias Kaminsky
- * @author David A. Velasco
+ * Manager for concurrent access to thumbnails cache.
  */
 public class ThumbnailsCacheManager {
     
@@ -144,7 +145,8 @@ public class ThumbnailsCacheManager {
         private FileDataStorageManager mStorageManager;
 
 
-        public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager, Account account) {
+        public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager,
+                                       Account account) {
             // Use a WeakReference to ensure the ImageView can be garbage collected
             mImageViewReference = new WeakReference<ImageView>(imageView);
             if (storageManager == null)
@@ -167,7 +169,8 @@ public class ThumbnailsCacheManager {
                     AccountManager accountMgr = AccountManager.get(MainApp.getAppContext());
 
                     mServerVersion = accountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION);
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, MainApp.getAppContext());
+                    OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount,
+                            MainApp.getAppContext());
                     mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                             getClientFor(ocAccount, MainApp.getAppContext());
                 }
@@ -275,18 +278,21 @@ public class ThumbnailsCacheManager {
                     // Download thumbnail from server
                     if (mClient != null && mServerVersion != null) {
                         OwnCloudVersion serverOCVersion = new OwnCloudVersion(mServerVersion);
-                        if (serverOCVersion.compareTo(new OwnCloudVersion(MINOR_SERVER_VERSION_FOR_THUMBS)) >= 0) {
+                        if (serverOCVersion.compareTo(
+                                new OwnCloudVersion(MINOR_SERVER_VERSION_FOR_THUMBS)) >= 0) {
                             try {
                                 int status = -1;
 
-                                String uri = mClient.getBaseUri() + "/index.php/apps/files/api/v1/thumbnail/" +
+                                String uri = mClient.getBaseUri() + "" +
+                                        "/index.php/apps/files/api/v1/thumbnail/" +
                                         px + "/" + px + Uri.encode(file.getRemotePath(), "/");
                                 Log_OC.d("Thumbnail", "URI: " + uri);
                                 GetMethod get = new GetMethod(uri);
                                 status = mClient.executeMethod(get);
                                 if (status == HttpStatus.SC_OK) {
                                     byte[] bytes = get.getResponseBody();
-                                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
+                                    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0,
+                                            bytes.length);
                                     thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
 
                                     // Add thumbnail to cache
index 3682a7b..6611306 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
  *   Copyright (C) 2011-2012  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -28,9 +31,6 @@ import android.database.sqlite.SQLiteOpenHelper;
 
 /**
  * Custom database helper for ownCloud
- * 
- * @author Bartek Przybylski
- * 
  */
 public class DbHandler {
     private SQLiteDatabase mDB;
index b6bfe4a..1f789d1 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -24,9 +27,6 @@ import com.owncloud.android.MainApp;
 \r
 /**\r
  * Meta-Class that holds various static field information\r
- * \r
- * @author Bartek Przybylski\r
- * \r
  */\r
 public class ProviderMeta {\r
 \r
index 4e139ae..2cf4358 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -29,8 +32,6 @@ import android.content.Intent;
 /**
  * App-registered receiver catching the broadcast intent reporting that the system was 
  * just boot up.
- * 
- * @author David A. Velasco
  */
 public class BootupBroadcastReceiver extends BroadcastReceiver {
 
index 89b00dc..04e9fbc 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -38,8 +41,6 @@ import com.owncloud.android.ui.activity.ComponentsGetter;
 /**
  * Filters out the file actions available in a given {@link Menu} for a given {@link OCFile} 
  * according to the current state of the latest. 
- * 
- * @author David A. Velasco
  */
 public class FileMenuFilter {
 
index cf9f474..b2f74f2 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2015 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -41,9 +45,7 @@ import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.dialog.ShareLinkToDialog;
 
 /**
- * 
- * @author masensio
- * @author David A. Velasco
+ *
  */
 public class FileOperationsHelper {
 
@@ -117,7 +119,7 @@ public class FileOperationsHelper {
     }
     
     
-    public void shareFileWithLinkToApp(OCFile file, Intent sendIntent) {
+    public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) {
         
         if (file != null) {
             mFileActivity.showLoadingDialog();
@@ -126,6 +128,7 @@ public class FileOperationsHelper {
             service.setAction(OperationsService.ACTION_CREATE_SHARE);
             service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
             service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+            service.putExtra(OperationsService.EXTRA_PASSWORD_SHARE, password);
             service.putExtra(OperationsService.EXTRA_SEND_INTENT, sendIntent);
             mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
             
index c1c3e9c..b52c36d 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012  Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index cd7afa6..f6d3b50 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
  *   Copyright (C) 2012-2015 ownCloud Inc.
  *
@@ -26,7 +28,9 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.Vector;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -49,7 +53,9 @@ import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 
 import android.accounts.Account;
+import android.accounts.AccountManager;
 import android.accounts.AccountsException;
+import android.accounts.OnAccountsUpdateListener;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -64,19 +70,20 @@ import android.os.Process;
 import android.support.v4.app.NotificationCompat;
 import android.util.Pair;
 
-public class FileDownloader extends Service implements OnDatatransferProgressListener {
-    
+public class FileDownloader extends Service
+        implements OnDatatransferProgressListener, OnAccountsUpdateListener {
+
     public static final String EXTRA_ACCOUNT = "ACCOUNT";
     public static final String EXTRA_FILE = "FILE";
 
     private static final String DOWNLOAD_ADDED_MESSAGE = "DOWNLOAD_ADDED";
     private static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";
-    public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";    
+    public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";
     public static final String EXTRA_FILE_PATH = "FILE_PATH";
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
     public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
     public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
-    
+
     private static final String TAG = "FileDownloader";
 
     private Looper mServiceLooper;
@@ -85,24 +92,24 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     private OwnCloudClient mDownloadClient = null;
     private Account mCurrentAccount = null;
     private FileDataStorageManager mStorageManager;
-    
+
     private IndexedForest<DownloadFileOperation> mPendingDownloads = new IndexedForest<DownloadFileOperation>();
 
     private DownloadFileOperation mCurrentDownload = null;
-    
+
     private NotificationManager mNotificationManager;
     private NotificationCompat.Builder mNotificationBuilder;
     private int mLastPercent;
 
-    
+
     public static String getDownloadAddedMessage() {
         return FileDownloader.class.getName() + DOWNLOAD_ADDED_MESSAGE;
     }
-    
+
     public static String getDownloadFinishMessage() {
         return FileDownloader.class.getName() + DOWNLOAD_FINISH_MESSAGE;
     }
-    
+
     /**
      * Service initialization
      */
@@ -111,11 +118,16 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         super.onCreate();
         Log_OC.d(TAG, "Creating service");
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        HandlerThread thread = new HandlerThread("FileDownloaderThread", Process.THREAD_PRIORITY_BACKGROUND);
+        HandlerThread thread = new HandlerThread("FileDownloaderThread",
+                Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
         mServiceLooper = thread.getLooper();
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileDownloaderBinder();
+
+        // add AccountsUpdatedListener
+        AccountManager am = AccountManager.get(getApplicationContext());
+        am.addOnAccountsUpdatedListener(this, null, false);
     }
 
 
@@ -124,19 +136,24 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
      */
     @Override
     public void onDestroy() {
-        Log_OC.v(TAG, "Destroying service" );
+        Log_OC.v(TAG, "Destroying service");
         mBinder = null;
         mServiceHandler = null;
         mServiceLooper.quit();
         mServiceLooper = null;
         mNotificationManager = null;
+
+        // remove AccountsUpdatedListener
+        AccountManager am = AccountManager.get(getApplicationContext());
+        am.removeOnAccountsUpdatedListener(this);
+
         super.onDestroy();
     }
 
 
     /**
      * Entry point to add one or several files to the queue of downloads.
-     *
+     * <p/>
      * New downloads are added calling to startService(), resulting in a call to this method.
      * This ensures the service will keep on working although the caller activity goes away.
      */
@@ -144,9 +161,9 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log_OC.d(TAG, "Starting command with id " + startId);
 
-        if (    !intent.hasExtra(EXTRA_ACCOUNT) ||
+        if (!intent.hasExtra(EXTRA_ACCOUNT) ||
                 !intent.hasExtra(EXTRA_FILE)
-           ) {
+                ) {
             Log_OC.e(TAG, "Not enough information provided in intent");
             return START_NOT_STICKY;
         } else {
@@ -158,42 +175,44 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                     "Received request to download file"
             );*/
 
-                AbstractList<String> requestedDownloads = new Vector<String>();
-                try {
-                    DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
-                    newDownload.addDatatransferProgressListener(this);
-                    newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
-                    Pair<String, String> putResult = mPendingDownloads.putIfAbsent(
+            AbstractList<String> requestedDownloads = new Vector<String>();
+            try {
+                DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
+                newDownload.addDatatransferProgressListener(this);
+                newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
+                Pair<String, String> putResult = mPendingDownloads.putIfAbsent(
                         account, file.getRemotePath(), newDownload
-                    );
-                    String downloadKey = putResult.first;
-                    requestedDownloads.add(downloadKey);
+                );
+                String downloadKey = putResult.first;
+                requestedDownloads.add(downloadKey);
                     /*Log_OC.v(
                         "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
                         "Download on " + file.getRemotePath() + " added to queue"
                     );*/
 
-                    // Store file on db with state 'downloading'
+                // Store file on db with state 'downloading'
                     /*
-                    TODO - check if helps with UI responsiveness, letting only folders use FileDownloaderBinder to check
-                    FileDataStorageManager storageManager = new FileDataStorageManager(account, getContentResolver());
+                    TODO - check if helps with UI responsiveness,
+                    letting only folders use FileDownloaderBinder to check
+                    FileDataStorageManager storageManager =
+                    new FileDataStorageManager(account, getContentResolver());
                     file.setDownloading(true);
                     storageManager.saveFile(file);
                     */
 
-                    sendBroadcastNewDownload(newDownload, putResult.second);
+                sendBroadcastNewDownload(newDownload, putResult.second);
 
-                } catch (IllegalArgumentException e) {
-                    Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
-                    return START_NOT_STICKY;
-                }
+            } catch (IllegalArgumentException e) {
+                Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
+                return START_NOT_STICKY;
+            }
 
-                if (requestedDownloads.size() > 0) {
-                    Message msg = mServiceHandler.obtainMessage();
-                    msg.arg1 = startId;
-                    msg.obj = requestedDownloads;
-                    mServiceHandler.sendMessage(msg);
-                }
+            if (requestedDownloads.size() > 0) {
+                Message msg = mServiceHandler.obtainMessage();
+                msg.arg1 = startId;
+                msg.obj = requestedDownloads;
+                mServiceHandler.sendMessage(msg);
+            }
             //}
         }
 
@@ -204,7 +223,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     /**
      * Provides a binder object that clients can use to perform operations on the queue of downloads,
      * excepting the addition of new files.
-     *
+     * <p/>
      * Implemented to perform cancellation, pause and resume of existing downloads.
      */
     @Override
@@ -218,20 +237,31 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
      */
     @Override
     public boolean onUnbind(Intent intent) {
-        ((FileDownloaderBinder)mBinder).clearListeners();
+        ((FileDownloaderBinder) mBinder).clearListeners();
         return false;   // not accepting rebinding (default behaviour)
     }
 
+    @Override
+    public void onAccountsUpdated(Account[] accounts) {
+         //review the current download and cancel it if its account doesn't exist
+        if (mCurrentDownload != null &&
+                !AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) {
+            mCurrentDownload.cancel();
+        }
+        // The rest of downloads are cancelled when they try to start
+    }
+
 
     /**
-     *  Binder to let client components to perform operations on the queue of downloads.
-     *
-     *  It provides by itself the available operations.
+     * Binder to let client components to perform operations on the queue of downloads.
+     * <p/>
+     * It provides by itself the available operations.
      */
     public class FileDownloaderBinder extends Binder implements OnDatatransferProgressListener {
-        
-        /** 
-         * Map of listeners that will be reported about progress of downloads from a {@link FileDownloaderBinder}
+
+        /**
+         * Map of listeners that will be reported about progress of downloads from a
+         * {@link FileDownloaderBinder}
          * instance.
          */
         private Map<Long, OnDatatransferProgressListener> mBoundListeners =
@@ -241,8 +271,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         /**
          * Cancels a pending or current download of a remote file.
          *
-         * @param account       ownCloud account where the remote file is stored.
-         * @param file          A file in the queue of pending downloads
+         * @param account ownCloud account where the remote file is stored.
+         * @param file    A file in the queue of pending downloads
          */
         public void cancel(Account account, OCFile file) {
             /*Log_OC.v(
@@ -251,7 +281,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             );
             Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
                     "Removing download of " + file.getRemotePath());*/
-            Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.remove(account, file.getRemotePath());
+            Pair<DownloadFileOperation, String> removeResult =
+                    mPendingDownloads.remove(account, file.getRemotePath());
             DownloadFileOperation download = removeResult.first;
             if (download != null) {
                 /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
@@ -262,58 +293,75 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                         mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
                         account.name.equals(mCurrentAccount.name)) {
                     /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
-                            "Canceling current sync as descendant: " + mCurrentDownload.getRemotePath());*/
+                     "Canceling current sync as descendant: " + mCurrentDownload.getRemotePath());*/
+                    mCurrentDownload.cancel();
+                }
+            }
+        }
+
+        /**
+         * Cancels a pending or current upload for an account
+         *
+         * @param account Owncloud accountName where the remote file will be stored.
+         */
+        public void cancel(Account account) {
+            Log_OC.d(TAG, "Account= " + account.name);
+
+            if (mCurrentDownload != null) {
+                Log_OC.d(TAG, "Current Download Account= " + mCurrentDownload.getAccount().name);
+                if (mCurrentDownload.getAccount().name.equals(account.name)) {
                     mCurrentDownload.cancel();
                 }
             }
+            // Cancel pending downloads
+            cancelDownloadsForAccount(account);
         }
-        
-        
+
         public void clearListeners() {
             mBoundListeners.clear();
         }
 
 
         /**
-         * Returns True when the file described by 'file' in the ownCloud account 'account' is downloading or
-         * waiting to download.
-         * 
+         * Returns True when the file described by 'file' in the ownCloud account 'account'
+         * is downloading or waiting to download.
+         * <p/>
          * If 'file' is a directory, returns 'true' if any of its descendant files is downloading or
          * waiting to download.
-         * 
-         * @param account       ownCloud account where the remote file is stored.
-         * @param file          A file that could be in the queue of downloads.
+         *
+         * @param account ownCloud account where the remote file is stored.
+         * @param file    A file that could be in the queue of downloads.
          */
         public boolean isDownloading(Account account, OCFile file) {
             if (account == null || file == null) return false;
             return (mPendingDownloads.contains(account, file.getRemotePath()));
         }
 
-        
+
         /**
          * Adds a listener interested in the progress of the download for a concrete file.
-         * 
-         * @param listener      Object to notify about progress of transfer.    
-         * @param account       ownCloud account holding the file of interest.
-         * @param file          {@link OCFile} of interest for listener.
+         *
+         * @param listener Object to notify about progress of transfer.
+         * @param account  ownCloud account holding the file of interest.
+         * @param file     {@link OCFile} of interest for listener.
          */
-        public void addDatatransferProgressListener (
+        public void addDatatransferProgressListener(
                 OnDatatransferProgressListener listener, Account account, OCFile file
         ) {
             if (account == null || file == null || listener == null) return;
             //String targetKey = buildKey(account, file.getRemotePath());
             mBoundListeners.put(file.getFileId(), listener);
         }
-        
-        
+
+
         /**
          * Removes a listener interested in the progress of the download for a concrete file.
-         * 
-         * @param listener      Object to notify about progress of transfer.    
-         * @param account       ownCloud account holding the file of interest.
-         * @param file          {@link OCFile} of interest for listener.
+         *
+         * @param listener Object to notify about progress of transfer.
+         * @param account  ownCloud account holding the file of interest.
+         * @param file     {@link OCFile} of interest for listener.
          */
-        public void removeDatatransferProgressListener (
+        public void removeDatatransferProgressListener(
                 OnDatatransferProgressListener listener, Account account, OCFile file
         ) {
             if (account == null || file == null || listener == null) return;
@@ -325,26 +373,42 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         }
 
         @Override
-        public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
-                String fileName) {
-            //String key = buildKey(mCurrentDownload.getAccount(), mCurrentDownload.getFile().getRemotePath());
-            OnDatatransferProgressListener boundListener = mBoundListeners.get(mCurrentDownload.getFile().getFileId());
+        public void onTransferProgress(long progressRate, long totalTransferredSoFar,
+                                       long totalToTransfer, String fileName) {
+            //String key = buildKey(mCurrentDownload.getAccount(),
+            // mCurrentDownload.getFile().getRemotePath());
+            OnDatatransferProgressListener boundListener =
+                    mBoundListeners.get(mCurrentDownload.getFile().getFileId());
             if (boundListener != null) {
-                boundListener.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName);
+                boundListener.onTransferProgress(progressRate, totalTransferredSoFar,
+                        totalToTransfer, fileName);
+            }
+        }
+
+        /**
+         * Review downloads and cancel it if its account doesn't exist
+         */
+        public void checkAccountOfCurrentDownload() {
+            if (mCurrentDownload != null &&
+                    !AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) {
+                mCurrentDownload.cancel();
             }
+            // The rest of downloads are cancelled when they try to start
         }
-        
+
     }
-    
-    
-    /** 
-     * Download worker. Performs the pending downloads in the order they were requested. 
-     * 
-     * Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}. 
+
+
+    /**
+     * Download worker. Performs the pending downloads in the order they were requested.
+     * <p/>
+     * Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}.
      */
     private static class ServiceHandler extends Handler {
-        // don't make it a final class, and don't remove the static ; lint will warn about a possible memory leak
+        // don't make it a final class, and don't remove the static ; lint will warn about a
+        // possible memory leak
         FileDownloader mService;
+
         public ServiceHandler(Looper looper, FileDownloader service) {
             super(looper);
             if (service == null)
@@ -367,12 +431,12 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             mService.stopSelf(msg.arg1);
         }
     }
-    
+
 
     /**
      * Core download method: requests a file to download and stores it.
-     * 
-     * @param downloadKey   Key to access the download to perform, contained in mPendingDownloads 
+     *
+     * @param downloadKey Key to access the download to perform, contained in mPendingDownloads
      */
     private void downloadFile(String downloadKey) {
 
@@ -381,54 +445,68 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         mCurrentDownload = mPendingDownloads.get(downloadKey);
 
         if (mCurrentDownload != null) {
-            
-            notifyDownloadStart(mCurrentDownload);
+            // Detect if the account exists
+            if (AccountUtils.exists(mCurrentDownload.getAccount(), getApplicationContext())) {
+                Log_OC.d(TAG, "Account " + mCurrentDownload.getAccount().name + " exists");
+                notifyDownloadStart(mCurrentDownload);
 
-            RemoteOperationResult downloadResult = null;
-            try {
-                /// prepare client object to send the request to the ownCloud server
-                if (mCurrentAccount == null || !mCurrentAccount.equals(mCurrentDownload.getAccount())) {
-                    mCurrentAccount = mCurrentDownload.getAccount();
-                    mStorageManager = new FileDataStorageManager(
-                            mCurrentAccount,
-                            getContentResolver()
-                    );
-                }   // else, reuse storage manager from previous operation
-
-                // always get client from client manager, to get fresh credentials in case of update
-                OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
-                mDownloadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
-                        getClientFor(ocAccount, this);
-
-
-                /// perform the download
-                /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
+                RemoteOperationResult downloadResult = null;
+                try {
+                    /// prepare client object to send the request to the ownCloud server
+                    if (mCurrentAccount == null ||
+                            !mCurrentAccount.equals(mCurrentDownload.getAccount())) {
+                        mCurrentAccount = mCurrentDownload.getAccount();
+                        mStorageManager = new FileDataStorageManager(
+                                mCurrentAccount,
+                                getContentResolver()
+                        );
+                    }   // else, reuse storage manager from previous operation
+
+                    // always get client from client manager, to get fresh credentials in case
+                    // of update
+                    OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
+                    mDownloadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+                            getClientFor(ocAccount, this);
+
+
+                    /// perform the download
+                    /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
                         "Executing download of " + mCurrentDownload.getRemotePath());*/
-                downloadResult = mCurrentDownload.execute(mDownloadClient);
-                if (downloadResult.isSuccess()) {
-                    saveDownloadedFile();
-                }
-            
-            } catch (AccountsException e) {
-                Log_OC.e(TAG, "Error while trying to get authorization for " + mCurrentAccount.name, e);
-                downloadResult = new RemoteOperationResult(e);
-            } catch (IOException e) {
-                Log_OC.e(TAG, "Error while trying to get authorization for " + mCurrentAccount.name, e);
-                downloadResult = new RemoteOperationResult(e);
-                
-            } finally {
+                    downloadResult = mCurrentDownload.execute(mDownloadClient);
+                    if (downloadResult.isSuccess()) {
+                        saveDownloadedFile();
+                    }
+
+                } catch (AccountsException e) {
+                    Log_OC.e(TAG, "Error while trying to get authorization for "
+                            + mCurrentAccount.name, e);
+                    downloadResult = new RemoteOperationResult(e);
+                } catch (IOException e) {
+                    Log_OC.e(TAG, "Error while trying to get authorization for "
+                            + mCurrentAccount.name, e);
+                    downloadResult = new RemoteOperationResult(e);
+
+                } finally {
                 /*Log_OC.v(   "NOW " + TAG + ", thread " + Thread.currentThread().getName(),
                         "Removing payload " + mCurrentDownload.getRemotePath());*/
 
-                Pair<DownloadFileOperation, String> removeResult =
-                        mPendingDownloads.removePayload(mCurrentAccount, mCurrentDownload.getRemotePath());
+                    Pair<DownloadFileOperation, String> removeResult =
+                            mPendingDownloads.removePayload(mCurrentAccount,
+                                    mCurrentDownload.getRemotePath());
 
-                /// notify result
-                notifyDownloadResult(mCurrentDownload, downloadResult);
+                    /// notify result
+                    notifyDownloadResult(mCurrentDownload, downloadResult);
 
-                sendBroadcastDownloadFinished(mCurrentDownload, downloadResult, removeResult.second);
-            }
+                    sendBroadcastDownloadFinished(mCurrentDownload, downloadResult,
+                            removeResult.second);
+                }
+            } else {
+                // Cancel the transfer
+                Log_OC.d(TAG, "Account " + mCurrentDownload.getAccount().toString() +
+                        " doesn't exist");
+                cancelDownloadsForAccount(mCurrentDownload.getAccount());
 
+            }
         }
     }
 
@@ -465,13 +543,13 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
 
     /**
      * Creates a status notification to show the download progress
-     * 
-     * @param download  Download operation starting.
+     *
+     * @param download Download operation starting.
      */
     private void notifyDownloadStart(DownloadFileOperation download) {
         /// create status notification with a progress bar
         mLastPercent = 0;
-        mNotificationBuilder = 
+        mNotificationBuilder =
                 NotificationBuilderWithProgressBar.newNotificationBuilderWithProgressBar(this);
         mNotificationBuilder
                 .setSmallIcon(R.drawable.notification_icon)
@@ -483,7 +561,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                         String.format(getString(R.string.downloader_download_in_progress_content), 0,
                                 new File(download.getSavePath()).getName())
                 );
-                
+
         /// includes a pending intent in the notification showing the details view of the file
         Intent showDetailsIntent = null;
         if (PreviewImageFragment.canBePreviewed(download.getFile())) {
@@ -494,22 +572,22 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, download.getFile());
         showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, download.getAccount());
         showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        
+
         mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-            this, (int) System.currentTimeMillis(), showDetailsIntent, 0
+                this, (int) System.currentTimeMillis(), showDetailsIntent, 0
         ));
 
         mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotificationBuilder.build());
     }
 
-    
+
     /**
      * Callback method to update the progress bar in the status notification.
      */
     @Override
-    public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath)
-    {
-        int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer));
+    public void onTransferProgress(long progressRate, long totalTransferredSoFar,
+                                   long totalToTransfer, String filePath) {
+        int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         if (percent != mLastPercent) {
             mNotificationBuilder.setProgress(100, percent, totalToTransfer < 0);
             String fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1);
@@ -519,81 +597,87 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         }
         mLastPercent = percent;
     }
-    
-    
+
+
     /**
      * Updates the status notification with the result of a download operation.
-     * 
-     * @param downloadResult    Result of the download operation.
-     * @param download          Finished download operation
+     *
+     * @param downloadResult Result of the download operation.
+     * @param download       Finished download operation
      */
-    private void notifyDownloadResult(DownloadFileOperation download, RemoteOperationResult downloadResult) {
+    private void notifyDownloadResult(DownloadFileOperation download,
+                                      RemoteOperationResult downloadResult) {
         mNotificationManager.cancel(R.string.downloader_download_in_progress_ticker);
         if (!downloadResult.isCancelled()) {
-            int tickerId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_ticker : 
-                R.string.downloader_download_failed_ticker;
-            
+            int tickerId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_ticker :
+                    R.string.downloader_download_failed_ticker;
+
             boolean needsToUpdateCredentials = (
                     downloadResult.getCode() == ResultCode.UNAUTHORIZED ||
-                    downloadResult.isIdPRedirection()
+                            downloadResult.isIdPRedirection()
             );
-            tickerId = (needsToUpdateCredentials) ? 
+            tickerId = (needsToUpdateCredentials) ?
                     R.string.downloader_download_failed_credentials_error : tickerId;
-            
+
             mNotificationBuilder
-            .setTicker(getString(tickerId))
-            .setContentTitle(getString(tickerId))
-            .setAutoCancel(true)
-            .setOngoing(false)
-            .setProgress(0, 0, false);
-            
+                    .setTicker(getString(tickerId))
+                    .setContentTitle(getString(tickerId))
+                    .setAutoCancel(true)
+                    .setOngoing(false)
+                    .setProgress(0, 0, false);
+
             if (needsToUpdateCredentials) {
-                
+
                 // let the user update credentials with one click
                 Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
-                updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, download.getAccount());
+                updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT,
+                        download.getAccount());
                 updateAccountCredentials.putExtra(
-                        AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
+                        AuthenticatorActivity.EXTRA_ACTION,
+                        AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
                 );
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                 updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
                 mNotificationBuilder
-                    .setContentIntent(PendingIntent.getActivity(
-                        this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT));
-                
+                        .setContentIntent(PendingIntent.getActivity(
+                                this, (int) System.currentTimeMillis(), updateAccountCredentials,
+                                PendingIntent.FLAG_ONE_SHOT));
+
             } else {
                 // TODO put something smart in showDetailsIntent
-                Intent   showDetailsIntent = new Intent();
+                Intent showDetailsIntent = new Intent();
                 mNotificationBuilder
-                    .setContentIntent(PendingIntent.getActivity(
-                        this, (int) System.currentTimeMillis(), showDetailsIntent, 0));
+                        .setContentIntent(PendingIntent.getActivity(
+                                this, (int) System.currentTimeMillis(), showDetailsIntent, 0));
             }
-            
+
             mNotificationBuilder.setContentText(
-                    ErrorMessageAdapter.getErrorCauseMessage(downloadResult, download, getResources())
+                    ErrorMessageAdapter.getErrorCauseMessage(downloadResult, download,
+                            getResources())
             );
             mNotificationManager.notify(tickerId, mNotificationBuilder.build());
-            
+
             // Remove success notification
-            if (downloadResult.isSuccess()) {   
+            if (downloadResult.isSuccess()) {
                 // Sleep 2 seconds, so show the notification before remove it
                 NotificationDelayer.cancelWithDelay(
-                        mNotificationManager, 
-                        R.string.downloader_download_succeeded_ticker, 
+                        mNotificationManager,
+                        R.string.downloader_download_succeeded_ticker,
                         2000);
             }
-                
+
         }
     }
-    
-    
+
+
     /**
-     * Sends a broadcast when a download finishes in order to the interested activities can update their view
-     * 
-     * @param download                  Finished download operation
-     * @param downloadResult            Result of the download operation
-     * @param unlinkedFromRemotePath    Path in the downloads tree where the download was unlinked from
+     * Sends a broadcast when a download finishes in order to the interested activities can
+     * update their view
+     *
+     * @param download               Finished download operation
+     * @param downloadResult         Result of the download operation
+     * @param unlinkedFromRemotePath Path in the downloads tree where the download was unlinked from
      */
     private void sendBroadcastDownloadFinished(
             DownloadFileOperation download,
@@ -609,15 +693,16 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         }
         sendStickyBroadcast(end);
     }
-    
-    
+
+
     /**
      * Sends a broadcast when a new download is added to the queue.
-     * 
-     * @param download              Added download operation
-     * @param linkedToRemotePath    Path in the downloads tree where the download was linked to
+     *
+     * @param download           Added download operation
+     * @param linkedToRemotePath Path in the downloads tree where the download was linked to
      */
-    private void sendBroadcastNewDownload(DownloadFileOperation download, String linkedToRemotePath) {
+    private void sendBroadcastNewDownload(DownloadFileOperation download,
+                                          String linkedToRemotePath) {
         Intent added = new Intent(getDownloadAddedMessage());
         added.putExtra(ACCOUNT_NAME, download.getAccount().name);
         added.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
@@ -626,4 +711,13 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         sendStickyBroadcast(added);
     }
 
+    /**
+     * Remove downloads of an account
+     *
+     * @param account       Downloads account to remove
+     */
+    private void cancelDownloadsForAccount(Account account) {
+        // Cancel pending downloads
+        mPendingDownloads.remove(account);
+    }
 }
index 6f77a9c..8beff92 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2012-2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -31,6 +33,7 @@ import java.util.concurrent.ConcurrentMap;
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AccountsException;
+import android.accounts.OnAccountsUpdateListener;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -45,6 +48,7 @@ import android.os.Process;
 import android.support.v4.app.NotificationCompat;
 import android.webkit.MimeTypeMap;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
@@ -76,8 +80,8 @@ import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.UriUtils;
 
 
-
-public class FileUploader extends Service implements OnDatatransferProgressListener {
+public class FileUploader extends Service
+        implements OnDatatransferProgressListener, OnAccountsUpdateListener {
 
     private static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
     public static final String EXTRA_UPLOAD_RESULT = "RESULT";
@@ -124,14 +128,14 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     private static final String MIME_TYPE_PDF = "application/pdf";
     private static final String FILE_EXTENSION_PDF = ".pdf";
 
-    
+
     public static String getUploadFinishMessage() {
         return FileUploader.class.getName().toString() + UPLOAD_FINISH_MESSAGE;
     }
-    
+
     /**
      * Builds a key for mPendingUploads from the account and file to upload
-     * 
+     *
      * @param account   Account where the file to upload is stored
      * @param file      File to upload
      */
@@ -145,7 +149,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Checks if an ownCloud server version should support chunked uploads.
-     * 
+     *
      * @param version OwnCloud version instance corresponding to an ownCloud
      *            server.
      * @return 'True' if the ownCloud server with version supports chunked
@@ -163,11 +167,16 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         super.onCreate();
         Log_OC.d(TAG, "Creating service");
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND);
+        HandlerThread thread = new HandlerThread("FileUploaderThread",
+                Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
         mServiceLooper = thread.getLooper();
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileUploaderBinder();
+
+        // add AccountsUpdatedListener
+        AccountManager am = AccountManager.get(getApplicationContext());
+        am.addOnAccountsUpdatedListener(this, null, false);
     }
 
     /**
@@ -181,13 +190,18 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         mServiceLooper.quit();
         mServiceLooper = null;
         mNotificationManager = null;
+
+        // remove AccountsUpdatedListener
+        AccountManager am = AccountManager.get(getApplicationContext());
+        am.removeOnAccountsUpdatedListener(this);
+
         super.onDestroy();
     }
 
 
     /**
      * Entry point to add one or several files to the queue of uploads.
-     * 
+     *
      * New uploads are added calling to startService(), resulting in a call to
      * this method. This ensures the service will keep on working although the
      * caller activity goes away.
@@ -241,12 +255,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             }
         }
 
-        FileDataStorageManager storageManager = new FileDataStorageManager(account, getContentResolver());
+        FileDataStorageManager storageManager = new FileDataStorageManager(account,
+                getContentResolver());
 
         boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
         boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
         int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_COPY);
-        
+
         if (intent.hasExtra(KEY_FILE) && files == null) {
             Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
             return Service.START_NOT_STICKY;
@@ -267,8 +282,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             files = new OCFile[localPaths.length];
             for (int i = 0; i < localPaths.length; i++) {
-                files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i]
-                        : (String) null), storageManager);
+                files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i],
+                        ((mimeTypes != null) ? mimeTypes[i] : (String) null), storageManager);
                 if (files[i] == null) {
                     // TODO @andomaex add failure Notification
                     return Service.START_NOT_STICKY;
@@ -279,7 +294,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         AccountManager aMgr = AccountManager.get(this);
         String version = aMgr.getUserData(account, Constants.KEY_OC_VERSION);
         OwnCloudVersion ocv = new OwnCloudVersion(version);
-        
+
         boolean chunked = FileUploader.chunkedUploadIsSupported(ocv);
         AbstractList<String> requestedUploads = new Vector<String>();
         String uploadKey = null;
@@ -287,12 +302,14 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         try {
             for (int i = 0; i < files.length; i++) {
                 uploadKey = buildRemoteName(account, files[i].getRemotePath());
-                newUpload = new UploadFileOperation(account, files[i], chunked, isInstant, forceOverwrite, localAction, 
+                newUpload = new UploadFileOperation(account, files[i], chunked, isInstant,
+                        forceOverwrite, localAction,
                         getApplicationContext());
                 if (isInstant) {
                     newUpload.setRemoteFolderToBeCreated();
                 }
-                mPendingUploads.putIfAbsent(uploadKey, newUpload); // Grants that the file only upload once time
+                // Grants that the file only upload once time
+                mPendingUploads.putIfAbsent(uploadKey, newUpload);
 
                 newUpload.addDatatransferProgressListener(this);
                 newUpload.addDatatransferProgressListener((FileUploaderBinder)mBinder);
@@ -326,7 +343,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     /**
      * Provides a binder object that clients can use to perform operations on
      * the queue of uploads, excepting the addition of new files.
-     * 
+     *
      * Implemented to perform cancellation, pause and resume of existing
      * uploads.
      */
@@ -334,7 +351,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     public IBinder onBind(Intent arg0) {
         return mBinder;
     }
-    
+
     /**
      * Called when ALL the bound clients were onbound.
      */
@@ -343,24 +360,34 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         ((FileUploaderBinder)mBinder).clearListeners();
         return false;   // not accepting rebinding (default behaviour)
     }
-    
+
+    @Override
+    public void onAccountsUpdated(Account[] accounts) {
+        // Review current upload, and cancel it if its account doen't exist
+        if (mCurrentUpload != null &&
+                !AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
+            mCurrentUpload.cancel();
+        }
+        // The rest of uploads are cancelled when they try to start
+    }
 
     /**
      * Binder to let client components to perform operations on the queue of
      * uploads.
-     * 
+     *
      * It provides by itself the available operations.
      */
     public class FileUploaderBinder extends Binder implements OnDatatransferProgressListener {
-        
-        /** 
-         * Map of listeners that will be reported about progress of uploads from a {@link FileUploaderBinder} instance 
+
+        /**
+         * Map of listeners that will be reported about progress of uploads from a
+         * {@link FileUploaderBinder} instance
          */
         private Map<String, OnDatatransferProgressListener> mBoundListeners = new HashMap<String, OnDatatransferProgressListener>();
-        
+
         /**
          * Cancels a pending or current upload of a remote file.
-         * 
+         *
          * @param account Owncloud account where the remote file will be stored.
          * @param file A file in the queue of pending uploads
          */
@@ -373,22 +400,36 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 upload.cancel();
             }
         }
-        
-        
-        
+
+        /**
+         * Cancels a pending or current upload for an account
+         *
+         * @param account Owncloud accountName where the remote file will be stored.
+         */
+        public void cancel(Account account) {
+            Log_OC.d(TAG, "Account= " + account.name);
+
+            if (mCurrentUpload != null) {
+                Log_OC.d(TAG, "Current Upload Account= " + mCurrentUpload.getAccount().name);
+                if (mCurrentUpload.getAccount().name.equals(account.name)) {
+                    mCurrentUpload.cancel();
+                }
+            }
+            // Cancel pending uploads
+            cancelUploadForAccount(account.name);
+        }
+
         public void clearListeners() {
             mBoundListeners.clear();
         }
 
-
-        
-        
         /**
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
-         * 
-         * If 'file' is a directory, returns 'true' if some of its descendant files is uploading or waiting to upload. 
-         * 
+         *
+         * If 'file' is a directory, returns 'true' if some of its descendant files
+         * is uploading or waiting to upload.
+         *
          * @param account   ownCloud account where the remote file will be stored.
          * @param file      A file that could be in the queue of pending uploads
          */
@@ -414,27 +455,29 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         /**
          * Adds a listener interested in the progress of the upload for a concrete file.
-         * 
+         *
          * @param listener      Object to notify about progress of transfer.    
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
          */
-        public void addDatatransferProgressListener (OnDatatransferProgressListener listener, Account account, OCFile file) {
+        public void addDatatransferProgressListener (OnDatatransferProgressListener listener,
+                                                     Account account, OCFile file) {
             if (account == null || file == null || listener == null) return;
             String targetKey = buildRemoteName(account, file);
             mBoundListeners.put(targetKey, listener);
         }
-        
-        
-        
+
+
+
         /**
          * Removes a listener interested in the progress of the upload for a concrete file.
-         * 
+         *
          * @param listener      Object to notify about progress of transfer.    
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
          */
-        public void removeDatatransferProgressListener (OnDatatransferProgressListener listener, Account account, OCFile file) {
+        public void removeDatatransferProgressListener (OnDatatransferProgressListener listener,
+                                                        Account account, OCFile file) {
             if (account == null || file == null || listener == null) return;
             String targetKey = buildRemoteName(account, file);
             if (mBoundListeners.get(targetKey) == listener) {
@@ -444,21 +487,32 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
 
         @Override
-        public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
-                String fileName) {
+        public void onTransferProgress(long progressRate, long totalTransferredSoFar,
+                                       long totalToTransfer, String fileName) {
             String key = buildRemoteName(mCurrentUpload.getAccount(), mCurrentUpload.getFile());
             OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
             if (boundListener != null) {
-                boundListener.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName);
+                boundListener.onTransferProgress(progressRate, totalTransferredSoFar,
+                        totalToTransfer, fileName);
             }
         }
-        
+
+        /**
+         * Review uploads and cancel it if its account doesn't exist
+         */
+        public void checkAccountOfCurrentUpload() {
+            if (mCurrentUpload != null &&
+                    !AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
+                mCurrentUpload.cancel();
+            }
+            // The rest of uploads are cancelled when they try to start
+        }
     }
 
     /**
      * Upload worker. Performs the pending uploads in the order they were
      * requested.
-     * 
+     *
      * Created with the Looper of a new thread, started in
      * {@link FileUploader#onCreate()}.
      */
@@ -491,7 +545,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Core upload method: sends the file(s) to upload
-     * 
+     *
      * @param uploadKey Key to access the upload to perform, contained in
      *            mPendingUploads
      */
@@ -503,81 +557,98 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         if (mCurrentUpload != null) {
 
-            notifyUploadStart(mCurrentUpload);
+            // Detect if the account exists
+            if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
+                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().name + " exists");
 
-            RemoteOperationResult uploadResult = null, grantResult = null;
-            
-            try {
-                /// prepare client object to send requests to the ownCloud server
-                if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
-                    mLastAccount = mCurrentUpload.getAccount();
-                    mStorageManager = 
-                            new FileDataStorageManager(mLastAccount, getContentResolver());
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
-                    mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
-                            getClientFor(ocAccount, this);
-                }
-                
-                /// check the existence of the parent folder for the file to upload
-                String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
-                remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ? remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
-                grantResult = grantFolderExistence(remoteParentPath);
-            
-                /// perform the upload
-                if (grantResult.isSuccess()) {
-                    OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
-                    mCurrentUpload.getFile().setParentId(parent.getFileId());
-                    uploadResult = mCurrentUpload.execute(mUploadClient);
-                    if (uploadResult.isSuccess()) {
-                        saveUploadedFile();
+                notifyUploadStart(mCurrentUpload);
+
+                RemoteOperationResult uploadResult = null, grantResult = null;
+
+                try {
+                    /// prepare client object to send requests to the ownCloud server
+                    if (mUploadClient == null ||
+                            !mLastAccount.equals(mCurrentUpload.getAccount())) {
+                        mLastAccount = mCurrentUpload.getAccount();
+                        mStorageManager =
+                                new FileDataStorageManager(mLastAccount, getContentResolver());
+                        OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
+                        mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+                                getClientFor(ocAccount, this);
+                    }
+
+                    /// check the existence of the parent folder for the file to upload
+                    String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
+                    remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ?
+                            remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
+                    grantResult = grantFolderExistence(remoteParentPath);
+
+                    /// perform the upload
+                    if (grantResult.isSuccess()) {
+                        OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
+                        mCurrentUpload.getFile().setParentId(parent.getFileId());
+                        uploadResult = mCurrentUpload.execute(mUploadClient);
+                        if (uploadResult.isSuccess()) {
+                            saveUploadedFile();
+                        }
+                    } else {
+                        uploadResult = grantResult;
+                    }
+
+                } catch (AccountsException e) {
+                    Log_OC.e(TAG, "Error while trying to get autorization for " +
+                            mLastAccount.name, e);
+                    uploadResult = new RemoteOperationResult(e);
+
+                } catch (IOException e) {
+                    Log_OC.e(TAG, "Error while trying to get autorization for " +
+                            mLastAccount.name, e);
+                    uploadResult = new RemoteOperationResult(e);
+
+                } finally {
+                    synchronized (mPendingUploads) {
+                        mPendingUploads.remove(uploadKey);
+                        Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
+                    }
+                    if (uploadResult.isException()) {
+                        // enforce the creation of a new client object for next uploads;
+                        // this grant that a new socket will be created in the future if
+                        // the current exception is due to an abrupt lose of network connection
+                        mUploadClient = null;
                     }
-                } else {
-                    uploadResult = grantResult;
-                }
-                
-            } catch (AccountsException e) {
-                Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
-                uploadResult = new RemoteOperationResult(e);
-                
-            } catch (IOException e) {
-                Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
-                uploadResult = new RemoteOperationResult(e);
-                
-            } finally {
-                synchronized (mPendingUploads) {
-                    mPendingUploads.remove(uploadKey);
-                    Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
-                }
-                if (uploadResult.isException()) {
-                    // enforce the creation of a new client object for next uploads; this grant that a new socket will 
-                    // be created in the future if the current exception is due to an abrupt lose of network connection
-                    mUploadClient = null;
                 }
-            }
-            
-            /// notify result
-            
-            notifyUploadResult(uploadResult, mCurrentUpload);
-            sendFinalBroadcast(mCurrentUpload, uploadResult);
 
+                /// notify result
+                notifyUploadResult(uploadResult, mCurrentUpload);
+                sendFinalBroadcast(mCurrentUpload, uploadResult);
+
+            } else {
+                // Cancel the transfer
+                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() +
+                        " doesn't exist");
+                cancelUploadForAccount(mCurrentUpload.getAccount().name);
+
+            }
         }
 
     }
 
     /**
-     * Checks the existence of the folder where the current file will be uploaded both in the remote server 
-     * and in the local database.
-     * 
-     * If the upload is set to enforce the creation of the folder, the method tries to create it both remote
-     * and locally.
-     *  
+     * Checks the existence of the folder where the current file will be uploaded both
+     * in the remote server and in the local database.
+     *
+     * If the upload is set to enforce the creation of the folder, the method tries to
+     * create it both remote and locally.
+     *
      *  @param  pathToGrant     Full remote path whose existence will be granted.
-     *  @return  An {@link OCFile} instance corresponding to the folder where the file will be uploaded.
+     *  @return  An {@link OCFile} instance corresponding to the folder where the file
+     *  will be uploaded.
      */
     private RemoteOperationResult grantFolderExistence(String pathToGrant) {
         RemoteOperation operation = new ExistenceCheckRemoteOperation(pathToGrant, this, false);
         RemoteOperationResult result = operation.execute(mUploadClient);
-        if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mCurrentUpload.isRemoteFolderToBeCreated()) {
+        if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND &&
+                mCurrentUpload.isRemoteFolderToBeCreated()) {
             SyncOperation syncOp = new CreateFolderOperation( pathToGrant, true);
             result = syncOp.execute(mUploadClient, mStorageManager);
         }
@@ -595,10 +666,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         return result;
     }
 
-    
+
     private OCFile createLocalFolder(String remotePath) {
         String parentPath = new File(remotePath).getParent();
-        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
+        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ?
+                parentPath : parentPath + OCFile.PATH_SEPARATOR;
         OCFile parent = mStorageManager.getFileByPath(parentPath);
         if (parent == null) {
             parent = createLocalFolder(parentPath);
@@ -612,15 +684,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         }
         return null;
     }
-    
+
 
     /**
      * Saves a OC File after a successful upload.
-     * 
+     *
      * A PROPFIND is necessary to keep the props in the local database
      * synchronized with the server, specially the modification time and Etag
      * (where available)
-     * 
+     *
      * TODO refactor this ugly thing
      */
     private void saveUploadedFile() {
@@ -633,13 +705,14 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         // new PROPFIND to keep data consistent with server 
         // in theory, should return the same we already have
-        ReadRemoteFileOperation operation = new ReadRemoteFileOperation(mCurrentUpload.getRemotePath());
+        ReadRemoteFileOperation operation =
+                new ReadRemoteFileOperation(mCurrentUpload.getRemotePath());
         RemoteOperationResult result = operation.execute(mUploadClient);
         if (result.isSuccess()) {
             updateOCFile(file, (RemoteFile) result.getData().get(0));
             file.setLastSyncDateForProperties(syncDate);
         }
-        
+
         // / maybe this would be better as part of UploadFileOperation... or
         // maybe all this method
         if (mCurrentUpload.wasRenamed()) {
@@ -649,8 +722,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 mStorageManager.saveFile(oldFile);
 
             } // else: it was just an automatic renaming due to a name
-              // coincidence; nothing else is needed, the storagePath is right
-              // in the instance returned by mCurrentUpload.getFile()
+            // coincidence; nothing else is needed, the storagePath is right
+            // in the instance returned by mCurrentUpload.getFile()
         }
         file.setNeedsUpdateThumbnail(true);
         mStorageManager.saveFile(file);
@@ -667,7 +740,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     }
 
     private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
-            FileDataStorageManager storageManager) {
+                                           FileDataStorageManager storageManager) {
 
         // MIME type
         if (mimeType == null || mimeType.length() <= 0) {
@@ -675,7 +748,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                         remotePath.substring(remotePath.lastIndexOf('.') + 1));
             } catch (IndexOutOfBoundsException e) {
-                Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + remotePath);
+                Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " +
+                        remotePath);
             }
         }
         if (mimeType == null) {
@@ -697,7 +771,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             newFile.setFileLength(localFile.length());
             newFile.setLastSyncDateForData(localFile.lastModified());
         } // don't worry about not assigning size, the problems with localPath
-          // are checked when the UploadFileOperation instance is created
+        // are checked when the UploadFileOperation instance is created
 
 
         newFile.setMimetype(mimeType);
@@ -707,13 +781,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Creates a status notification to show the upload progress
-     * 
+     *
      * @param upload Upload operation starting.
      */
     private void notifyUploadStart(UploadFileOperation upload) {
         // / create status notification with a progress bar
         mLastPercent = 0;
-        mNotificationBuilder = 
+        mNotificationBuilder =
                 NotificationBuilderWithProgressBar.newNotificationBuilderWithProgressBar(this);
         mNotificationBuilder
                 .setOngoing(true)
@@ -730,7 +804,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
         showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-            this, (int) System.currentTimeMillis(), showDetailsIntent, 0
+                this, (int) System.currentTimeMillis(), showDetailsIntent, 0
         ));
 
         mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
@@ -740,11 +814,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      * Callback method to update the progress bar in the status notification
      */
     @Override
-    public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath) {
+    public void onTransferProgress(long progressRate, long totalTransferredSoFar,
+                                   long totalToTransfer, String filePath) {
         int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         if (percent != mLastPercent) {
             mNotificationBuilder.setProgress(100, percent, false);
-            String fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1);
+            String fileName = filePath.substring(
+                    filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1);
             String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName);
             mNotificationBuilder.setContentText(text);
             mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
@@ -754,7 +830,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Updates the status notification with the result of an upload operation.
-     * 
+     *
      * @param uploadResult Result of the upload operation.
      * @param upload Finished upload operation
      */
@@ -763,33 +839,33 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
         // / cancelled operation or success -> silent removal of progress notification
         mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
-        
+
         // Show the result: success or fail notification
         if (!uploadResult.isCancelled()) {
-            int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker : 
-                R.string.uploader_upload_failed_ticker;
-            
+            int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker :
+                    R.string.uploader_upload_failed_ticker;
+
             String content = null;
 
             // check credentials error
             boolean needsToUpdateCredentials = (
-                    uploadResult.getCode() == ResultCode.UNAUTHORIZED || 
-                    uploadResult.isIdPRedirection()
+                    uploadResult.getCode() == ResultCode.UNAUTHORIZED ||
+                            uploadResult.isIdPRedirection()
             );
-            tickerId = (needsToUpdateCredentials) ? 
+            tickerId = (needsToUpdateCredentials) ?
                     R.string.uploader_upload_failed_credentials_error : tickerId;
 
             mNotificationBuilder
-            .setTicker(getString(tickerId))
-            .setContentTitle(getString(tickerId))
-            .setAutoCancel(true)
-            .setOngoing(false)
-            .setProgress(0, 0, false);
-            
+                    .setTicker(getString(tickerId))
+                    .setContentTitle(getString(tickerId))
+                    .setAutoCancel(true)
+                    .setOngoing(false)
+                    .setProgress(0, 0, false);
+
             content =  ErrorMessageAdapter.getErrorCauseMessage(
                     uploadResult, upload, getResources()
             );
-            
+
             if (needsToUpdateCredentials) {
                 // let the user update credentials with one click
                 Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
@@ -797,24 +873,24 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                         AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount()
                 );
                 updateAccountCredentials.putExtra(
-                        AuthenticatorActivity.EXTRA_ACTION, 
+                        AuthenticatorActivity.EXTRA_ACTION,
                         AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
                 );
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                 updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
                 mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-                    this, 
-                    (int) System.currentTimeMillis(), 
-                    updateAccountCredentials, 
-                    PendingIntent.FLAG_ONE_SHOT
+                        this,
+                        (int) System.currentTimeMillis(),
+                        updateAccountCredentials,
+                        PendingIntent.FLAG_ONE_SHOT
                 ));
-                
-                mUploadClient = null;   
-                    // grant that future retries on the same account will get the fresh credentials
+
+                mUploadClient = null;
+                // grant that future retries on the same account will get the fresh credentials
             } else {
                 mNotificationBuilder.setContentText(content);
-    
+
                 if (upload.isInstant()) {
                     DbHandler db = null;
                     try {
@@ -825,12 +901,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                         if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
                             //message = getString(R.string.failed_upload_quota_exceeded_text);
                             if (db.updateFileState(
-                                    upload.getOriginalStoragePath(), 
+                                    upload.getOriginalStoragePath(),
                                     DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
                                     message) == 0) {
                                 db.putFileForLater(
-                                        upload.getOriginalStoragePath(), 
-                                        upload.getAccount().name, 
+                                        upload.getOriginalStoragePath(),
+                                        upload.getAccount().name,
                                         message
                                 );
                             }
@@ -842,22 +918,22 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                     }
                 }
             }
-            
+
             mNotificationBuilder.setContentText(content);
             mNotificationManager.notify(tickerId, mNotificationBuilder.build());
-            
+
             if (uploadResult.isSuccess()) {
-                
+
                 DbHandler db = new DbHandler(this.getBaseContext());
                 db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
                 db.close();
 
                 // remove success notification, with a delay of 2 seconds
                 NotificationDelayer.cancelWithDelay(
-                        mNotificationManager, 
-                        R.string.uploader_upload_succeeded_ticker, 
+                        mNotificationManager,
+                        R.string.uploader_upload_succeeded_ticker,
                         2000);
-                
+
             }
         }
     }
@@ -865,17 +941,17 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     /**
      * Sends a broadcast in order to the interested activities can update their
      * view
-     * 
+     *
      * @param upload Finished upload operation
      * @param uploadResult Result of the upload operation
      */
     private void sendFinalBroadcast(UploadFileOperation upload, RemoteOperationResult uploadResult) {
         Intent end = new Intent(getUploadFinishMessage());
         end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
-                                                                 // path, after
-                                                                 // possible
-                                                                 // automatic
-                                                                 // renaming
+        // path, after
+        // possible
+        // automatic
+        // renaming
         if (upload.wasRenamed()) {
             end.putExtra(EXTRA_OLD_REMOTE_PATH, upload.getOldFile().getRemotePath());
         }
@@ -892,10 +968,29 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      * @param mimeType
      * @return true if is needed to add the pdf file extension to the file
      */
-    private boolean isPdfFileFromContentProviderWithoutExtension(String localPath, String mimeType) {
-        return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) && 
-                mimeType.equals(MIME_TYPE_PDF) && 
+    private boolean isPdfFileFromContentProviderWithoutExtension(String localPath,
+                                                                 String mimeType) {
+        return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) &&
+                mimeType.equals(MIME_TYPE_PDF) &&
                 !localPath.endsWith(FILE_EXTENSION_PDF);
     }
 
+    /**
+     * Remove uploads of an account
+     * @param accountName
+     */
+    private void cancelUploadForAccount(String accountName){
+        // this can be slow if there are many uploads :(
+        Iterator<String> it = mPendingUploads.keySet().iterator();
+        Log_OC.d(TAG, "Number of pending updloads= "  + mPendingUploads.size());
+        while (it.hasNext()) {
+            String key = it.next();
+            Log_OC.d(TAG, "mPendingUploads CANCELLED " + key);
+            if (key.startsWith(accountName)) {
+                synchronized (mPendingUploads) {
+                    mPendingUploads.remove(key);
+                }
+            }
+        }
+    }
 }
index e2e9cb8..4c1ac7b 100644 (file)
@@ -1,4 +1,7 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
@@ -21,6 +24,7 @@ import android.accounts.Account;
 import android.util.Pair;
 
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.utils.Log_OC;
 
 import java.io.File;
 import java.util.HashSet;
@@ -35,8 +39,6 @@ import java.util.concurrent.ConcurrentMap;
  *  A map provides the indexation based in hashing.
  *
  *  A tree is created per account.
- *
- * @author David A. Velasco
  */
 public class IndexedForest<V> {
 
@@ -211,6 +213,21 @@ public class IndexedForest<V> {
 
 
     /**
+     * Remove the elements that contains account as a part of its key
+     * @param account
+     */
+    public void remove(Account account){
+        Iterator<String> it = mMap.keySet().iterator();
+        while (it.hasNext()) {
+            String key = it.next();
+            Log_OC.d("IndexedForest", "Number of pending downloads= "  + mMap.size());
+            if (key.startsWith(account.name)) {
+                mMap.remove(key);
+            }
+        }
+    }
+
+    /**
      * Builds a key to index files
      *
      * @param account       Account where the file to download is stored
@@ -220,6 +237,4 @@ public class IndexedForest<V> {
         return account.name + remotePath;
     }
 
-
-
 }
index b6ee1ac..f2ed3bb 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index b257bd3..653943b 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
- * 
- *   Copyright (C) 2012-2013  ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -51,8 +53,6 @@ import com.owncloud.android.R;
  * 
  * It synchronizes itself with the state of the 
  * {@link MediaPlayer}.
- * 
- * @author David A. Velasco
  */
 
 public class MediaControlView extends FrameLayout /* implements OnLayoutChangeListener, OnTouchListener */ implements OnClickListener, OnSeekBarChangeListener {
index 52daa04..e53c635 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -49,8 +52,6 @@ import com.owncloud.android.ui.activity.FileDisplayActivity;
  * 
  * Waits for Intents which signal the service to perform specific operations: Play, Pause,
  * Rewind, etc.
- * 
- * @author David A. Velasco
  */
 public class MediaService extends Service implements OnCompletionListener, OnPreparedListener,
                 OnErrorListener, AudioManager.OnAudioFocusChangeListener {
index 1b56ec0..95bf520 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -34,8 +37,6 @@ import android.widget.MediaController;
  * 
  *  Provides the operations of {@link MediaController.MediaPlayerControl}, and an extra method to check if
  *  an {@link OCFile} instance is handled by the MediaService.
- *  
- *  @author David A. Velasco
  */
 public class MediaServiceBinder extends Binder implements MediaController.MediaPlayerControl {
 
index 63ddf63..c71b35f 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -31,8 +34,6 @@ import android.widget.RemoteViews;
  * a progress bar is available in every Android version, because 
  * {@link NotificationCompat.Builder#setProgress(int, int, boolean)} has no
  * real effect for Android < 4.0
- * 
- * @author David A. Velasco
  */
 public class NotificationBuilderWithProgressBar extends NotificationCompat.Builder {
 
index aeefe12..ab1399f 100644 (file)
@@ -1,3 +1,22 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 package com.owncloud.android.notifications;
 
 import java.util.Random;
index 4df8b3d..b020b92 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -17,6 +21,7 @@
 
 package com.owncloud.android.operations;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.resources.files.CreateRemoteFolderOperation;
@@ -31,9 +36,6 @@ import com.owncloud.android.utils.FileStorageUtils;
 /**
  * Access to remote operation performing the creation of a new folder in the ownCloud server.
  * Save the new folder in Database
- * 
- * @author David A. Velasco 
- * @author masensio
  */
 public class CreateFolderOperation extends SyncOperation implements OnRemoteOperationListener{
     
@@ -45,7 +47,8 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
     /**
      * Constructor
      * 
-     * @param createFullPath        'True' means that all the ancestor folders should be created if don't exist yet.
+     * @param createFullPath        'True' means that all the ancestor folders should be created
+     *                              if don't exist yet.
      */
     public CreateFolderOperation(String remotePath, boolean createFullPath) {
         mRemotePath = remotePath;
@@ -56,7 +59,8 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
 
     @Override
     protected RemoteOperationResult run(OwnCloudClient client) {
-        CreateRemoteFolderOperation operation = new CreateRemoteFolderOperation(mRemotePath, mCreateFullPath);
+        CreateRemoteFolderOperation operation = new CreateRemoteFolderOperation(mRemotePath,
+                mCreateFullPath);
         RemoteOperationResult result =  operation.execute(client);
         
         if (result.isSuccess()) {
@@ -76,7 +80,8 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
     }
     
     
-    private void onCreateRemoteFolderOperationFinish(CreateRemoteFolderOperation operation, RemoteOperationResult result) {
+    private void onCreateRemoteFolderOperationFinish(CreateRemoteFolderOperation operation,
+                                                     RemoteOperationResult result) {
        if (result.isSuccess()) {
            saveFolderInDB();
        } else {
index 6d9a253..63f7493 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -19,14 +22,12 @@ package com.owncloud.android.operations;
 
 /**
  * Creates a new share from a given file
- * 
- * @author masensio
- *
  */
 
 import android.content.Context;
 import android.content.Intent;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -44,7 +45,6 @@ import com.owncloud.android.operations.common.SyncOperation;
 public class CreateShareOperation extends SyncOperation {
 
     private static final String TAG = CreateShareOperation.class.getSimpleName();
-    
 
     protected FileDataStorageManager mStorageManager;
 
@@ -62,10 +62,13 @@ public class CreateShareOperation extends SyncOperation {
      * @param context       The context that the share is coming from.
      * @param path          Full path of the file/folder being shared. Mandatory argument
      * @param shareType     0 = user, 1 = group, 3 = Public link. Mandatory argument
-     * @param shareWith     User/group ID with who the file should be shared.  This is mandatory for shareType of 0 or 1
+     * @param shareWith     User/group ID with who the file should be shared.
+     *                      This is mandatory for shareType of 0 or 1
      * @param publicUpload  If false (default) public cannot upload to a public shared folder. 
-     *                      If true public can upload to a shared folder. Only available for public link shares
-     * @param password      Password to protect a public link share. Only available for public link shares
+     *                      If true public can upload to a shared folder.
+     *                      Only available for public link shares
+     * @param password      Password to protect a public link share.
+     *                      Only available for public link shares
      * @param permissions   1 - Read only - Default for public shares
      *                      2 - Update
      *                      4 - Create
@@ -76,8 +79,9 @@ public class CreateShareOperation extends SyncOperation {
      *                      To obtain combinations, add the desired values together.  
      *                      For instance, for Re-Share, delete, read, update, add 16+8+2+1 = 27.
      */
-    public CreateShareOperation(Context context, String path, ShareType shareType, String shareWith, boolean publicUpload,
-            String password, int permissions, Intent sendIntent) {
+    public CreateShareOperation(Context context, String path, ShareType shareType, String shareWith,
+                                boolean publicUpload, String password, int permissions,
+                                Intent sendIntent) {
 
         mContext = context;
         mPath = path;
@@ -95,10 +99,12 @@ public class CreateShareOperation extends SyncOperation {
         
         // Check if the share link already exists
         operation = new GetRemoteSharesForFileOperation(mPath, false, false);
-        RemoteOperationResult result = ((GetRemoteSharesForFileOperation)operation).execute(client);
+        RemoteOperationResult result =
+                ((GetRemoteSharesForFileOperation)operation).execute(client);
 
         if (!result.isSuccess() || result.getData().size() <= 0) {
-            operation = new CreateRemoteShareOperation(mPath, mShareType, mShareWith, mPublicUpload, mPassword, mPermissions);
+            operation = new CreateRemoteShareOperation(mPath, mShareType, mShareWith, mPublicUpload,
+                    mPassword, mPermissions);
             result = ((CreateRemoteShareOperation)operation).execute(client);
         }
         
@@ -112,7 +118,30 @@ public class CreateShareOperation extends SyncOperation {
         return result;
     }
     
-    
+    public String getPath() {
+        return mPath;
+    }
+
+    public ShareType getShareType() {
+        return mShareType;
+    }
+
+    public String getShareWith() {
+        return mShareWith;
+    }
+
+    public boolean getPublicUpload() {
+        return mPublicUpload;
+    }
+
+    public String getPassword() {
+        return mPassword;
+    }
+
+    public int getPermissions() {
+        return mPermissions;
+    }
+
     public Intent getSendIntent() {
         return mSendIntent;
     }
index 5afc421..4aeff99 100644 (file)
@@ -1,24 +1,20 @@
-/* ownCloud Android Library is available under MIT license
- *   Copyright (C) 2014 ownCloud Inc.
- *   
- *   Permission is hereby granted, free of charge, to any person obtaining a copy
- *   of this software and associated documentation files (the "Software"), to deal
- *   in the Software without restriction, including without limitation the rights
- *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- *   copies of the Software, and to permit persons to whom the Software is
- *   furnished to do so, subject to the following conditions:
- *   
- *   The above copyright notice and this permission notice shall be included in
- *   all copies or substantial portions of the Software.
- *   
- *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
- *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
- *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
- *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
- *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
- *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- *   THE SOFTWARE.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
@@ -26,6 +22,7 @@ package com.owncloud.android.operations;
 
 import java.util.ArrayList;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -47,9 +44,7 @@ import android.net.Uri;
  * When successful, the instance of {@link RemoteOperationResult} passed
  * through {@link OnRemoteOperationListener#onRemoteOperationFinish(RemoteOperation, 
  * RemoteOperationResult)} returns in {@link RemoteOperationResult#getData()}
- * a value of {@link AuthenticationMethod}. 
- * 
- * @author David A. Velasco
+ * a value of {@link AuthenticationMethod}.
  */
 public class DetectAuthenticationMethodOperation extends RemoteOperation {
     
@@ -69,7 +64,6 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation {
      * Constructor
      * 
      * @param context       Android context of the caller.
-     * @param webdavUrl
      */
     public DetectAuthenticationMethodOperation(Context context) {
         mContext = context;
@@ -130,7 +124,8 @@ public class DetectAuthenticationMethodOperation extends RemoteOperation {
         ArrayList<Object> data = new ArrayList<Object>();
         data.add(authMethod);
         result.setData(data);
-        return result;  // same result instance, so that other errors can be handled by the caller transparently
+        return result;  // same result instance, so that other errors
+                        // can be handled by the caller transparently
        }
        
        
index 0a5ff94..0cb303c 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -23,6 +27,7 @@ import java.util.Iterator;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.OwnCloudClient;
@@ -38,9 +43,6 @@ import android.webkit.MimeTypeMap;
 
 /**
  * Remote mDownloadOperation performing the download of a file to an ownCloud server
- * 
- * @author David A. Velasco
- * @author masensio
  */
 public class DownloadFileOperation extends RemoteOperation {
     
@@ -57,9 +59,11 @@ public class DownloadFileOperation extends RemoteOperation {
     
     public DownloadFileOperation(Account account, OCFile file) {
         if (account == null)
-            throw new IllegalArgumentException("Illegal null account in DownloadFileOperation creation");
+            throw new IllegalArgumentException("Illegal null account in DownloadFileOperation " +
+                    "creation");
         if (file == null)
-            throw new IllegalArgumentException("Illegal null file in DownloadFileOperation creation");
+            throw new IllegalArgumentException("Illegal null file in DownloadFileOperation " +
+                    "creation");
         
         mAccount = account;
         mFile = file;
@@ -76,7 +80,7 @@ public class DownloadFileOperation extends RemoteOperation {
     }
 
     public String getSavePath() {
-        String path = mFile.getStoragePath();   // re-downloads should be done over the original file 
+        String path = mFile.getStoragePath();  // re-downloads should be done over the original file
         if (path != null && path.length() > 0) {
             return path;
         }
@@ -101,9 +105,11 @@ public class DownloadFileOperation extends RemoteOperation {
             try {
                 mimeType = MimeTypeMap.getSingleton()
                     .getMimeTypeFromExtension(
-                            mFile.getRemotePath().substring(mFile.getRemotePath().lastIndexOf('.') + 1));
+                            mFile.getRemotePath().substring(
+                                    mFile.getRemotePath().lastIndexOf('.') + 1));
             } catch (IndexOutOfBoundsException e) {
-                Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " + mFile.getRemotePath());
+                Log_OC.e(TAG, "Trying to find out MIME type of a file without extension: " +
+                        mFile.getRemotePath());
             }
         }
         if (mimeType == null) {
@@ -117,7 +123,8 @@ public class DownloadFileOperation extends RemoteOperation {
     }
     
     public long getModificationTimestamp() {
-        return (mModificationTimestamp > 0) ? mModificationTimestamp : mFile.getModificationTimestamp();
+        return (mModificationTimestamp > 0) ? mModificationTimestamp :
+                mFile.getModificationTimestamp();
     }
 
     @Override
@@ -151,9 +158,11 @@ public class DownloadFileOperation extends RemoteOperation {
             newFile.getParentFile().mkdirs();
             moved = tmpFile.renameTo(newFile);
             if (!moved)
-                result = new RemoteOperationResult(RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED);
+                result = new RemoteOperationResult(
+                        RemoteOperationResult.ResultCode.LOCAL_STORAGE_NOT_MOVED);
         }
-        Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " + result.getLogMessage());
+        Log_OC.i(TAG, "Download of " + mFile.getRemotePath() + " to " + getSavePath() + ": " +
+                result.getLogMessage());
         
         return result;
     }
@@ -177,5 +186,4 @@ public class DownloadFileOperation extends RemoteOperation {
             mDataTransferListeners.remove(listener);
         }
     }
-    
 }
index 9b7cf87..8e91100 100644 (file)
@@ -1,24 +1,21 @@
-/* ownCloud Android Library is available under MIT license
- *   Copyright (C) 2014 ownCloud Inc.
- *   
- *   Permission is hereby granted, free of charge, to any person obtaining a copy
- *   of this software and associated documentation files (the "Software"), to deal
- *   in the Software without restriction, including without limitation the rights
- *   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- *   copies of the Software, and to permit persons to whom the Software is
- *   furnished to do so, subject to the following conditions:
- *   
- *   The above copyright notice and this permission notice shall be included in
- *   all copies or substantial portions of the Software.
- *   
- *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
- *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
- *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
- *   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
- *   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
- *   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- *   THE SOFTWARE.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
@@ -26,6 +23,7 @@ package com.owncloud.android.operations;
 
 import java.util.ArrayList;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -43,9 +41,6 @@ import android.content.Context;
  * 
  * Checks the existence of a configured ownCloud server in the URL, gets its version 
  * and finds out what authentication method is needed to access files in it.
- * 
- * @author David A. Velasco
- * @author masensio
  */
 
 public class GetServerInfoOperation extends RemoteOperation {
index 649437d..bf136ad 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -20,6 +23,7 @@ package com.owncloud.android.operations;
 
 import java.util.ArrayList;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -28,10 +32,7 @@ import com.owncloud.android.lib.resources.shares.GetRemoteSharesForFileOperation
 import com.owncloud.android.operations.common.SyncOperation;
 
 /**
- * Provide a list shares for a specific file.  
- * 
- * @author masensio
- *
+ * Provide a list shares for a specific file.
  */
 public class GetSharesForFileOperation extends SyncOperation {
     
@@ -58,7 +59,8 @@ public class GetSharesForFileOperation extends SyncOperation {
 
     @Override
     protected RemoteOperationResult run(OwnCloudClient client) {
-        GetRemoteSharesForFileOperation operation = new GetRemoteSharesForFileOperation(mPath, mReshares, mSubfiles);
+        GetRemoteSharesForFileOperation operation = new GetRemoteSharesForFileOperation(mPath,
+                mReshares, mSubfiles);
         RemoteOperationResult result = operation.execute(client);
 
         if (result.isSuccess()) {
index d096788..09a8e34 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -19,6 +23,7 @@ package com.owncloud.android.operations;
 
 import java.util.ArrayList;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
@@ -29,9 +34,6 @@ import com.owncloud.android.operations.common.SyncOperation;
 /**
  * Access to remote operation to get the share files/folders
  * Save the data in Database
- * 
- * @author masensio
- * @author David A. Velasco
  */
 
 public class GetSharesOperation extends SyncOperation {
index 63856c3..be254e7 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -17,6 +20,7 @@
 
 package com.owncloud.android.operations;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -29,8 +33,6 @@ import android.accounts.Account;
 
 /**
  * Operation mmoving an {@link OCFile} to a different folder.
- * 
- * @author David A. Velasco
  */
 public class MoveFileOperation extends SyncOperation {
     
@@ -46,8 +48,8 @@ public class MoveFileOperation extends SyncOperation {
     /**
      * Constructor
      * 
-     * @param path              Remote path of the {@link OCFile} to move.
-     * @param newParentPath     Path to the folder where the file will be moved into. 
+     * @param srcPath           Remote path of the {@link OCFile} to move.
+     * @param targetParentPath  Path to the folder where the file will be moved into.
      * @param account           OwnCloud account containing both the file and the target folder 
      */
     public MoveFileOperation(String srcPath, String targetParentPath, Account account) {
index 6f4ff74..918c57b 100644 (file)
@@ -1,3 +1,22 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 package com.owncloud.android.operations;
 
 import java.util.ArrayList;
index 5371789..50a35fd 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -36,6 +39,7 @@ import android.content.Intent;
 import android.util.Log;
 //import android.support.v4.content.LocalBroadcastManager;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 
@@ -64,8 +68,6 @@ import com.owncloud.android.utils.FileStorageUtils;
  *  properties, and updates the local database with them.
  *  
  *  Does NOT enter in the child folders to synchronize their contents also.
- * 
- *  @author David A. Velasco
  */
 public class RefreshFolderOperation extends RemoteOperation {
 
@@ -127,7 +129,7 @@ public class RefreshFolderOperation extends RemoteOperation {
      * @param   syncFullAccount         'True' means that this operation is part of a full account 
      *                                  synchronization.
      * @param   isShareSupported        'True' means that the server supports the sharing API.           
-     * @param   ignoreEtag              'True' means that the content of the remote folder should
+     * @param   ignoreETag              'True' means that the content of the remote folder should
      *                                  be fetched and updated even though the 'eTag' did not 
      *                                  change.  
      * @param   dataStorageManager      Interface with the local database.
@@ -374,7 +376,8 @@ public class RefreshFolderOperation extends RemoteOperation {
                     remoteFile.setFileLength(localFile.getFileLength()); 
                         // TODO move operations about size of folders to FileContentProvider
                 } else if (mRemoteFolderChanged && remoteFile.isImage() &&
-                        remoteFile.getModificationTimestamp() != localFile.getModificationTimestamp()) {
+                        remoteFile.getModificationTimestamp() !=
+                                localFile.getModificationTimestamp()) {
                     remoteFile.setNeedsUpdateThumbnail(true);
                     Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
                 }
index 6bd4e8a..012ef23 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -17,6 +21,7 @@
 
 package com.owncloud.android.operations;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -27,9 +32,6 @@ import com.owncloud.android.operations.common.SyncOperation;
 
 /**
  * Remote operation performing the removal of a remote file or folder in the ownCloud server.
- * 
- * @author David A. Velasco
- * @author masensio
  */
 public class RemoveFileOperation extends SyncOperation {
     
index aa98607..a4cfa02 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -20,6 +24,7 @@ package com.owncloud.android.operations;
 import java.io.File;
 import java.io.IOException;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -32,9 +37,6 @@ import com.owncloud.android.utils.FileStorageUtils;
 
 /**
  * Remote operation performing the rename of a remote file (or folder?) in the ownCloud server.
- * 
- * @author David A. Velasco
- * @author masensio
  */
 public class RenameFileOperation extends SyncOperation {
     
@@ -50,7 +52,8 @@ public class RenameFileOperation extends SyncOperation {
     /**
      * Constructor
      * 
-     * @param remotePath            RemotePath of the OCFile instance describing the remote file or folder to rename
+     * @param remotePath            RemotePath of the OCFile instance describing the remote file or
+     *                              folder to rename
      * @param newName               New name to set as the name of file.
      */
     public RenameFileOperation(String remotePath, String newName) {
@@ -81,7 +84,8 @@ public class RenameFileOperation extends SyncOperation {
                 return new RemoteOperationResult(ResultCode.INVALID_LOCAL_FILE_NAME);
             }
             String parent = (new File(mFile.getRemotePath())).getParent();
-            parent = (parent.endsWith(OCFile.PATH_SEPARATOR)) ? parent : parent + OCFile.PATH_SEPARATOR; 
+            parent = (parent.endsWith(OCFile.PATH_SEPARATOR)) ? parent : parent +
+                    OCFile.PATH_SEPARATOR;
             mNewRemotePath =  parent + mNewName;
             if (mFile.isFolder()) {
                 mNewRemotePath += OCFile.PATH_SEPARATOR;
@@ -92,7 +96,8 @@ public class RenameFileOperation extends SyncOperation {
                 return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
             }
             
-            RenameRemoteFileOperation operation = new RenameRemoteFileOperation(mFile.getFileName(), mFile.getRemotePath(), 
+            RenameRemoteFileOperation operation = new RenameRemoteFileOperation(mFile.getFileName(),
+                    mFile.getRemotePath(),
                     mNewName, mFile.isFolder());
             result = operation.execute(client);
 
@@ -107,7 +112,8 @@ public class RenameFileOperation extends SyncOperation {
             }
             
         } catch (IOException e) {
-            Log_OC.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((mNewRemotePath==null) ? mNewName : mNewRemotePath) + ": " + 
+            Log_OC.e(TAG, "Rename " + mFile.getRemotePath() + " to " + ((mNewRemotePath==null) ?
+                    mNewName : mNewRemotePath) + ": " +
                     ((result!= null) ? result.getLogMessage() : ""), e);
         }
 
@@ -133,7 +139,8 @@ public class RenameFileOperation extends SyncOperation {
                 // notify to scan about new file
                 getStorageManager().triggerMediaScan(newPath);
             }
-            // else - NOTHING: the link to the local file is kept although the local name can't be updated
+            // else - NOTHING: the link to the local file is kept although the local name
+            // can't be updated
             // TODO - study conditions when this could be a problem
         }
         
@@ -143,16 +150,17 @@ public class RenameFileOperation extends SyncOperation {
     /**
      * Checks if the new name to set is valid in the file system 
      * 
-     * The only way to be sure is trying to create a file with that name. It's made in the temporal directory
-     * for downloads, out of any account, and then removed. 
+     * The only way to be sure is trying to create a file with that name. It's made in the
+     * temporal directory for downloads, out of any account, and then removed.
      * 
-     * IMPORTANT: The test must be made in the same file system where files are download. The internal storage
-     * could be formatted with a different file system.
+     * IMPORTANT: The test must be made in the same file system where files are download.
+     * The internal storage could be formatted with a different file system.
      * 
-     * TODO move this method, and maybe FileDownload.get***Path(), to a class with utilities specific for the interactions with the file system
+     * TODO move this method, and maybe FileDownload.get***Path(), to a class with utilities
+     * specific for the interactions with the file system
      * 
-     * @return              'True' if a temporal file named with the name to set could be created in the file system where 
-     *                      local files are stored.
+     * @return              'True' if a temporal file named with the name to set could be
+     *                      created in the file system where local files are stored.
      * @throws IOException  When the temporal folder can not be created.
      */
     private boolean isValidNewName() throws IOException {
@@ -169,14 +177,16 @@ public class RenameFileOperation extends SyncOperation {
             throw new IOException("Unexpected error: temporal directory could not be created");
         }
         try {
-            testFile.createNewFile();   // return value is ignored; it could be 'false' because the file already existed, that doesn't invalidate the name
+            testFile.createNewFile();   // return value is ignored; it could be 'false' because
+            // the file already existed, that doesn't invalidate the name
         } catch (IOException e) {
             Log_OC.i(TAG, "Test for validity of name " + mNewName + " in the file system failed");
             return false;
         }
         boolean result = (testFile.exists() && testFile.isFile());
         
-        // cleaning ; result is ignored, since there is not much we could do in case of failure, but repeat and repeat...
+        // cleaning ; result is ignored, since there is not much we could do in case of failure,
+        // but repeat and repeat...
         testFile.delete();
         
         return result;
index 72cb22b..27b0b5a 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   @author masensio
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -18,6 +22,7 @@
 
 package com.owncloud.android.operations;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileUploader;
@@ -36,9 +41,6 @@ import android.content.Intent;
 
 /**
  * Remote operation performing the read of remote file in the ownCloud server.
- * 
- * @author David A. Velasco
- * @author masensio
  */
 
 public class SynchronizeFileOperation extends SyncOperation {
@@ -65,8 +67,8 @@ public class SynchronizeFileOperation extends SyncOperation {
     /**
      * Constructor for "full synchronization mode".
      * 
-     * Uses remotePath to retrieve all the data both in local cache and in the remote OC server when the operation
-     * is executed, instead of reusing {@link OCFile} instances.
+     * Uses remotePath to retrieve all the data both in local cache and in the remote OC server
+     * when the operation is executed, instead of reusing {@link OCFile} instances.
      * 
      * Useful for direct synchronization of a single file.
      * 
@@ -93,17 +95,19 @@ public class SynchronizeFileOperation extends SyncOperation {
 
     
     /**
-     * Constructor allowing to reuse {@link OCFile} instances just queried from local cache or from remote OC server.
+     * Constructor allowing to reuse {@link OCFile} instances just queried from local cache or
+     * from remote OC server.
      * 
-     * Useful to include this operation as part of the synchronization of a folder (or a full account), avoiding the
-     * repetition of fetch operations (both in local database or remote server).
+     * Useful to include this operation as part of the synchronization of a folder
+     * (or a full account), avoiding the repetition of fetch operations (both in local database
+     * or remote server).
      * 
-     * At least one of localFile or serverFile MUST NOT BE NULL. If you don't have none of them, use the other 
-     * constructor.
+     * At least one of localFile or serverFile MUST NOT BE NULL. If you don't have none of them,
+     * use the other constructor.
      * 
      * @param localFile             Data of file (just) retrieved from local cache/database.
-     * @param serverFile            Data of file (just) retrieved from a remote server. If null, will be
-     *                              retrieved from network by the operation when executed.
+     * @param serverFile            Data of file (just) retrieved from a remote server. If null,
+     *                              will be retrieved from network by the operation when executed.
      * @param account               ownCloud account holding the file.
      * @param syncFileContents      When 'true', transference of data will be started by the 
      *                              operation if needed and no conflict is detected.
@@ -121,7 +125,8 @@ public class SynchronizeFileOperation extends SyncOperation {
         if (mLocalFile != null) {
             mRemotePath = mLocalFile.getRemotePath();
             if (mServerFile != null && !mServerFile.getRemotePath().equals(mRemotePath)) {
-                throw new IllegalArgumentException("serverFile and localFile do not correspond to the same OC file");
+                throw new IllegalArgumentException("serverFile and localFile do not correspond" +
+                        " to the same OC file");
             }
         } else if (mServerFile != null) {
             mRemotePath = mServerFile.getRemotePath();
@@ -138,21 +143,24 @@ public class SynchronizeFileOperation extends SyncOperation {
     /**
      * Temporal constructor.
      * 
-     * Extends the previous one to allow constrained synchronizations where uploads are never performed - only
-     * downloads or conflict detection.
+     * Extends the previous one to allow constrained synchronizations where uploads are never
+     * performed - only downloads or conflict detection.
      * 
-     * Do not use unless you are involved in 'folder synchronization' or 'folder download' work in progress.
+     * Do not use unless you are involved in 'folder synchronization' or 'folder download' work
+     * in progress.
      * 
      * TODO Remove when 'folder synchronization' replaces 'folder download'.
      * 
-     * @param localFile             Data of file (just) retrieved from local cache/database. MUSTN't be null.
-     * @param serverFile            Data of file (just) retrieved from a remote server. If null, will be
-     *                              retrieved from network by the operation when executed.
+     * @param localFile             Data of file (just) retrieved from local cache/database.
+     *                              MUSTN't be null.
+     * @param serverFile            Data of file (just) retrieved from a remote server.
+     *                              If null, will be retrieved from network by the operation
+     *                              when executed.
      * @param account               ownCloud account holding the file.
      * @param syncFileContents      When 'true', transference of data will be started by the 
      *                              operation if needed and no conflict is detected.
-     * @param allowUploads          When 'false', uploads to the server are not done; only downloads or conflict
-     *                              detection. 
+     * @param allowUploads          When 'false', uploads to the server are not done;
+     *                              only downloads or conflict detection.
      * @param context               Android context; needed to start transfers.
      */
     public SynchronizeFileOperation(
@@ -205,7 +213,8 @@ public class SynchronizeFileOperation extends SyncOperation {
                         serverChanged = (!mServerFile.getEtag().equals(mLocalFile.getEtag()));
                     } else { */
                 serverChanged = (
-                    mServerFile.getModificationTimestamp() != mLocalFile.getModificationTimestampAtLastSyncForData()
+                    mServerFile.getModificationTimestamp() !=
+                            mLocalFile.getModificationTimestampAtLastSyncForData()
                 );
                 //}
                 boolean localChanged = (
@@ -220,10 +229,13 @@ public class SynchronizeFileOperation extends SyncOperation {
                 } else if (localChanged) {
                     if (mSyncFileContents && mAllowUploads) {
                         requestForUpload(mLocalFile);
-                        // the local update of file properties will be done by the FileUploader service when the upload finishes
+                        // the local update of file properties will be done by the FileUploader
+                        // service when the upload finishes
                     } else {
-                        // NOTHING TO DO HERE: updating the properties of the file in the server without uploading the contents would be stupid; 
-                        // So, an instance of SynchronizeFileOperation created with syncFileContents == false is completely useless when we suspect
+                        // NOTHING TO DO HERE: updating the properties of the file in the server
+                        // without uploading the contents would be stupid;
+                        // So, an instance of SynchronizeFileOperation created with
+                        // syncFileContents == false is completely useless when we suspect
                         // that an upload is necessary (for instance, in FileObserverService).
                     }
                     result = new RemoteOperationResult(ResultCode.OK);
@@ -232,8 +244,10 @@ public class SynchronizeFileOperation extends SyncOperation {
                     mLocalFile.setRemoteId(mServerFile.getRemoteId());
                     
                     if (mSyncFileContents) {
-                        requestForDownload(mLocalFile); // local, not server; we won't to keep the value of keepInSync!
-                        // the update of local data will be done later by the FileUploader service when the upload finishes
+                        requestForDownload(mLocalFile); // local, not server; we won't to keep
+                        // the value of keepInSync!
+                        // the update of local data will be done later by the FileUploader
+                        // service when the upload finishes
                     } else {
                         // TODO CHECK: is this really useful in some point in the code?
                         mServerFile.setKeepInSync(mLocalFile.keepInSync());
@@ -254,8 +268,8 @@ public class SynchronizeFileOperation extends SyncOperation {
 
         }
 
-        Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() + ": " 
-                + result.getLogMessage());
+        Log_OC.i(TAG, "Synchronizing " + mAccount.name + ", file " + mLocalFile.getRemotePath() +
+                ": " + result.getLogMessage());
 
         return result;
     }
@@ -270,7 +284,9 @@ public class SynchronizeFileOperation extends SyncOperation {
         Intent i = new Intent(mContext, FileUploader.class);
         i.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
         i.putExtra(FileUploader.KEY_FILE, file);
-        /*i.putExtra(FileUploader.KEY_REMOTE_FILE, mRemotePath);    // doing this we would lose the value of keepInSync in the road, and maybe it's not updated in the database when the FileUploader service gets it!  
+        /*i.putExtra(FileUploader.KEY_REMOTE_FILE, mRemotePath);
+        // doing this we would lose the value of keepInSync in the road, and maybe
+        // it's not updated in the database when the FileUploader service gets it!
         i.putExtra(FileUploader.KEY_LOCAL_FILE, localFile.getStoragePath());*/
         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
         i.putExtra(FileUploader.KEY_FORCE_OVERWRITE, true);
index 06760e8..286b5ea 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -22,6 +25,7 @@ import android.content.Context;
 import android.content.Intent;
 import android.util.Log;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
@@ -56,8 +60,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
  *  properties, and updates the local database with them.
  *  
  *  Does NOT enter in the child folders to synchronize their contents also.
- * 
- *  @author David A. Velasco
  */
 public class SynchronizeFolderOperation extends SyncOperation {
 
@@ -109,7 +111,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
      * @param   account                 ownCloud account where the folder is located.
      * @param   currentSyncTime         Time stamp for the synchronization process in progress.
      */
-    public SynchronizeFolderOperation(Context context, String remotePath, Account account, long currentSyncTime){
+    public SynchronizeFolderOperation(Context context, String remotePath, Account account,
+                                      long currentSyncTime){
         mRemotePath = remotePath;
         mCurrentSyncTime = currentSyncTime;
         mAccount = account;
@@ -173,7 +176,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
 
     }
 
-    private RemoteOperationResult checkForChanges(OwnCloudClient client) throws OperationCancelledException {
+    private RemoteOperationResult checkForChanges(OwnCloudClient client)
+            throws OperationCancelledException {
         Log_OC.d(TAG, "Checking changes in " + mAccount.name + mRemotePath);
 
         mRemoteFolderChanged = true;
@@ -217,7 +221,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
     }
 
 
-    private RemoteOperationResult fetchAndSyncRemoteFolder(OwnCloudClient client) throws OperationCancelledException {
+    private RemoteOperationResult fetchAndSyncRemoteFolder(OwnCloudClient client)
+            throws OperationCancelledException {
         if (mCancellationRequested.get()) {
             throw new OperationCancelledException();
         }
@@ -249,7 +254,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
             storageManager.removeFolder(
                     mLocalFolder,
                     true,
-                    (   mLocalFolder.isDown() &&        // TODO: debug, I think this is always false for folders
+                    (   mLocalFolder.isDown() &&        // TODO: debug, I think this is
+                                                        // always false for folders
                             mLocalFolder.getStoragePath().startsWith(currentSavePath)
                     )
             );
@@ -326,7 +332,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
                     remoteFile.setFileLength(localFile.getFileLength());
                         // TODO move operations about size of folders to FileContentProvider
                 } else if (mRemoteFolderChanged && remoteFile.isImage() &&
-                        remoteFile.getModificationTimestamp() != localFile.getModificationTimestamp()) {
+                        remoteFile.getModificationTimestamp() !=
+                                localFile.getModificationTimestamp()) {
                     remoteFile.setNeedsUpdateThumbnail(true);
                     Log.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
                 }
@@ -438,7 +445,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
      * @param filesToSyncContents       Synchronization operations to execute.
      * @param client                    Interface to the remote ownCloud server.
      */
-    private void startContentSynchronizations(List<SyncOperation> filesToSyncContents, OwnCloudClient client) 
+    private void startContentSynchronizations(List<SyncOperation> filesToSyncContents,
+                                              OwnCloudClient client)
             throws OperationCancelledException {
 
         Log_OC.v(TAG, "Starting content synchronization... ");
@@ -468,7 +476,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
 
     
     /**
-     * Creates and populates a new {@link com.owncloud.android.datamodel.OCFile} object with the data read from the server.
+     * Creates and populates a new {@link com.owncloud.android.datamodel.OCFile}
+     * object with the data read from the server.
      *
      * @param remote    remote file read from the server (remote file or folder).
      * @return          New OCFile instance representing the remote resource described by we.
@@ -488,8 +497,8 @@ public class SynchronizeFolderOperation extends SyncOperation {
 
     /**
      * Scans the default location for saving local copies of files searching for
-     * a 'lost' file with the same full name as the {@link com.owncloud.android.datamodel.OCFile} received as
-     * parameter.
+     * a 'lost' file with the same full name as the {@link com.owncloud.android.datamodel.OCFile}
+     * received as parameter.
      *  
      * @param file      File to associate a possible 'lost' local file.
      */
index c08c8e5..1b66226 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -19,6 +22,7 @@ package com.owncloud.android.operations;
 
 import android.content.Context;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.OCFile;
 
 import com.owncloud.android.lib.common.OwnCloudClient;
@@ -35,8 +39,6 @@ import com.owncloud.android.operations.common.SyncOperation;
 /**
  * Unshare file/folder
  * Save the data in Database
- * 
- * @author masensio
  */
 public class UnshareLinkOperation extends SyncOperation {
 
@@ -56,10 +58,12 @@ public class UnshareLinkOperation extends SyncOperation {
         RemoteOperationResult result  = null;
         
         // Get Share for a file
-        OCShare share = getStorageManager().getFirstShareByPathAndType(mRemotePath, ShareType.PUBLIC_LINK);
+        OCShare share = getStorageManager().getFirstShareByPathAndType(mRemotePath,
+                ShareType.PUBLIC_LINK);
         
         if (share != null) {
-            RemoveRemoteShareOperation operation = new RemoveRemoteShareOperation((int) share.getIdRemoteShared());
+            RemoveRemoteShareOperation operation =
+                    new RemoveRemoteShareOperation((int) share.getIdRemoteShared());
             result = operation.execute(client);
 
             if (result.isSuccess() || result.getCode() == ResultCode.SHARE_NOT_FOUND) {
@@ -88,7 +92,8 @@ public class UnshareLinkOperation extends SyncOperation {
     }
     
     private boolean existsFile(OwnCloudClient client, String remotePath){
-        ExistenceCheckRemoteOperation existsOperation = new ExistenceCheckRemoteOperation(remotePath, mContext, false);
+        ExistenceCheckRemoteOperation existsOperation =
+                new ExistenceCheckRemoteOperation(remotePath, mContext, false);
         RemoteOperationResult result = existsOperation.execute(client);
         return result.isSuccess();
     }
index ac73d96..d2bf5f3 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -38,8 +41,6 @@ import android.content.Context;
 
 /**
  * Remote operation that checks the version of an ownCloud server and stores it locally
- * 
- * @author David A. Velasco
  */
 public class UpdateOCVersionOperation extends RemoteOperation {
 
index 1536a60..b114195 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -55,8 +58,6 @@ import com.owncloud.android.utils.UriUtils;
 
 /**
  * Remote operation performing the upload of a file to an ownCloud server
- * 
- * @author David A. Velasco
  */
 public class UploadFileOperation extends RemoteOperation {
 
@@ -76,7 +77,7 @@ public class UploadFileOperation extends RemoteOperation {
     private String mOriginalStoragePath = null;
     PutMethod mPutMethod = null;
     private Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
-    private final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
+    private AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
     private Context mContext;
     
     private UploadRemoteFileOperation mUploadOperation;
@@ -92,7 +93,8 @@ public class UploadFileOperation extends RemoteOperation {
                                 int localBehaviour, 
                                 Context context) {
         if (account == null)
-            throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation");
+            throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation " +
+                    "creation");
         if (file == null)
             throw new IllegalArgumentException("Illegal NULL file in UploadFileOperation creation");
         if (file.getStoragePath() == null || file.getStoragePath().length() <= 0) {
@@ -212,7 +214,8 @@ public class UploadFileOperation extends RemoteOperation {
 
             // check location of local file; if not the expected, copy to a
             // temporal file before upload (if COPY is the expected behaviour)
-            if (!mOriginalStoragePath.equals(expectedPath) && mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY) {
+            if (!mOriginalStoragePath.equals(expectedPath) &&
+                    mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY) {
 
                 if (FileStorageUtils.getUsableSpace(mAccount.name) < originalFile.length()) {
                     result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_FULL);
@@ -221,7 +224,8 @@ public class UploadFileOperation extends RemoteOperation {
 
                 } else {
 
-                    String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
+                    String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) +
+                            mFile.getRemotePath();
                     mFile.setStoragePath(temporalPath);
                     temporalFile = new File(temporalPath);
 
@@ -251,10 +255,10 @@ public class UploadFileOperation extends RemoteOperation {
                             int nRead;
                             byte[] data = new byte[16384];
 
-                            while ((nRead = in.read(data, 0, data.length)) != -1) {
+                            while (!mCancellationRequested.get() &&
+                                    (nRead = in.read(data, 0, data.length)) != -1) {
                                 out.write(data, 0, nRead);
                             }
-
                             out.flush();
 
                         } else {
@@ -268,12 +272,17 @@ public class UploadFileOperation extends RemoteOperation {
                                 out = new FileOutputStream(temporalFile);
                                 byte[] buf = new byte[1024];
                                 int len;
-                                while ((len = in.read(buf)) > 0) {
+                                while (!mCancellationRequested.get() && (len = in.read(buf)) > 0) {
                                     out.write(buf, 0, len);
                                 }
                             }
                         }
 
+                        if (mCancellationRequested.get()) {
+                            result = new RemoteOperationResult(new OperationCancelledException());
+                        }
+
+
                     } catch (Exception e) {
                         result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_COPIED);
                         return result;
@@ -283,63 +292,69 @@ public class UploadFileOperation extends RemoteOperation {
                             if (in != null)
                                 in.close();
                         } catch (Exception e) {
-                            Log_OC.d(TAG, "Weird exception while closing input stream for " + mOriginalStoragePath + " (ignoring)", e);
+                            Log_OC.d(TAG, "Weird exception while closing input stream for " +
+                                    mOriginalStoragePath + " (ignoring)", e);
                         }
                         try {
                             if (out != null)
                                 out.close();
                         } catch (Exception e) {
-                            Log_OC.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
+                            Log_OC.d(TAG, "Weird exception while closing output stream for " +
+                                    expectedPath + " (ignoring)", e);
                         }
                     }
                 }
             }
-            localCopyPassed = true;
+            localCopyPassed = (result == null);
 
             /// perform the upload
-            if ( mChunked && (new File(mFile.getStoragePath())).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) {
-                mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), 
-                        mFile.getMimetype());
+            if ( mChunked &&
+                    (new File(mFile.getStoragePath())).length() >
+                            ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) {
+                mUploadOperation = new ChunkedUploadRemoteFileOperation(mFile.getStoragePath(),
+                        mFile.getRemotePath(), mFile.getMimetype());
             } else {
-                mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(), mFile.getRemotePath(), 
-                        mFile.getMimetype());
+                mUploadOperation = new UploadRemoteFileOperation(mFile.getStoragePath(),
+                        mFile.getRemotePath(), mFile.getMimetype());
             }
             Iterator <OnDatatransferProgressListener> listener = mDataTransferListeners.iterator();
             while (listener.hasNext()) {
                 mUploadOperation.addDatatransferProgressListener(listener.next());
             }
-            result = mUploadOperation.execute(client);
-
-            /// move local temporal file or original file to its corresponding
-            // location in the ownCloud local folder
-            if (result.isSuccess()) {
-                if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
-                    mFile.setStoragePath(null);
-
-                } else {
-                    mFile.setStoragePath(expectedPath);
-                    File fileToMove = null;
-                    if (temporalFile != null) { // FileUploader.LOCAL_BEHAVIOUR_COPY
-                                                // ; see where temporalFile was
-                                                // set
-                        fileToMove = temporalFile;
-                    } else { // FileUploader.LOCAL_BEHAVIOUR_MOVE
-                        fileToMove = originalFile;
-                    }
-                    if (!expectedFile.equals(fileToMove)) {
-                        File expectedFolder = expectedFile.getParentFile();
-                        expectedFolder.mkdirs();
-                        if (!expectedFolder.isDirectory() || !fileToMove.renameTo(expectedFile)) {
-                            mFile.setStoragePath(null); // forget the local file
-                            // by now, treat this as a success; the file was
-                            // uploaded; the user won't like that the local file
-                            // is not linked, but this should be a very rare
-                            // fail;
-                            // the best option could be show a warning message
-                            // (but not a fail)
-                            // result = new
-                            // RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED);
-                            // return result;
+            if (!mCancellationRequested.get()) {
+                result = mUploadOperation.execute(client);
+
+                /// move local temporal file or original file to its corresponding
+                // location in the ownCloud local folder
+                if (result.isSuccess()) {
+                    if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
+                        mFile.setStoragePath(null);
+
+                    } else {
+                        mFile.setStoragePath(expectedPath);
+                        File fileToMove = null;
+                        if (temporalFile != null) { // FileUploader.LOCAL_BEHAVIOUR_COPY
+                            // ; see where temporalFile was
+                            // set
+                            fileToMove = temporalFile;
+                        } else { // FileUploader.LOCAL_BEHAVIOUR_MOVE
+                            fileToMove = originalFile;
+                        }
+                        if (!expectedFile.equals(fileToMove)) {
+                            File expectedFolder = expectedFile.getParentFile();
+                            expectedFolder.mkdirs();
+                            if (!expectedFolder.isDirectory() || !fileToMove.renameTo(expectedFile)) {
+                                mFile.setStoragePath(null); // forget the local file
+                                // by now, treat this as a success; the file was
+                                // uploaded; the user won't like that the local file
+                                // is not linked, but this should be a very rare
+                                // fail;
+                                // the best option could be show a warning message
+                                // (but not a fail)
+                                // result = new
+                                // RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_MOVED);
+                                // return result;
+                            }
                         }
                     }
                 }
@@ -358,19 +373,23 @@ public class UploadFileOperation extends RemoteOperation {
                 temporalFile.delete();
             }
             if (result.isSuccess()) {
-                Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
+                Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " +
+                        result.getLogMessage());
             } else {
                 if (result.getException() != null) {
                     String complement = "";
                     if (!nameCheckPassed) {
                         complement = " (while checking file existence in server)";
                     } else if (!localCopyPassed) {
-                        complement = " (while copying local file to " + FileStorageUtils.getSavePath(mAccount.name)
+                        complement = " (while copying local file to " +
+                                FileStorageUtils.getSavePath(mAccount.name)
                                 + ")";
                     }
-                    Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage() + complement, result.getException());
+                    Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
+                            ": " + result.getLogMessage() + complement, result.getException());
                 } else {
-                    Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
+                    Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath +
+                            ": " + result.getLogMessage());
                 }
             }
         }
@@ -385,7 +404,8 @@ public class UploadFileOperation extends RemoteOperation {
         newFile.setFileLength(mFile.getFileLength());
         newFile.setMimetype(mFile.getMimetype());
         newFile.setModificationTimestamp(mFile.getModificationTimestamp());
-        newFile.setModificationTimestampAtLastSyncForData(mFile.getModificationTimestampAtLastSyncForData());
+        newFile.setModificationTimestampAtLastSyncForData(
+                mFile.getModificationTimestampAtLastSyncForData());
         // newFile.setEtag(mFile.getEtag())
         newFile.setKeepInSync(mFile.keepInSync());
         newFile.setLastSyncDateForProperties(mFile.getLastSyncDateForProperties());
@@ -400,7 +420,8 @@ public class UploadFileOperation extends RemoteOperation {
      * Checks if remotePath does not exist in the server and returns it, or adds
      * a suffix to it in order to avoid the server file is overwritten.
      * 
-     * @param string
+     * @param wc
+     * @param remotePath
      * @return
      */
     private String getAvailableRemotePath(OwnCloudClient wc, String remotePath) throws Exception {
@@ -436,12 +457,16 @@ public class UploadFileOperation extends RemoteOperation {
     }
 
     private boolean existsFile(OwnCloudClient client, String remotePath){
-        ExistenceCheckRemoteOperation existsOperation = new ExistenceCheckRemoteOperation(remotePath, mContext, false);
+        ExistenceCheckRemoteOperation existsOperation =
+                new ExistenceCheckRemoteOperation(remotePath, mContext, false);
         RemoteOperationResult result = existsOperation.execute(client);
         return result.isSuccess();
     }
     
     public void cancel() {
-        mUploadOperation.cancel();
+        mCancellationRequested = new AtomicBoolean(true);
+        if (mUploadOperation != null) {
+            mUploadOperation.cancel();
+        }
     }
 }
index 8c5678b..5fb5c8c 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -17,6 +20,7 @@
 
 package com.owncloud.android.operations.common;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
@@ -32,8 +36,6 @@ import android.os.Handler;
  * with local data in the device.
  * 
  * Provides methods to execute the operation both synchronously or asynchronously.
- * 
- * @author David A. Velasco 
  */
 public abstract class SyncOperation extends RemoteOperation {
        
@@ -51,18 +53,21 @@ public abstract class SyncOperation extends RemoteOperation {
      * 
      * Do not call this method from the main thread.
      * 
-     * This method should be used whenever an ownCloud account is available, instead of {@link #execute(OwnCloudClient)}. 
+     * This method should be used whenever an ownCloud account is available, instead of
+     * {@link #execute(OwnCloudClient, com.owncloud.android.datamodel.FileDataStorageManager)}.
      * 
-     * @param account   ownCloud account in remote ownCloud server to reach during the execution of the operation.
+     * @param storageManager
      * @param context   Android context for the component calling the method.
      * @return          Result of the operation.
      */
     public RemoteOperationResult execute(FileDataStorageManager storageManager, Context context) {
         if (storageManager == null) {
-            throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+            throw new IllegalArgumentException("Trying to execute a sync operation with a " +
+                    "NULL storage manager");
         }
         if (storageManager.getAccount() == null) {
-            throw new IllegalArgumentException("Trying to execute a sync operation with a storage manager for a NULL account");
+            throw new IllegalArgumentException("Trying to execute a sync operation with a " +
+                    "storage manager for a NULL account");
         }
         mStorageManager = storageManager;
         return super.execute(mStorageManager.getAccount(), context);
@@ -74,12 +79,16 @@ public abstract class SyncOperation extends RemoteOperation {
         * 
      * Do not call this method from the main thread.
      * 
-        * @param client        Client object to reach an ownCloud server during the execution of the operation.
+        * @param client        Client object to reach an ownCloud server during the execution of the o
+     *                  peration.
+     * @param storageManager
         * @return                      Result of the operation.
         */
-       public RemoteOperationResult execute(OwnCloudClient client, FileDataStorageManager storageManager) {
+       public RemoteOperationResult execute(OwnCloudClient client,
+                                         FileDataStorageManager storageManager) {
         if (storageManager == null)
-            throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+            throw new IllegalArgumentException("Trying to execute a sync operation with a " +
+                    "NULL storage manager");
         mStorageManager = storageManager;
                return super.execute(client);
        }
@@ -88,24 +97,31 @@ public abstract class SyncOperation extends RemoteOperation {
     /**
      * Asynchronously executes the remote operation
      * 
-     * This method should be used whenever an ownCloud account is available, instead of {@link #execute(OwnCloudClient)}. 
+     * This method should be used whenever an ownCloud account is available, instead of
+     * {@link #execute(OwnCloudClient)}.
      * 
-     * @param account           ownCloud account in remote ownCloud server to reach during the execution of the operation.
+     * @param account           ownCloud account in remote ownCloud server to reach during the
+     *                          execution of the operation.
      * @param context           Android context for the component calling the method.
      * @param listener          Listener to be notified about the execution of the operation.
-     * @param listenerHandler   Handler associated to the thread where the methods of the listener objects must be called.
+     * @param listenerHandler   Handler associated to the thread where the methods of the listener
+     *                          objects must be called.
      * @return                  Thread were the remote operation is executed.
      */
        /*
-    public Thread execute(FileDataStorageManager storageManager, Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) {
+    public Thread execute(FileDataStorageManager storageManager,
+    Context context, OnRemoteOperationListener listener, Handler listenerHandler, Activity callerActivity) {
         if (storageManager == null) {
-            throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+            throw new IllegalArgumentException("Trying to execute a sync operation
+             with a NULL storage manager");
         }
         if (storageManager.getAccount() == null) {
-            throw new IllegalArgumentException("Trying to execute a sync operation with a storage manager for a NULL account");
+            throw new IllegalArgumentException("Trying to execute a sync operation with a
+             storage manager for a NULL account");
         }
         mStorageManager = storageManager;
-        return super.execute(storageManager.getAccount(), context, listener, listenerHandler, callerActivity);
+        return super.execute(storageManager.getAccount(), context, listener, listenerHandler,
+         callerActivity);
     }
     */
 
@@ -113,14 +129,18 @@ public abstract class SyncOperation extends RemoteOperation {
        /**
         * Asynchronously executes the remote operation
         * 
-        * @param client                        Client object to reach an ownCloud server during the execution of the operation.
+        * @param client                        Client object to reach an ownCloud server during the
+     *                          execution of the operation.
         * @param listener                      Listener to be notified about the execution of the operation.
-        * @param listenerHandler       Handler associated to the thread where the methods of the listener objects must be called.
+        * @param listenerHandler       Handler associated to the thread where the methods of
+     *                          the listener objects must be called.
         * @return                                      Thread were the remote operation is executed.
         */
-       public Thread execute(OwnCloudClient client, FileDataStorageManager storageManager, OnRemoteOperationListener listener, Handler listenerHandler) {
+       public Thread execute(OwnCloudClient client, FileDataStorageManager storageManager,
+                          OnRemoteOperationListener listener, Handler listenerHandler) {
         if (storageManager == null) {
-            throw new IllegalArgumentException("Trying to execute a sync operation with a NULL storage manager");
+            throw new IllegalArgumentException("Trying to execute a sync operation " +
+                    "with a NULL storage manager");
         }
         mStorageManager = storageManager;
         return super.execute(client, listener, listenerHandler);
index 4ea4812..737c664 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -45,10 +49,6 @@ import android.text.TextUtils;
 
 /**
  * The ContentProvider for the ownCloud App.
- * 
- * @author Bartek Przybylski
- * @author David A. Velasco
- * 
  */
 public class FileContentProvider extends ContentProvider {
 
index 581a686..fcaf0c7 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -37,7 +39,6 @@ import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.users.GetRemoteUserNameOperation;
 import com.owncloud.android.operations.common.SyncOperation;
@@ -84,30 +85,26 @@ public class OperationsService extends Service {
     public static final String EXTRA_RESULT = "RESULT";
     public static final String EXTRA_NEW_PARENT_PATH = "NEW_PARENT_PATH";
     public static final String EXTRA_FILE = "FILE";
+    public static final String EXTRA_PASSWORD_SHARE = "PASSWORD_SHARE";
 
-    // TODO review if ALL OF THEM are necessary
-    public static final String EXTRA_SUCCESS_IF_ABSENT = "SUCCESS_IF_ABSENT";
-    public static final String EXTRA_USERNAME = "USERNAME";
-    public static final String EXTRA_PASSWORD = "PASSWORD";
-    public static final String EXTRA_AUTH_TOKEN = "AUTH_TOKEN";
     public static final String EXTRA_COOKIE = "COOKIE";
     
     public static final String ACTION_CREATE_SHARE = "CREATE_SHARE";
     public static final String ACTION_UNSHARE = "UNSHARE";
     public static final String ACTION_GET_SERVER_INFO = "GET_SERVER_INFO";
     public static final String ACTION_OAUTH2_GET_ACCESS_TOKEN = "OAUTH2_GET_ACCESS_TOKEN";
-    public static final String ACTION_EXISTENCE_CHECK = "EXISTENCE_CHECK";
     public static final String ACTION_GET_USER_NAME = "GET_USER_NAME";
     public static final String ACTION_RENAME = "RENAME";
     public static final String ACTION_REMOVE = "REMOVE";
     public static final String ACTION_CREATE_FOLDER = "CREATE_FOLDER";
     public static final String ACTION_SYNC_FILE = "SYNC_FILE";
-    public static final String ACTION_SYNC_FOLDER = "SYNC_FOLDER";  // for the moment, just to download
-    //public static final String ACTION_CANCEL_SYNC_FOLDER = "CANCEL_SYNC_FOLDER";  // for the moment, just to download
+    public static final String ACTION_SYNC_FOLDER = "SYNC_FOLDER";//for the moment, just to download
     public static final String ACTION_MOVE_FILE = "MOVE_FILE";
     
-    public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() + ".OPERATION_ADDED";
-    public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() + ".OPERATION_FINISHED";
+    public static final String ACTION_OPERATION_ADDED = OperationsService.class.getName() +
+            ".OPERATION_ADDED";
+    public static final String ACTION_OPERATION_FINISHED = OperationsService.class.getName() +
+            ".OPERATION_FINISHED";
 
 
     private ConcurrentMap<Integer, Pair<RemoteOperation, RemoteOperationResult>> 
@@ -117,18 +114,11 @@ public class OperationsService extends Service {
     private static class Target {
         public Uri mServerUrl = null;
         public Account mAccount = null;
-        public String mUsername = null;
-        public String mPassword = null;
-        public String mAuthToken = null;
         public String mCookie = null;
         
-        public Target(Account account, Uri serverUrl, String username, String password, String authToken,
-                String cookie) {
+        public Target(Account account, Uri serverUrl, String cookie) {
             mAccount = account;
             mServerUrl = serverUrl;
-            mUsername = username;
-            mPassword = password;
-            mAuthToken = authToken;
             mCookie = cookie;
         }
     }
@@ -147,7 +137,8 @@ public class OperationsService extends Service {
         Log_OC.d(TAG, "Creating service");
 
         /// First worker thread for most of operations 
-        HandlerThread thread = new HandlerThread("Operations thread", Process.THREAD_PRIORITY_BACKGROUND);
+        HandlerThread thread = new HandlerThread("Operations thread",
+                Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
         mOperationsHandler = new ServiceHandler(thread.getLooper(), this);
         mOperationsBinder = new OperationsServiceBinder(mOperationsHandler);
@@ -184,7 +175,8 @@ public class OperationsService extends Service {
 
             Pair<Target, RemoteOperation> itemToQueue = newOperation(intent);
             if (itemToQueue != null) {
-                mSyncFolderHandler.add(account, remotePath, (SynchronizeFolderOperation)itemToQueue.second);
+                mSyncFolderHandler.add(account, remotePath,
+                        (SynchronizeFolderOperation)itemToQueue.second);
                 Message msg = mSyncFolderHandler.obtainMessage();
                 msg.arg1 = startId;
                 msg.obj = itemSyncKey;
@@ -248,7 +240,7 @@ public class OperationsService extends Service {
      */
     @Override
     public boolean onUnbind(Intent intent) {
-        ((OperationsServiceBinder)mOperationsBinder).clearListeners();
+        mOperationsBinder.clearListeners();
         return false;   // not accepting rebinding (default behaviour)
     }
 
@@ -261,7 +253,8 @@ public class OperationsService extends Service {
     public class OperationsServiceBinder extends Binder /* implements OnRemoteOperationListener */ {
         
         /** 
-         * Map of listeners that will be reported about the end of operations from a {@link OperationsServiceBinder} instance 
+         * Map of listeners that will be reported about the end of operations from a
+         * {@link OperationsServiceBinder} instance
          */
         private ConcurrentMap<OnRemoteOperationListener, Handler> mBoundListeners = 
                 new ConcurrentHashMap<OnRemoteOperationListener, Handler>();
@@ -294,9 +287,11 @@ public class OperationsService extends Service {
          * Adds a listener interested in being reported about the end of operations.
          * 
          * @param listener          Object to notify about the end of operations.    
-         * @param callbackHandler   {@link Handler} to access the listener without breaking Android threading protection.
+         * @param callbackHandler   {@link Handler} to access the listener without
+         *                                         breaking Android threading protection.
          */
-        public void addOperationListener (OnRemoteOperationListener listener, Handler callbackHandler) {
+        public void addOperationListener (OnRemoteOperationListener listener,
+                                          Handler callbackHandler) {
             synchronized (mBoundListeners) {
                 mBoundListeners.put(listener, callbackHandler);
             }
@@ -304,7 +299,8 @@ public class OperationsService extends Service {
         
         
         /**
-         * Removes a listener from the list of objects interested in the being reported about the end of operations.
+         * Removes a listener from the list of objects interested in the being reported about
+         * the end of operations.
          * 
          * @param listener      Object to notify about progress of transfer.    
          */
@@ -318,7 +314,8 @@ public class OperationsService extends Service {
         /**
          * TODO - IMPORTANT: update implementation when more operations are moved into the service 
          * 
-         * @return  'True' when an operation that enforces the user to wait for completion is in process.
+         * @return  'True' when an operation that enforces the user to wait for completion is
+         *          in process.
          */
         public boolean isPerformingBlockingOperation() {
             return (!mServiceHandler.mPendingOperations.isEmpty());
@@ -346,7 +343,8 @@ public class OperationsService extends Service {
         }
         
         
-        public boolean dispatchResultIfFinished(int operationId, OnRemoteOperationListener listener) {
+        public boolean dispatchResultIfFinished(int operationId,
+                                                OnRemoteOperationListener listener) {
             Pair<RemoteOperation, RemoteOperationResult> undispatched = 
                     mUndispatchedFinishedOperations.remove(operationId);
             if (undispatched != null) {
@@ -365,15 +363,15 @@ public class OperationsService extends Service {
         
         
         /**
-         * Returns True when the file described by 'file' in the ownCloud account 'account' is downloading or waiting
-         * to download.
+         * Returns True when the file described by 'file' in the ownCloud account 'account' is
+         * downloading or waiting to download.
          * 
-         * If 'file' is a directory, returns 'true' if some of its descendant files is downloading or waiting
-         * to download.
+         * If 'file' is a directory, returns 'true' if some of its descendant files is downloading
+         * or waiting to download.
          * 
          * @param account       ownCloud account where the remote file is stored.
-         * @param remotePath    Path of the folder to check if something is synchronizing / downloading / uploading
-         *                      inside.
+         * @param remotePath    Path of the folder to check if something is synchronizing
+         *                      / downloading / uploading inside.
          */
         public boolean isSynchronizing(Account account, String remotePath) {
             return mSyncFolderHandler.isSynchronizing(account, remotePath);
@@ -388,7 +386,8 @@ public class OperationsService extends Service {
      * Created with the Looper of a new thread, started in {@link OperationsService#onCreate()}. 
      */
     private static class ServiceHandler extends Handler {
-        // don't make it a final class, and don't remove the static ; lint will warn about a possible memory leak
+        // don't make it a final class, and don't remove the static ; lint will warn about a p
+        // ossible memory leak
         
         
         OperationsService mService;
@@ -439,7 +438,8 @@ public class OperationsService extends Service {
                     if (mLastTarget == null || !mLastTarget.equals(next.first)) {
                         mLastTarget = next.first;
                         if (mLastTarget.mAccount != null) {
-                            OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mAccount, mService);
+                            OwnCloudAccount ocAccount = new OwnCloudAccount(mLastTarget.mAccount,
+                                    mService);
                             mOwnCloudClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                                     getClientFor(ocAccount, mService);
                             mStorageManager = new FileDataStorageManager(
@@ -448,19 +448,11 @@ public class OperationsService extends Service {
                             );
                         } else {
                             OwnCloudCredentials credentials = null;
-                            if (mLastTarget.mUsername != null && 
-                                    mLastTarget.mUsername.length() > 0) {
-                                credentials = OwnCloudCredentialsFactory.newBasicCredentials(
-                                        mLastTarget.mUsername, 
-                                        mLastTarget.mPassword);  // basic
-                                
-                            } else if (mLastTarget.mAuthToken != null && 
-                                    mLastTarget.mAuthToken.length() > 0) {
-                                credentials = OwnCloudCredentialsFactory.newBearerCredentials(
-                                        mLastTarget.mAuthToken);  // bearer token
-                                
-                            } else if (mLastTarget.mCookie != null &&
+                            if (mLastTarget.mCookie != null &&
                                     mLastTarget.mCookie.length() > 0) {
+                                // just used for GetUserName
+                                // TODO refactor to run GetUserName as AsyncTask in the context of
+                                // AuthenticatorActivity
                                 credentials = OwnCloudCredentialsFactory.newSamlSsoCredentials(
                                         mLastTarget.mCookie); // SAML SSO
                             }
@@ -474,24 +466,29 @@ public class OperationsService extends Service {
 
                     /// perform the operation
                     if (mCurrentOperation instanceof SyncOperation) {
-                        result = ((SyncOperation)mCurrentOperation).execute(mOwnCloudClient, mStorageManager);
+                        result = ((SyncOperation)mCurrentOperation).execute(mOwnCloudClient,
+                                mStorageManager);
                     } else {
                         result = mCurrentOperation.execute(mOwnCloudClient);
                     }
                     
                 } catch (AccountsException e) {
                     if (mLastTarget.mAccount == null) {
-                        Log_OC.e(TAG, "Error while trying to get authorization for a NULL account", e);
+                        Log_OC.e(TAG, "Error while trying to get authorization for a NULL account",
+                                e);
                     } else {
-                        Log_OC.e(TAG, "Error while trying to get authorization for " + mLastTarget.mAccount.name, e);
+                        Log_OC.e(TAG, "Error while trying to get authorization for " +
+                                mLastTarget.mAccount.name, e);
                     }
                     result = new RemoteOperationResult(e);
                     
                 } catch (IOException e) {
                     if (mLastTarget.mAccount == null) {
-                        Log_OC.e(TAG, "Error while trying to get authorization for a NULL account", e);
+                        Log_OC.e(TAG, "Error while trying to get authorization for a NULL account",
+                                e);
                     } else {
-                        Log_OC.e(TAG, "Error while trying to get authorization for " + mLastTarget.mAccount.name, e);
+                        Log_OC.e(TAG, "Error while trying to get authorization for " +
+                                mLastTarget.mAccount.name, e);
                     }
                     result = new RemoteOperationResult(e);
                 } catch (Exception e) {
@@ -509,7 +506,7 @@ public class OperationsService extends Service {
                 }
                 
                 //sendBroadcastOperationFinished(mLastTarget, mCurrentOperation, result);
-                mService.dispatchResultToOperationListeners(mLastTarget, mCurrentOperation, result);
+                mService.dispatchResultToOperationListeners(mCurrentOperation, result);
             }
         }
 
@@ -524,7 +521,8 @@ public class OperationsService extends Service {
      * TODO - move to ServiceHandler (probably)
      * 
      * @param operationIntent       Intent describing a new operation to queue and execute.
-     * @return                      Pair with the new operation object and the information about its target server.
+     * @return                      Pair with the new operation object and the information about its
+     *                              target server.
      */
     private Pair<Target , RemoteOperation> newOperation(Intent operationIntent) {
         RemoteOperation operation = null;
@@ -537,26 +535,22 @@ public class OperationsService extends Service {
             } else {
                 Account account = operationIntent.getParcelableExtra(EXTRA_ACCOUNT);
                 String serverUrl = operationIntent.getStringExtra(EXTRA_SERVER_URL);
-                String username = operationIntent.getStringExtra(EXTRA_USERNAME);
-                String password = operationIntent.getStringExtra(EXTRA_PASSWORD);
-                String authToken = operationIntent.getStringExtra(EXTRA_AUTH_TOKEN);
                 String cookie = operationIntent.getStringExtra(EXTRA_COOKIE);
                 target = new Target(
                         account, 
                         (serverUrl == null) ? null : Uri.parse(serverUrl),
-                        username,
-                        password,
-                        authToken,
                         cookie
                 );
                 
                 String action = operationIntent.getAction();
                 if (action.equals(ACTION_CREATE_SHARE)) {  // Create Share
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+                    String password = operationIntent.getStringExtra(EXTRA_PASSWORD_SHARE);
                     Intent sendIntent = operationIntent.getParcelableExtra(EXTRA_SEND_INTENT);
                     if (remotePath.length() > 0) {
-                        operation = new CreateShareOperation(OperationsService.this, remotePath, ShareType.PUBLIC_LINK,
-                                "", false, "", 1, sendIntent);
+                        operation = new CreateShareOperation(OperationsService.this, remotePath,
+                                ShareType.PUBLIC_LINK,
+                                "", false, password, 1, sendIntent);
                     }
                     
                 } else if (action.equals(ACTION_UNSHARE)) {  // Unshare file
@@ -581,12 +575,6 @@ public class OperationsService extends Service {
                             getString(R.string.oauth2_grant_type),
                             oauth2QueryParameters);
                     
-                } else if (action.equals(ACTION_EXISTENCE_CHECK)) {
-                    // Existence Check 
-                    String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    boolean successIfAbsent = operationIntent.getBooleanExtra(EXTRA_SUCCESS_IF_ABSENT, false);
-                    operation = new ExistenceCheckRemoteOperation(remotePath, OperationsService.this, successIfAbsent);
-                    
                 } else if (action.equals(ACTION_GET_USER_NAME)) {
                     // Get User Name
                     operation = new GetRemoteUserNameOperation();
@@ -600,19 +588,22 @@ public class OperationsService extends Service {
                 } else if (action.equals(ACTION_REMOVE)) {
                     // Remove file or folder
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL, false);
+                    boolean onlyLocalCopy = operationIntent.getBooleanExtra(EXTRA_REMOVE_ONLY_LOCAL,
+                            false);
                     operation = new RemoveFileOperation(remotePath, onlyLocalCopy);
                     
                 } else if (action.equals(ACTION_CREATE_FOLDER)) {
                     // Create Folder
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH, true);
+                    boolean createFullPath = operationIntent.getBooleanExtra(EXTRA_CREATE_FULL_PATH,
+                            true);
                     operation = new CreateFolderOperation(remotePath, createFullPath);
                     
                 } else if (action.equals(ACTION_SYNC_FILE)) {
                     // Sync file
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    boolean syncFileContents = operationIntent.getBooleanExtra(EXTRA_SYNC_FILE_CONTENTS, true);
+                    boolean syncFileContents =
+                            operationIntent.getBooleanExtra(EXTRA_SYNC_FILE_CONTENTS, true);
                     operation = new SynchronizeFileOperation(
                             remotePath, account, syncFileContents, getApplicationContext()
                     );
@@ -621,7 +612,7 @@ public class OperationsService extends Service {
                     // Sync file
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
                     operation = new SynchronizeFolderOperation(
-                            this,                       // TODO remove this dependency from construction time 
+                            this,                       // TODO remove this dependency from construction time
                             remotePath,
                             account, 
                             System.currentTimeMillis()  // TODO remove this dependency from construction time
@@ -652,7 +643,8 @@ public class OperationsService extends Service {
     /**
      * Sends a broadcast when a new operation is added to the queue.
      * 
-     * Local broadcasts are only delivered to activities in the same process, but can't be done sticky :\
+     * Local broadcasts are only delivered to activities in the same process, but can't be
+     * done sticky :\
      * 
      * @param target            Account or URL pointing to an OC server.
      * @param operation         Added operation.
@@ -673,7 +665,8 @@ public class OperationsService extends Service {
     // TODO - maybe add a notification for real start of operations
     
     /**
-     * Sends a LOCAL broadcast when an operations finishes in order to the interested activities can update their view
+     * Sends a LOCAL broadcast when an operations finishes in order to the interested activities c
+     * an update their view
      * 
      * Local broadcasts are only delivered to activities in the same process.
      * 
@@ -681,7 +674,8 @@ public class OperationsService extends Service {
      * @param operation         Finished operation.
      * @param result            Result of the operation.
      */
-    private void sendBroadcastOperationFinished(Target target, RemoteOperation operation, RemoteOperationResult result) {
+    private void sendBroadcastOperationFinished(Target target, RemoteOperation operation,
+                                                RemoteOperationResult result) {
         Intent intent = new Intent(ACTION_OPERATION_FINISHED);
         intent.putExtra(EXTRA_RESULT, result);
         if (target.mAccount != null) {
@@ -698,14 +692,15 @@ public class OperationsService extends Service {
     /**
      * Notifies the currently subscribed listeners about the end of an operation.
      *
-     * @param target            Account or URL pointing to an OC server.
      * @param operation         Finished operation.
      * @param result            Result of the operation.
      */
     protected void dispatchResultToOperationListeners(
-            Target target, final RemoteOperation operation, final RemoteOperationResult result) {
+            final RemoteOperation operation, final RemoteOperationResult result
+    ) {
         int count = 0;
-        Iterator<OnRemoteOperationListener> listeners = mOperationsBinder.mBoundListeners.keySet().iterator();
+        Iterator<OnRemoteOperationListener> listeners =
+                mOperationsBinder.mBoundListeners.keySet().iterator();
         while (listeners.hasNext()) {
             final OnRemoteOperationListener listener = listeners.next();
             final Handler handler = mOperationsBinder.mBoundListeners.get(listener);
index 02f8f7a..33318f5 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
@@ -25,6 +27,7 @@ import android.os.Looper;
 import android.os.Message;
 import android.util.Pair;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
@@ -126,14 +129,15 @@ class SyncFolderHandler extends Handler {
             } finally {
                 mPendingOperations.removePayload(account, remotePath);
 
-                mService.dispatchResultToOperationListeners(null, mCurrentSyncOperation, result);
+                mService.dispatchResultToOperationListeners(mCurrentSyncOperation, result);
 
                 sendBroadcastFinishedSyncFolder(account, remotePath, result.isSuccess());
             }
         }
     }
 
-    public void add(Account account, String remotePath, SynchronizeFolderOperation syncFolderOperation){
+    public void add(Account account, String remotePath,
+                    SynchronizeFolderOperation syncFolderOperation){
         mPendingOperations.putIfAbsent(account, remotePath, syncFolderOperation);
         sendBroadcastNewSyncFolder(account, remotePath);    // TODO upgrade!
     }
@@ -168,26 +172,29 @@ class SyncFolderHandler extends Handler {
     }
 
     /**
-     * TODO review this method when "folder synchronization" replaces "folder download"; this is a fast and ugly
-     * patch.
+     * TODO review this method when "folder synchronization" replaces "folder download";
+     * this is a fast and ugly patch.
      */
     private void sendBroadcastNewSyncFolder(Account account, String remotePath) {
         Intent added = new Intent(FileDownloader.getDownloadAddedMessage());
         added.putExtra(FileDownloader.ACCOUNT_NAME, account.name);
         added.putExtra(FileDownloader.EXTRA_REMOTE_PATH, remotePath);
-        added.putExtra(FileDownloader.EXTRA_FILE_PATH, FileStorageUtils.getSavePath(account.name) + remotePath);
+        added.putExtra(FileDownloader.EXTRA_FILE_PATH, FileStorageUtils.getSavePath(account.name)
+                + remotePath);
         mService.sendStickyBroadcast(added);
     }
 
     /**
-     * TODO review this method when "folder synchronization" replaces "folder download"; this is a fast and ugly
-     * patch.
+     * TODO review this method when "folder synchronization" replaces "folder download";
+     * this is a fast and ugly patch.
      */
-    private void sendBroadcastFinishedSyncFolder(Account account, String remotePath, boolean success) {
+    private void sendBroadcastFinishedSyncFolder(Account account, String remotePath,
+                                                 boolean success) {
         Intent finished = new Intent(FileDownloader.getDownloadFinishMessage());
         finished.putExtra(FileDownloader.ACCOUNT_NAME, account.name);
         finished.putExtra(FileDownloader.EXTRA_REMOTE_PATH, remotePath);
-        finished.putExtra(FileDownloader.EXTRA_FILE_PATH, FileStorageUtils.getSavePath(account.name) + remotePath);
+        finished.putExtra(FileDownloader.EXTRA_FILE_PATH,
+                FileStorageUtils.getSavePath(account.name) + remotePath);
         finished.putExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, success);
         mService.sendStickyBroadcast(finished);
     }
index 114f0e4..83de450 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -54,8 +57,6 @@ import com.owncloud.android.utils.FileStorageUtils;
  * memory. To minimize the impact of this, the service always returns
  * Service.START_STICKY, and the later restart of the service is explicitly
  * considered in {@link FileObserverService#onStartCommand(Intent, int, int)}.
- * 
- * @author David A. Velasco
  */
 public class FileObserverService extends Service {
 
index 67b41a1..5329b52 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -46,8 +49,6 @@ import com.owncloud.android.ui.activity.ConflictsResolveActivity;
  *  The second case requires to monitor the folder parent of the files, since a direct 
  *  {@link FileObserver} on it will not receive more events after the file is deleted to
  *  be replaced.
- * 
- * @author David A. Velasco
  */
 public class FolderObserver extends FileObserver {
 
index 28cfa54..4740310 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author sassman\r
+ *   @author David A. Velasco\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -24,6 +28,7 @@ import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;\r
 import org.apache.http.client.ClientProtocolException;\r
 \r
+import com.owncloud.android.MainApp;\r
 import com.owncloud.android.datamodel.FileDataStorageManager;\r
 import com.owncloud.android.lib.common.accounts.AccountUtils;\r
 import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;\r
@@ -44,9 +49,6 @@ import android.content.Context;
  * resource types, like FileSync, ConcatsSync, CalendarSync, etc..\r
  * \r
  * Implements the standard {@link AbstractThreadedSyncAdapter}.\r
- * \r
- * @author sassman\r
- * @author David A. Velasco\r
  */\r
 public abstract class AbstractOwnCloudSyncAdapter extends\r
         AbstractThreadedSyncAdapter {\r
@@ -63,7 +65,8 @@ public abstract class AbstractOwnCloudSyncAdapter extends
         this.setAccountManager(AccountManager.get(context));\r
     }\r
 \r
-    public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {\r
+    public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize,\r
+                                       boolean allowParallelSyncs) {\r
         super(context, autoInitialize, allowParallelSyncs);\r
         this.setAccountManager(AccountManager.get(context));\r
     }\r
@@ -100,7 +103,8 @@ public abstract class AbstractOwnCloudSyncAdapter extends
         return mStoreManager;\r
     }\r
 \r
-    protected void initClientForCurrentAccount() throws OperationCanceledException, AuthenticatorException, IOException, AccountNotFoundException {\r
+    protected void initClientForCurrentAccount() throws OperationCanceledException,\r
+            AuthenticatorException, IOException, AccountNotFoundException {\r
         AccountUtils.constructFullURLForAccount(getContext(), account);\r
         OwnCloudAccount ocAccount = new OwnCloudAccount(account, getContext());\r
         mClient = OwnCloudClientManagerFactory.getDefaultSingleton().\r
index 3ba1676..d3ab06c 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 6d7c46c..d907bb4 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 4683896..43ddae3 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -26,6 +30,7 @@ import java.util.Map;
 
 import org.apache.jackrabbit.webdav.DavException;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -54,26 +59,31 @@ import android.support.v4.app.NotificationCompat;
  * Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing 
  * ownCloud files.
  * 
- * Performs a full synchronization of the account recieved in {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}.
- * 
- * @author Bartek Przybylski
- * @author David A. Velasco
+ * Performs a full synchronization of the account recieved in {@link #onPerformSync(Account, Bundle,
+ * String, ContentProviderClient, SyncResult)}.
  */
 public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
 
     private final static String TAG = FileSyncAdapter.class.getSimpleName();
 
-    /** Maximum number of failed folder synchronizations that are supported before finishing the synchronization operation */
+    /** Maximum number of failed folder synchronizations that are supported before finishing
+     * the synchronization operation */
     private static final int MAX_FAILED_RESULTS = 3; 
     
     
-    public static final String EVENT_FULL_SYNC_START = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_START";
-    public static final String EVENT_FULL_SYNC_END = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_END";
-    public static final String EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED";
-    //public static final String EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED = FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED";
+    public static final String EVENT_FULL_SYNC_START = FileSyncAdapter.class.getName() +
+            ".EVENT_FULL_SYNC_START";
+    public static final String EVENT_FULL_SYNC_END = FileSyncAdapter.class.getName() +
+            ".EVENT_FULL_SYNC_END";
+    public static final String EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED =
+            FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED";
+    //public static final String EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED =
+    // FileSyncAdapter.class.getName() + ".EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED";
     
-    public static final String EXTRA_ACCOUNT_NAME = FileSyncAdapter.class.getName() + ".EXTRA_ACCOUNT_NAME";
-    public static final String EXTRA_FOLDER_PATH = FileSyncAdapter.class.getName() + ".EXTRA_FOLDER_PATH";
+    public static final String EXTRA_ACCOUNT_NAME = FileSyncAdapter.class.getName() +
+            ".EXTRA_ACCOUNT_NAME";
+    public static final String EXTRA_FOLDER_PATH = FileSyncAdapter.class.getName() +
+            ".EXTRA_FOLDER_PATH";
     public static final String EXTRA_RESULT = FileSyncAdapter.class.getName() + ".EXTRA_RESULT";
     
     
@@ -83,7 +93,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     /** Flag made 'true' when a request to cancel the synchronization is received */
     private boolean mCancellation;
     
-    /** When 'true' the process was requested by the user through the user interface; when 'false', it was requested automatically by the system */
+    /** When 'true' the process was requested by the user through the user interface;
+     *  when 'false', it was requested automatically by the system */
     private boolean mIsManualSync;
     
     /** Counter for failed operations in the synchronization process */
@@ -98,7 +109,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     /** Counter of failed operations in synchronization of kept-in-sync files */
     private int mFailsInFavouritesFound;
     
-    /** Map of remote and local paths to files that where locally stored in a location out of the ownCloud folder and couldn't be copied automatically into it */
+    /** Map of remote and local paths to files that where locally stored in a location out
+     * of the ownCloud folder and couldn't be copied automatically into it */
     private Map<String, String> mForgottenLocalFiles;
 
     /** {@link SyncResult} instance to return to the system when the synchronization finish */
@@ -154,19 +166,22 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
         try {
             this.initClientForCurrentAccount();
         } catch (IOException e) {
-            /// the account is unknown for the Synchronization Manager, unreachable this context, or can not be authenticated; don't try this again
+            /// the account is unknown for the Synchronization Manager, unreachable this context,
+            // or can not be authenticated; don't try this again
             mSyncResult.tooManyRetries = true;
             notifyFailedSynchronization();
             return;
         } catch (AccountsException e) {
-            /// the account is unknown for the Synchronization Manager, unreachable this context, or can not be authenticated; don't try this again
+            /// the account is unknown for the Synchronization Manager, unreachable this context,
+            // or can not be authenticated; don't try this again
             mSyncResult.tooManyRetries = true;
             notifyFailedSynchronization();
             return;
         }
         
         Log_OC.d(TAG, "Synchronization of ownCloud account " + account.name + " starting");
-        sendLocalBroadcast(EVENT_FULL_SYNC_START, null, null);  // message to signal the start of the synchronization to the UI
+        sendLocalBroadcast(EVENT_FULL_SYNC_START, null, null);  // message to signal the start
+                                                                // of the synchronization to the UI
         
         try {
             updateOCVersion();
@@ -175,16 +190,19 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                 synchronizeFolder(getStorageManager().getFileByPath(OCFile.ROOT_PATH));
                 
             } else {
-                Log_OC.d(TAG, "Leaving synchronization before synchronizing the root folder because cancelation request");
+                Log_OC.d(TAG, "Leaving synchronization before synchronizing the root folder " +
+                        "because cancelation request");
             }
             
             
         } finally {
-            // it's important making this although very unexpected errors occur; that's the reason for the finally
+            // it's important making this although very unexpected errors occur;
+            // that's the reason for the finally
             
             if (mFailedResultsCounter > 0 && mIsManualSync) {
                 /// don't let the system synchronization manager retries MANUAL synchronizations
-                //      (be careful: "MANUAL" currently includes the synchronization requested when a new account is created and when the user changes the current account)
+                //      (be careful: "MANUAL" currently includes the synchronization requested when
+                //      a new account is created and when the user changes the current account)
                 mSyncResult.tooManyRetries = true;
                 
                 /// notify the user about the failure of MANUAL synchronization
@@ -196,7 +214,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             if (mForgottenLocalFiles.size() > 0) {
                 notifyForgottenLocalFiles();
             }
-            sendLocalBroadcast(EVENT_FULL_SYNC_END, null, mLastFailedResult);   // message to signal the end to the UI
+            sendLocalBroadcast(EVENT_FULL_SYNC_END, null, mLastFailedResult);   // message to signal
+                                                                                // the end to the UI
         }
         
     }
@@ -209,7 +228,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
      * locally saved. 
      * 
      * See {@link #onPerformSync(Account, Bundle, String, ContentProviderClient, SyncResult)}
-     * and {@link #synchronizeFolder(String, long)}.
+     * and {@link #synchronizeFolder(OCFile)}.
      */
     @Override
     public void onSyncCanceled() {
@@ -260,14 +279,14 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
         }
         */
         // folder synchronization
-        RefreshFolderOperation synchFolderOp = new RefreshFolderOperation(  folder,
-                                                                                    mCurrentSyncTime, 
-                                                                                    true,
-                                                                                    mIsShareSupported,
-                                                                                    false,
-                                                                                    getStorageManager(), 
-                                                                                    getAccount(), 
-                                                                                    getContext()
+        RefreshFolderOperation synchFolderOp = new RefreshFolderOperation( folder,
+                                                                                   mCurrentSyncTime,
+                                                                                   true,
+                                                                                   mIsShareSupported,
+                                                                                   false,
+                                                                                   getStorageManager(),
+                                                                                   getAccount(),
+                                                                                   getContext()
                                                                                   );
         RemoteOperationResult result = synchFolderOp.execute(getClient());
         
@@ -288,7 +307,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             if (result.isSuccess()) {
                 // synchronize children folders 
                 List<OCFile> children = synchFolderOp.getChildren();
-                fetchChildren(folder, children, synchFolderOp.getRemoteFolderChanged());    // beware of the 'hidden' recursion here!
+                // beware of the 'hidden' recursion here!
+                fetchChildren(folder, children, synchFolderOp.getRemoteFolderChanged());
             }
             
         } else {
@@ -311,11 +331,12 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     }
 
     /**
-     * Checks if a failed result should terminate the synchronization process immediately, according to
-     * OUR OWN POLICY
+     * Checks if a failed result should terminate the synchronization process immediately,
+     * according to OUR OWN POLICY
      * 
      * @param   failedResult        Remote operation result to check.
-     * @return                      'True' if the result should immediately finish the synchronization
+     * @return                      'True' if the result should immediately finish the
+     *                              synchronization
      */
     private boolean isFinisher(RemoteOperationResult failedResult) {
         if  (failedResult != null) {
@@ -346,23 +367,29 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                 syncDown = (parentEtagChanged || etag == null || etag.length() == 0);
                 if(syncDown) { */
                     synchronizeFolder(newFile);
-                    //sendLocalBroadcast(EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED, parent.getRemotePath(), null);
+                    //sendLocalBroadcast(EVENT_FULL_SYNC_FOLDER_SIZE_SYNCED, parent.getRemotePath(),
+                    // null);
                 //}
             }
         }
        
-        if (mCancellation && i <files.size()) Log_OC.d(TAG, "Leaving synchronization before synchronizing " + files.get(i).getRemotePath() + " due to cancelation request");
+        if (mCancellation && i <files.size()) Log_OC.d(TAG,
+                "Leaving synchronization before synchronizing " + files.get(i).getRemotePath() +
+                        " due to cancelation request");
     }
 
     
     /**
-     * Sends a message to any application component interested in the progress of the synchronization.
+     * Sends a message to any application component interested in the progress of the
+     * synchronization.
      * 
      * @param event             Event in the process of synchronization to be notified.   
      * @param dirRemotePath     Remote path of the folder target of the event occurred.
-     * @param result            Result of an individual {@ SynchronizeFolderOperation}, if completed; may be null.
+     * @param result            Result of an individual {@ SynchronizeFolderOperation},
+     *                          if completed; may be null.
      */
-    private void sendLocalBroadcast(String event, String dirRemotePath, RemoteOperationResult result) {
+    private void sendLocalBroadcast(String event, String dirRemotePath,
+                                    RemoteOperationResult result) {
         Log_OC.d(TAG, "Send broadcast " + event);
         Intent intent = new Intent(event);
         intent.putExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME, getAccount().name);
@@ -393,7 +420,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
             // let the user update credentials with one click
             Intent updateAccountCredentials = new Intent(getContext(), AuthenticatorActivity.class);
             updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount());
-            updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
+            updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
+                    AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
             updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
             updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
@@ -401,7 +429,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                 .setTicker(i18n(R.string.sync_fail_ticker_unauthorized))
                 .setContentTitle(i18n(R.string.sync_fail_ticker_unauthorized))
                 .setContentIntent(PendingIntent.getActivity(
-                    getContext(), (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT
+                    getContext(), (int)System.currentTimeMillis(), updateAccountCredentials,
+                        PendingIntent.FLAG_ONE_SHOT
                 ))
                 .setContentText(i18n(R.string.sync_fail_content_unauthorized, getAccount().name));
         } else {
@@ -416,7 +445,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
 
 
     /**
-     * Notifies the user about conflicts and strange fails when trying to synchronize the contents of kept-in-sync files.
+     * Notifies the user about conflicts and strange fails when trying to synchronize the contents
+     * of kept-in-sync files.
      * 
      * By now, we won't consider a failed synchronization.
      */
@@ -431,7 +461,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                     getContext(), (int) System.currentTimeMillis(), new Intent(), 0
                 ))
                 .setContentTitle(i18n(R.string.sync_fail_in_favourites_ticker))
-                .setContentText(i18n(R.string.sync_fail_in_favourites_content, mFailedResultsCounter + mConflictsFound, mConflictsFound));
+                .setContentText(i18n(R.string.sync_fail_in_favourites_content,
+                        mFailedResultsCounter + mConflictsFound, mConflictsFound));
             
             showNotification(R.string.sync_fail_in_favourites_ticker, notificationBuilder);
         } else {
@@ -451,13 +482,15 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
     }
     
     /**
-     * Notifies the user about local copies of files out of the ownCloud local directory that were 'forgotten' because 
-     * copying them inside the ownCloud local directory was not possible.
+     * Notifies the user about local copies of files out of the ownCloud local directory that
+     * were 'forgotten' because copying them inside the ownCloud local directory was not possible.
      * 
-     * We don't want links to files out of the ownCloud local directory (foreign files) anymore. It's easy to have 
-     * synchronization problems if a local file is linked to more than one remote file.
+     * We don't want links to files out of the ownCloud local directory (foreign files) anymore.
+     * It's easy to have synchronization problems if a local file is linked to more than one
+     * remote file.
      * 
-     * We won't consider a synchronization as failed when foreign files can not be copied to the ownCloud local directory.
+     * We won't consider a synchronization as failed when foreign files can not be copied to
+     * the ownCloud local directory.
      */
     private void notifyForgottenLocalFiles() {
         NotificationCompat.Builder notificationBuilder = createNotificationBuilder();
@@ -479,7 +512,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                 getContext(), (int) System.currentTimeMillis(), explanationIntent, 0
             ))
             .setContentTitle(i18n(R.string.sync_foreign_files_forgotten_ticker))
-            .setContentText(i18n(R.string.sync_foreign_files_forgotten_content, mForgottenLocalFiles.size(), i18n(R.string.app_name)));
+            .setContentText(i18n(R.string.sync_foreign_files_forgotten_content,
+                    mForgottenLocalFiles.size(), i18n(R.string.app_name)));
         
         showNotification(R.string.sync_foreign_files_forgotten_ticker, notificationBuilder);
     }
index 5da8c24..e48f91f 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
+ *   @author David A. Velasco\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -24,10 +28,7 @@ import android.os.IBinder;
 /**\r
  * Background service for synchronizing remote files with their local state.\r
  * \r
- * Serves as a connector to an instance of {@link FileSyncAdapter}, as required by standard Android APIs. \r
- * \r
- * @author Bartek Przybylski\r
- * @author David A. Velasco\r
+ * Serves as a connector to an instance of {@link FileSyncAdapter}, as required by standard Android APIs.\r
  */\r
 public class FileSyncService extends Service {\r
     \r
index a65f3ad..e1fa805 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -22,9 +25,6 @@ import android.view.View.OnClickListener;
 \r
 /**\r
  * Represents an Item on the ActionBar.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
  */\r
 public class ActionItem {\r
     private Drawable mIcon;\r
index dac083a..b451fca 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2014 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
index fccf56d..44f8976 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Lorensius. W. T\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -32,9 +35,6 @@ import android.widget.PopupWindow;
 \r
 /**\r
  * Represents a custom PopupWindows\r
- * \r
- * @author Lorensius. W. T\r
- * \r
  */\r
 public class CustomPopup {\r
     protected final View mAnchor;\r
index 20bf66f..2258764 100644 (file)
@@ -1,4 +1,7 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2012 Bartek Przybylski
  *   Copyright (C) 2012-2015 ownCloud Inc.
  *
@@ -28,9 +31,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 /**
  * ListView allowing to specify the position of an item that should be centered in the visible area, if possible.
  *
- * The cleanest way I found to overcome the problem due to getHeight() returns 0 until the view is really drawn. 
- *
- * @author David A. Velasco
+ * The cleanest way I found to overcome the problem due to getHeight() returns 0 until the view is really drawn.
  */
 public class ExtendedListView extends ListView {
 
index e38d29a..946a41e 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2014 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
index 86fe3fe..db27951 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Lorensius. W. T\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -42,8 +45,6 @@ import com.owncloud.android.R;
 /**\r
  * Popup window, shows action list as icon and text like the one in Gallery3D\r
  * app.\r
- * \r
- * @author Lorensius. W. T\r
  */\r
 public class QuickAction extends CustomPopup {\r
     private final View root;\r
index 8f562b3..4437cce 100644 (file)
@@ -1,3 +1,22 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 package com.owncloud.android.ui;
 
 import android.content.Context;
index 455bdc9..b1613fd 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
index 4a8148f..c65c51f 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
index 2916ac3..043f67e 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 509e5c7..c3db9a4 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author David A. Velasco
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -32,10 +36,7 @@ import android.os.Bundle;
 
 /**
  * Wrapper activity which will be launched if keep-in-sync file will be modified by external
- * application. 
- * 
- * @author Bartek Przybylski
- * @author David A. Velasco
+ * application.
  */
 public class ConflictsResolveActivity extends FileActivity implements OnConflictDecisionMadeListener {
 
index b503c37..de5b3c3 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -28,8 +31,6 @@ import android.widget.Toast;
 
 /**
  * Activity copying the text of the received Intent into the system clibpoard.
- * 
- * @author David A. Velasco
  */
 @SuppressWarnings("deprecation")
 public class CopyToClipboardActivity extends Activity {
index bffec8b..9405ca7 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -57,8 +60,6 @@ import com.owncloud.android.utils.FileStorageUtils;
  * files.
  * 
  * Shown when the error notification summarizing the list of errors is clicked by the user.
- * 
- * @author David A. Velasco
  */
 public class ErrorsWhileCopyingHandlerActivity  extends SherlockFragmentActivity implements OnClickListener {
 
@@ -129,9 +130,7 @@ public class ErrorsWhileCopyingHandlerActivity  extends SherlockFragmentActivity
     
     /**
      * Customized adapter, showing the local files as main text in two-lines list item and the remote files
-     * as the secondary text. 
-     * 
-     * @author David A. Velasco
+     * as the secondary text.
      */
     public class ErrorsWhileCopyingListAdapter extends ArrayAdapter<String> {
         
@@ -200,8 +199,6 @@ public class ErrorsWhileCopyingHandlerActivity  extends SherlockFragmentActivity
     
     /**
      * Asynchronous task performing the move of all the local files to the ownCloud folder.
-     * 
-     * @author David A. Velasco
      */
     private class MoveFilesTask extends AsyncTask<Void, Void, Boolean> {
 
index 536800b..a566ccd 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -56,30 +59,31 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.operations.CreateShareOperation;
 import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.UnshareLinkOperation;
-
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
+import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.ui.dialog.LoadingDialog;
+import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 
 
 /**
  * Activity with common behaviour for activities handling {@link OCFile}s in ownCloud {@link Account}s .
- * 
- * @author David A. Velasco
  */
-public class FileActivity extends SherlockFragmentActivity 
-implements OnRemoteOperationListener, ComponentsGetter {
+public class FileActivity extends SherlockFragmentActivity
+        implements OnRemoteOperationListener, ComponentsGetter {
 
     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";
+    public static final String EXTRA_FROM_NOTIFICATION = "com.owncloud.android.ui.activity.FROM_NOTIFICATION";
     
     public static final String TAG = FileActivity.class.getSimpleName();
     
     private static final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
-    private static final String KEY_WAITING_FOR_OP_ID = "WAITING_FOR_OP_ID";;
+    private static final String KEY_WAITING_FOR_OP_ID = "WAITING_FOR_OP_ID";
+    private static final String DIALOG_SHARE_PASSWORD = "DIALOG_SHARE_PASSWORD";
+    private static final String KEY_TRY_SHARE_AGAIN = "TRY_SHARE_AGAIN";
     
     protected static final long DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS = 200;
     
@@ -94,10 +98,10 @@ implements OnRemoteOperationListener, ComponentsGetter {
     private boolean mRedirectingToSetupAccount = false;
     
     /** Flag to signal when the value of mAccount was set */ 
-    private boolean mAccountWasSet;
+    protected boolean mAccountWasSet;
     
     /** Flag to signal when the value of mAccount was restored from a saved state */ 
-    private boolean mAccountWasRestored;
+    protected boolean mAccountWasRestored;
     
     /** Flag to signal if the activity is launched by a notification */
     private boolean mFromNotification;
@@ -117,6 +121,8 @@ implements OnRemoteOperationListener, ComponentsGetter {
     protected FileDownloaderBinder mDownloaderBinder = null;
     protected FileUploaderBinder mUploaderBinder = null;
     private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
+
+    private boolean mTryShareAgain = false;
     
     
     /**
@@ -139,6 +145,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
             mFileOperationsHelper.setOpIdWaitingFor(
                     savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID, Long.MAX_VALUE)
                     );
+            mTryShareAgain = savedInstanceState.getBoolean(KEY_TRY_SHARE_AGAIN);
         } else {
             account = getIntent().getParcelableExtra(FileActivity.EXTRA_ACCOUNT);
             mFile = getIntent().getParcelableExtra(FileActivity.EXTRA_FILE);
@@ -158,7 +165,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
         if (mUploadServiceConnection != null) {
             bindService(new Intent(this, FileUploader.class), mUploadServiceConnection, Context.BIND_AUTO_CREATE);
         }
-        
+
     }
 
     
@@ -221,6 +228,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
             unbindService(mUploadServiceConnection);
             mUploadServiceConnection = null;
         }
+
         super.onDestroy();
     }
     
@@ -235,7 +243,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
      *  @param account          New {@link Account} to set.
      *  @param savedAccount     When 'true', account was retrieved from a saved instance state.
      */
-    private void setAccount(Account account, boolean savedAccount) {
+    protected void setAccount(Account account, boolean savedAccount) {
         Account oldAccount = mAccount;
         boolean validAccount = (account != null && AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), account.name));
         if (validAccount) {
@@ -256,8 +264,6 @@ implements OnRemoteOperationListener, ComponentsGetter {
      *  to create a new ownCloud {@link Account}.
      *  
      *  POSTCONDITION: updates {@link #mAccountWasSet} and {@link #mAccountWasRestored}.
-     *   
-     *  @return     'True' if the checked {@link Account} was valid.
      */
     private void swapToDefaultAccount() {
         // default to the most recently used account
@@ -302,6 +308,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
         outState.putParcelable(FileActivity.EXTRA_ACCOUNT, mAccount);
         outState.putBoolean(FileActivity.EXTRA_FROM_NOTIFICATION, mFromNotification);
         outState.putLong(KEY_WAITING_FOR_OP_ID, mFileOperationsHelper.getOpIdWaitingFor());
+        outState.putBoolean(KEY_TRY_SHARE_AGAIN, mTryShareAgain);
     }
     
     
@@ -334,6 +341,10 @@ implements OnRemoteOperationListener, ComponentsGetter {
         return mAccount;
     }
 
+    protected void setAccount(Account account) {
+        mAccount = account;
+    }
+
     /**
      * @return Value of mFromNotification: True if the Activity is launched by a notification
      */
@@ -347,7 +358,14 @@ implements OnRemoteOperationListener, ComponentsGetter {
     protected boolean isRedirectingToSetupAccount() {
         return mRedirectingToSetupAccount;
     }
-    
+
+    public boolean isTryShareAgain(){
+        return mTryShareAgain;
+    }
+
+    public void setTryShareAgain(boolean tryShareAgain) {
+       mTryShareAgain = tryShareAgain;
+    }
     
     public OperationsServiceBinder getOperationsServiceBinder() {
         return mOperationsServiceBinder;
@@ -356,15 +374,12 @@ implements OnRemoteOperationListener, ComponentsGetter {
     protected ServiceConnection newTransferenceServiceConnection() {
         return null;
     }
-    
 
     /**
      * Helper class handling a callback from the {@link AccountManager} after the creation of
      * a new ownCloud {@link Account} finished, successfully or not.
      * 
      * At this moment, only called after the creation of the first account.
-     * 
-     * @author David A. Velasco
      */
     public class AccountCreationCallback implements AccountManagerCallback<Bundle> {
 
@@ -454,10 +469,12 @@ implements OnRemoteOperationListener, ComponentsGetter {
             
             if (result.getCode() == ResultCode.UNAUTHORIZED) {
                 dismissLoadingDialog();
-                Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
+                Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result,
+                                operation, getResources()),
                         Toast.LENGTH_LONG);
                 t.show();
             }
+            mTryShareAgain = false;
 
         } else if (operation instanceof CreateShareOperation) {
             onCreateShareOperationFinish((CreateShareOperation) operation, result);
@@ -482,18 +499,36 @@ implements OnRemoteOperationListener, ComponentsGetter {
     }
     
 
-    private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
+    private void onCreateShareOperationFinish(CreateShareOperation operation,
+                                              RemoteOperationResult result) {
         dismissLoadingDialog();
         if (result.isSuccess()) {
+            mTryShareAgain = false;
             updateFileFromDB();
             
             Intent sendIntent = operation.getSendIntent();
             startActivity(sendIntent);
-            
-        } else { 
-            Toast t = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                    Toast.LENGTH_LONG);
-            t.show();
+        } else {
+            // Detect Failure (403) --> needs Password
+            if (result.getCode() == ResultCode.SHARE_FORBIDDEN) {
+                if (!isTryShareAgain()) {
+                    SharePasswordDialogFragment dialog =
+                            SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()),
+                                    operation.getSendIntent());
+                    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,
+                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+                        Toast.LENGTH_LONG);
+                t.show();
+            }
         } 
     }
     
@@ -605,7 +640,7 @@ implements OnRemoteOperationListener, ComponentsGetter {
     @Override
     public FileUploaderBinder getFileUploaderBinder() {
         return mUploaderBinder;
-    };    
+    }
     
     
 }
index ef9de9e..3ea6822 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
 package com.owncloud.android.ui.activity;
 
 import java.io.File;
-import java.io.IOException;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -96,7 +97,6 @@ import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.UnshareLinkOperation;
 import com.owncloud.android.services.observer.FileObserverService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
-import com.owncloud.android.ui.adapter.FileListListAdapter;
 import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
@@ -115,9 +115,6 @@ import com.owncloud.android.utils.UriUtils;
 
 /**
  * Displays, what files the user has available in his ownCloud.
- * 
- * @author Bartek Przybylski
- * @author David A. Velasco
  */
 
 public class FileDisplayActivity extends HookActivity implements
@@ -649,6 +646,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         if (filePaths != null) {
             String[] remotePaths = new String[filePaths.length];
             String remotePathBase = "";
+
             for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
                 remotePathBase += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
             }
@@ -1110,40 +1108,34 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                                     (synchResult.isException() && synchResult.getException() 
                                             instanceof AuthenticatorException))) {
 
-                            OwnCloudClient client = null;
+
                             try {
-                                OwnCloudAccount ocAccount = 
+                                OwnCloudClient client;
+                                OwnCloudAccount ocAccount =
                                         new OwnCloudAccount(getAccount(), context);
                                 client = (OwnCloudClientManagerFactory.getDefaultSingleton().
                                         removeClientFor(ocAccount));
-                                // TODO get rid of these exceptions
-                            } catch (AccountNotFoundException e) {
-                                e.printStackTrace();
-                            } catch (AuthenticatorException e) {
-                                e.printStackTrace();
-                            } catch (OperationCanceledException e) {
-                                e.printStackTrace();
-                            } catch (IOException e) {
-                                e.printStackTrace();
-                            }
-                            
-                            if (client != null) {
-                                OwnCloudCredentials cred = client.getCredentials();
-                                if (cred != null) {
-                                    AccountManager am = AccountManager.get(context);
-                                    if (cred.authTokenExpires()) {
-                                        am.invalidateAuthToken(
-                                                getAccount().type, 
-                                                cred.getAuthToken()
-                                        );
-                                    } else {
-                                        am.clearPassword(getAccount());
+
+                                if (client != null) {
+                                    OwnCloudCredentials cred = client.getCredentials();
+                                    if (cred != null) {
+                                        AccountManager am = AccountManager.get(context);
+                                        if (cred.authTokenExpires()) {
+                                            am.invalidateAuthToken(
+                                                    getAccount().type,
+                                                    cred.getAuthToken()
+                                            );
+                                        } else {
+                                            am.clearPassword(getAccount());
+                                        }
                                     }
                                 }
+                                requestCredentialsUpdate();
+
+                            } catch (AccountNotFoundException e) {
+                                Log_OC.e(TAG, "Account " + getAccount() + " was removed!", e);
                             }
-                            
-                            requestCredentialsUpdate();
-                            
+
                         }
                     }
                     removeStickyBroadcast(intent);
@@ -1388,7 +1380,11 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
      * TODO
      */
     private void updateNavigationElementsInActionBar(OCFile chosenFile) {
-        ActionBar actionBar = getSupportActionBar(); 
+        ActionBar actionBar = getSupportActionBar();
+
+        // For adding content description tag to a title field in the action bar
+        int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
+
         if (chosenFile == null || mDualPane) {
             // only list of files - set for browsing through folders
             OCFile currentDir = getCurrentDir();
@@ -1397,6 +1393,10 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             actionBar.setDisplayShowTitleEnabled(!noRoot); 
             if (!noRoot) {
                 actionBar.setTitle(getString(R.string.default_display_name_for_root_folder));
+                View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
+                if (actionBarTitleView != null) {    // it's null in Android 2.x
+                    actionBarTitleView.setContentDescription(getString(R.string.default_display_name_for_root_folder));
+                }
             }
             actionBar.setNavigationMode(!noRoot ? ActionBar.NAVIGATION_MODE_STANDARD : ActionBar.NAVIGATION_MODE_LIST);
             actionBar.setListNavigationCallbacks(mDirectories, this);   // assuming mDirectories is updated
@@ -1406,6 +1406,11 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             actionBar.setDisplayShowTitleEnabled(true);
             actionBar.setTitle(chosenFile.getFileName());
             actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
+            View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
+            if (actionBarTitleView != null) {    // it's null in Android 2.x
+                getWindow().getDecorView().findViewById(actionBarTitleId).
+                        setContentDescription(chosenFile.getFileName());
+            }
         }
     }
 
@@ -1763,7 +1768,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             if (file.isFolder()) {
                 return file;
             } else if (getStorageManager() != null) {
-                String parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
+                String parentPath = file.getRemotePath().substring(0,
+                        file.getRemotePath().lastIndexOf(file.getFileName()));
                 return getStorageManager().getFileByPath(parentPath);
             }
         }
@@ -1785,7 +1791,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                                                                         getAccount(), 
                                                                         getApplicationContext()
                                                                       );
-        synchFolderOp.execute(getAccount(), this, null, null);
+        synchFolderOp.execute(getAccount(), MainApp.getAppContext(), this, null, null);
         
         setSupportProgressBarIndeterminateVisibility(true);
 
@@ -1797,7 +1803,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
      */
     public void showUntrustedCertDialog(RemoteOperationResult result) {
         // Show a dialog with the certificate info
-        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException());
+        SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError(
+                (CertificateCombinedException)result.getException());
         FragmentManager fm = getSupportFragmentManager();
         FragmentTransaction ft = fm.beginTransaction();
         dialog.show(ft, DIALOG_UNTRUSTED_CERT);
index e4b1886..62299f2 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -43,6 +45,7 @@ import com.actionbarsherlock.view.Menu;
 import com.actionbarsherlock.view.MenuInflater;
 import com.actionbarsherlock.view.MenuItem;
 import com.actionbarsherlock.view.Window;
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudAccount;
@@ -489,40 +492,33 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
                                     (synchResult.isException() && synchResult.getException() 
                                             instanceof AuthenticatorException))) {
 
-                            OwnCloudClient client = null;
                             try {
-                                OwnCloudAccount ocAccount = 
+                                OwnCloudClient client;
+                                OwnCloudAccount ocAccount =
                                         new OwnCloudAccount(getAccount(), context);
                                 client = (OwnCloudClientManagerFactory.getDefaultSingleton().
                                         removeClientFor(ocAccount));
-                                // TODO get rid of these exceptions
-                            } catch (AccountNotFoundException e) {
-                                e.printStackTrace();
-                            } catch (AuthenticatorException e) {
-                                e.printStackTrace();
-                            } catch (OperationCanceledException e) {
-                                e.printStackTrace();
-                            } catch (IOException e) {
-                                e.printStackTrace();
-                            }
-                            
-                            if (client != null) {
-                                OwnCloudCredentials cred = client.getCredentials();
-                                if (cred != null) {
-                                    AccountManager am = AccountManager.get(context);
-                                    if (cred.authTokenExpires()) {
-                                        am.invalidateAuthToken(
-                                                getAccount().type, 
-                                                cred.getAuthToken()
-                                        );
-                                    } else {
-                                        am.clearPassword(getAccount());
+
+                                if (client != null) {
+                                    OwnCloudCredentials cred = client.getCredentials();
+                                    if (cred != null) {
+                                        AccountManager am = AccountManager.get(context);
+                                        if (cred.authTokenExpires()) {
+                                            am.invalidateAuthToken(
+                                                    getAccount().type,
+                                                    cred.getAuthToken()
+                                            );
+                                        } else {
+                                            am.clearPassword(getAccount());
+                                        }
                                     }
                                 }
+                                requestCredentialsUpdate();
+
+                            } catch (AccountNotFoundException e) {
+                                Log_OC.e(TAG, "Account " + getAccount() + " was removed!", e);
                             }
-                            
-                            requestCredentialsUpdate();
-                            
+
                         }
                     }
                     removeStickyBroadcast(intent);
index 901434e..0d4ab01 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -41,8 +44,6 @@ import com.owncloud.android.utils.DisplayUtils;
  * 
  * Added to show explanations for notifications when the user clicks on them, and there no place
  * better to show them.
- * 
- * @author David A. Velasco
  */
 public class GenericExplanationActivity  extends SherlockFragmentActivity {
 
index 54d65b1..daca8ad 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 793b3d9..5640404 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 22bdb18..d82f33b 100644 (file)
@@ -1,3 +1,24 @@
+
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 package com.owncloud.android.ui.activity;
 
 import android.support.v4.widget.SwipeRefreshLayout;
index 39b973d..76ece93 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2011 Bartek Przybylski
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 7a29073..5585024 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -21,13 +25,17 @@ import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AccountManagerCallback;
 import android.accounts.AccountManagerFuture;
+import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.IBinder;
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
 import android.preference.Preference.OnPreferenceChangeListener;
@@ -50,20 +58,25 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.authentication.AuthenticatorActivity;
+import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.db.DbHandler;
+import com.owncloud.android.files.FileOperationsHelper;
+import com.owncloud.android.files.services.FileDownloader;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.ui.RadioButtonPreference;
 import com.owncloud.android.utils.DisplayUtils;
 
+import java.io.File;
+
 
 /**
  * An Activity that allows the user to change the application's settings.
- * 
- * @author Bartek Przybylski
- * @author David A. Velasco
  */
-public class Preferences extends SherlockPreferenceActivity implements AccountManagerCallback<Boolean> {
+public class Preferences extends SherlockPreferenceActivity
+        implements AccountManagerCallback<Boolean>, ComponentsGetter {
     
     private static final String TAG = "OwnCloudPreferences";
 
@@ -88,6 +101,9 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     private Preference mPrefInstantVideoUploadPathWiFi;
     private String mUploadVideoPath;
 
+    protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
+    protected FileUploader.FileUploaderBinder mUploaderBinder = null;
+    private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
 
     @SuppressWarnings("deprecation")
     @Override
@@ -101,6 +117,14 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
         actionBar.setDisplayHomeAsUpEnabled(true);
         actionBar.setTitle(R.string.actionbar_settings);
 
+        // For adding content description tag to a title field in the action bar
+        int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
+        View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
+        if (actionBarTitleView != null) {    // it's null in Android 2.x
+            getWindow().getDecorView().findViewById(actionBarTitleId).
+                    setContentDescription(getString(R.string.actionbar_settings));
+        }
+
         // Load the accounts category for adding the list of accounts
         mAccountsPrefCategory = (PreferenceCategory) findPreference("accounts_category");
 
@@ -199,13 +223,13 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
                         String username = currentAccount.name.substring(0, currentAccount.name.lastIndexOf('@'));
                         
                         String recommendSubject = String.format(getString(R.string.recommend_subject), appName);
-                        String recommendText = String.format(getString(R.string.recommend_text), appName, downloadUrl, username);
+                        String recommendText = String.format(getString(R.string.recommend_text),
+                                appName, downloadUrl, username);
                         
                         intent.putExtra(Intent.EXTRA_SUBJECT, recommendSubject);
                         intent.putExtra(Intent.EXTRA_TEXT, recommendText);
                         startActivity(intent);
 
-
                         return(true);
 
                     }
@@ -337,6 +361,18 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
        loadInstantUploadPath();
        loadInstantUploadVideoPath();
 
+        /* ComponentsGetter */
+        mDownloadServiceConnection = newTransferenceServiceConnection();
+        if (mDownloadServiceConnection != null) {
+            bindService(new Intent(this, FileDownloader.class), mDownloadServiceConnection,
+                    Context.BIND_AUTO_CREATE);
+        }
+        mUploadServiceConnection = newTransferenceServiceConnection();
+        if (mUploadServiceConnection != null) {
+            bindService(new Intent(this, FileUploader.class), mUploadServiceConnection,
+                    Context.BIND_AUTO_CREATE);
+        }
+
     }
     
     private void toggleInstantPictureOptions(Boolean value){
@@ -402,6 +438,7 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
 
                     // Remove account
                     am.removeAccount(a, this, mHandler);
+                    Log_OC.d(TAG, "Remove an account " + a.name);
                 }
             }
         }
@@ -412,6 +449,18 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     @Override
     public void run(AccountManagerFuture<Boolean> future) {
         if (future.isDone()) {
+            // after remove account
+            Account account = new Account(mAccountName, MainApp.getAccountType());
+            if (!AccountUtils.exists(account, MainApp.getAppContext())) {
+                // Cancel tranfers
+                if (mUploaderBinder != null) {
+                    mUploaderBinder.cancel(account);
+                }
+                if (mDownloaderBinder != null) {
+                    mDownloaderBinder.cancel(account);
+                }
+            }
+
             Account a = AccountUtils.getCurrentOwnCloudAccount(this);
             String accountName = "";
             if (a == null) {
@@ -494,6 +543,16 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
     @Override
     protected void onDestroy() {
         mDbHandler.close();
+
+        if (mDownloadServiceConnection != null) {
+            unbindService(mDownloadServiceConnection);
+            mDownloadServiceConnection = null;
+        }
+        if (mUploadServiceConnection != null) {
+            unbindService(mUploadServiceConnection);
+            mUploadServiceConnection = null;
+        }
+
         super.onDestroy();
     }
 
@@ -637,4 +696,65 @@ public class Preferences extends SherlockPreferenceActivity implements AccountMa
         editor.putString("instant_video_upload_path", mUploadVideoPath);
         editor.commit();
     }
+
+    // Methods for ComponetsGetter
+    @Override
+    public FileDownloader.FileDownloaderBinder getFileDownloaderBinder() {
+        return mDownloaderBinder;
+    }
+
+
+    @Override
+    public FileUploader.FileUploaderBinder getFileUploaderBinder() {
+        return mUploaderBinder;
+    }
+
+    @Override
+    public OperationsService.OperationsServiceBinder getOperationsServiceBinder() {
+        return null;
+    }
+
+    @Override
+    public FileDataStorageManager getStorageManager() {
+        return null;
+    }
+
+    @Override
+    public FileOperationsHelper getFileOperationsHelper() {
+        return null;
+    }
+
+    protected ServiceConnection newTransferenceServiceConnection() {
+        return new PreferencesServiceConnection();
+    }
+
+    /** Defines callbacks for service binding, passed to bindService() */
+    private class PreferencesServiceConnection implements ServiceConnection {
+
+        @Override
+        public void onServiceConnected(ComponentName component, IBinder service) {
+
+            if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
+                mDownloaderBinder = (FileDownloader.FileDownloaderBinder) service;
+
+            } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
+                Log_OC.d(TAG, "Upload service connected");
+                mUploaderBinder = (FileUploader.FileUploaderBinder) service;
+            } else {
+                return;
+            }
+
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName component) {
+            if (component.equals(new ComponentName(Preferences.this, FileDownloader.class))) {
+                Log_OC.d(TAG, "Download service suddenly disconnected");
+                mDownloaderBinder = null;
+            } else if (component.equals(new ComponentName(Preferences.this, FileUploader.class))) {
+                Log_OC.d(TAG, "Upload service suddenly disconnected");
+                mUploaderBinder = null;
+            }
+        }
+    };
 }
index 0918572..7563ea6 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -48,9 +51,6 @@ import com.owncloud.android.utils.FileStorageUtils;
 /**
  * Displays local files and let the user choose what of them wants to upload
  * to the current ownCloud account
- * 
- * @author David A. Velasco
- * 
  */
 
 public class UploadFilesActivity extends FileActivity implements
@@ -289,8 +289,6 @@ public class UploadFilesActivity extends FileActivity implements
      * to upload into the ownCloud local folder.
      * 
      * Maybe an AsyncTask is not strictly necessary, but who really knows.
-     * 
-     * @author David A. Velasco
      */
     private class CheckAvailableSpaceTask extends AsyncTask<Void, Void, Boolean> {
 
index aa3b8aa..d1509f9 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 6c8a132..9dc0fbf 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
  *   Copyright (C) 2012  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -26,14 +29,6 @@ import java.util.List;
 import java.util.Stack;
 import java.util.Vector;
 
-import com.owncloud.android.MainApp;
-import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountAuthenticator;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.services.FileUploader;
-import com.owncloud.android.lib.common.utils.Log_OC;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.app.AlertDialog;
@@ -46,6 +41,7 @@ import android.content.DialogInterface.OnCancelListener;
 import android.content.DialogInterface.OnClickListener;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.res.Resources.NotFoundException;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
@@ -59,32 +55,42 @@ import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.ListView;
 import android.widget.SimpleAdapter;
 import android.widget.Toast;
 
 import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.SherlockListActivity;
 import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountAuthenticator;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ErrorMessageAdapter;
+
 
 /**
  * This can be used to upload things to an ownCloud instance.
- * 
- * @author Bartek Przybylski
- * 
  */
-public class Uploader extends SherlockListActivity implements OnItemClickListener, android.view.View.OnClickListener {
-    private static final String TAG = "ownCloudUploader";
+public class Uploader extends FileActivity
+        implements OnItemClickListener, android.view.View.OnClickListener {
+
+    private static final String TAG = Uploader.class.getSimpleName();
 
-    private Account mAccount;
     private AccountManager mAccountManager;
     private Stack<String> mParents;
     private ArrayList<Parcelable> mStreamsToUpload;
     private boolean mCreateDir;
     private String mUploadPath;
-    private FileDataStorageManager mStorageManager;
     private OCFile mFile;
-
+    private boolean mAccountSelected;
+    
     private final static int DIALOG_NO_ACCOUNT = 0;
     private final static int DIALOG_WAITING = 1;
     private final static int DIALOG_NO_STREAM = 2;
@@ -92,36 +98,72 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
 
     private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
 
+    private final static String KEY_PARENTS = "PARENTS";
+    private final static String KEY_FILE = "FILE";
+    private final static String KEY_ACCOUNT_SELECTED = "ACCOUNT_SELECTED";
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        prepareStreamsToUpload();
+
+        if (savedInstanceState == null) {
+            mParents = new Stack<String>();
+            mAccountSelected = false;
+        } else {
+            mParents = (Stack<String>) savedInstanceState.getSerializable(KEY_PARENTS);
+            mFile = savedInstanceState.getParcelable(KEY_FILE);
+            mAccountSelected = savedInstanceState.getBoolean(KEY_ACCOUNT_SELECTED);
+        }
         super.onCreate(savedInstanceState);
-        mParents = new Stack<String>();
 
         ActionBar actionBar = getSupportActionBar();
         actionBar.setIcon(DisplayUtils.getSeasonalIconId());
 
-        if (prepareStreamsToUpload()) {
+    }
+
+    @Override
+    protected void setAccount(Account account, boolean savedAccount) {
+        if (somethingToUpload()) {
             mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);
             Account[] accounts = mAccountManager.getAccountsByType(MainApp.getAccountType());
             if (accounts.length == 0) {
                 Log_OC.i(TAG, "No ownCloud account is available");
                 showDialog(DIALOG_NO_ACCOUNT);
-            } else if (accounts.length > 1) {
-                Log_OC.i(TAG, "More then one ownCloud is available");
+            } else if (accounts.length > 1 && !mAccountSelected) {
+                Log_OC.i(TAG, "More than one ownCloud is available");
                 showDialog(DIALOG_MULTIPLE_ACCOUNT);
             } else {
-                mAccount = accounts[0];
-                mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
-                initTargetFolder();
-                populateDirectoryList();
-                
+                if (!savedAccount) {
+                    setAccount(accounts[0]);
+                }
             }
-            
+
         } else {
             showDialog(DIALOG_NO_STREAM);
         }
+
+        super.setAccount(account, savedAccount);
     }
-    
+
+    @Override
+    protected void onAccountSet(boolean stateWasRecovered) {
+        super.onAccountSet(mAccountWasRestored);
+        initTargetFolder();
+        populateDirectoryList();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+         Log_OC.d(TAG, "onSaveInstanceState() start");
+        super.onSaveInstanceState(outState);
+        outState.putSerializable(KEY_PARENTS, mParents);
+        //outState.putParcelable(KEY_ACCOUNT, mAccount);
+        outState.putParcelable(KEY_FILE, mFile);
+        outState.putBoolean(KEY_ACCOUNT_SELECTED, mAccountSelected);
+
+        Log_OC.d(TAG, "onSaveInstanceState() end");
+    }
+
     @Override
     protected Dialog onCreateDialog(final int id) {
         final AlertDialog.Builder builder = new Builder(this);
@@ -135,7 +177,8 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
         case DIALOG_NO_ACCOUNT:
             builder.setIcon(android.R.drawable.ic_dialog_alert);
             builder.setTitle(R.string.uploader_wrn_no_account_title);
-            builder.setMessage(String.format(getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
+            builder.setMessage(String.format(
+                    getString(R.string.uploader_wrn_no_account_text), getString(R.string.app_name)));
             builder.setCancelable(false);
             builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
                 @Override
@@ -168,18 +211,20 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
             });
             return builder.create();
         case DIALOG_MULTIPLE_ACCOUNT:
-            CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(MainApp.getAccountType()).length];
+            CharSequence ac[] = new CharSequence[
+                    mAccountManager.getAccountsByType(MainApp.getAccountType()).length];
             for (int i = 0; i < ac.length; ++i) {
-                ac[i] = DisplayUtils.convertIdn(mAccountManager.getAccountsByType(MainApp.getAccountType())[i].name, false);
+                ac[i] = DisplayUtils.convertIdn(
+                        mAccountManager.getAccountsByType(MainApp.getAccountType())[i].name, false);
             }
             builder.setTitle(R.string.common_choose_account);
             builder.setItems(ac, new OnClickListener() {
                 @Override
                 public void onClick(DialogInterface dialog, int which) {
-                    mAccount = mAccountManager.getAccountsByType(MainApp.getAccountType())[which];
-                    mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());
-                    initTargetFolder();
-                    populateDirectoryList();
+                    setAccount(mAccountManager.getAccountsByType(MainApp.getAccountType())[which]);
+                    onAccountSet(mAccountWasRestored);
+                    dialog.dismiss();
+                    mAccountSelected = true;
                 }
             });
             builder.setCancelable(true);
@@ -241,7 +286,7 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         // click on folder in the list
         Log_OC.d(TAG, "on item click");
-        Vector<OCFile> tmpfiles = mStorageManager.getFolderContent(mFile);
+        Vector<OCFile> tmpfiles = getStorageManager().getFolderContent(mFile);
         if (tmpfiles.size() <= 0) return;
         // filter on dirtype
         Vector<OCFile> files = new Vector<OCFile>();
@@ -260,7 +305,8 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
         // click on button
         switch (v.getId()) {
         case R.id.uploader_choose_folder:
-            mUploadPath = "";   // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix
+            mUploadPath = "";   // first element in mParents is root dir, represented by "";
+                                // init mUploadPath with "/" results in a "//" prefix
             for (String p : mParents)
                 mUploadPath += p + OCFile.PATH_SEPARATOR;
             Log_OC.d(TAG, "Uploading file to dir " + mUploadPath);
@@ -268,6 +314,13 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
             uploadFiles();
 
             break;
+            
+        case R.id.uploader_new_folder:
+            CreateFolderDialogFragment dialog = CreateFolderDialogFragment.newInstance(mFile);
+            dialog.show(getSupportFragmentManager(), "createdirdialog");
+            break;
+            
+            
         default:
             throw new IllegalArgumentException("Wrong element clicked");
         }
@@ -289,7 +342,7 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
                 // there is no need for checking for is there more then one
                 // account at this point
                 // since account setup can set only one account at time
-                mAccount = accounts[0];
+                setAccount(accounts[0]);
                 populateDirectoryList();
             }
         }
@@ -297,6 +350,8 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
 
     private void populateDirectoryList() {
         setContentView(R.layout.uploader_layout);
+        
+        ListView mListView = (ListView) findViewById(android.R.id.list);
 
         String current_dir = mParents.peek();
         if(current_dir.equals("")){
@@ -314,9 +369,9 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
         
         Log_OC.d(TAG, "Populating view with content of : " + full_path);
 
-        mFile = mStorageManager.getFileByPath(full_path);
+        mFile = getStorageManager().getFileByPath(full_path);
         if (mFile != null) {
-            Vector<OCFile> files = mStorageManager.getFolderContent(mFile);
+            Vector<OCFile> files = getStorageManager().getFolderContent(mFile);
             List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
             for (OCFile f : files) {
                 HashMap<String, Object> h = new HashMap<String, Object>();
@@ -330,10 +385,15 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
                                                 R.layout.uploader_list_item_layout,
                                                 new String[] {"dirname"},
                                                 new int[] {R.id.textView1});
-            setListAdapter(sa);
-            Button btn = (Button) findViewById(R.id.uploader_choose_folder);
-            btn.setOnClickListener(this);
-            getListView().setOnItemClickListener(this);
+            
+            mListView.setAdapter(sa);
+            Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
+            btnChooseFolder.setOnClickListener(this);
+            
+            Button btnNewFolder = (Button) findViewById(R.id.uploader_new_folder);
+            btnNewFolder.setOnClickListener(this);
+            
+            mListView.setOnItemClickListener(this);
         }
     }
 
@@ -345,13 +405,16 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
         return full_path;
     }
 
-    private boolean prepareStreamsToUpload() {
+    private void prepareStreamsToUpload() {
         if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
             mStreamsToUpload = new ArrayList<Parcelable>();
             mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
         } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
             mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
         }
+    }
+
+    private boolean somethingToUpload() {
         return (mStreamsToUpload != null && mStreamsToUpload.get(0) != null);
     }
 
@@ -371,38 +434,52 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
                        String mimeType = getContentResolver().getType(uri);
                        
                        if (mimeType.contains("image")) {
-                           String[] CONTENT_PROJECTION = { Images.Media.DATA, Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE, Images.Media.SIZE};
-                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                           String[] CONTENT_PROJECTION = { Images.Media.DATA,
+                                   Images.Media.DISPLAY_NAME, Images.Media.MIME_TYPE,
+                                   Images.Media.SIZE};
+                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
+                                   null, null);
                            c.moveToFirst();
                            int index = c.getColumnIndex(Images.Media.DATA);
                            String data = c.getString(index);
                            local.add(data);
-                           remote.add(mUploadPath + c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME)));
+                           remote.add(mUploadPath +
+                                   c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME)));
                        
                        }
                        else if (mimeType.contains("video")) {
-                           String[] CONTENT_PROJECTION = { Video.Media.DATA, Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE, Video.Media.SIZE, Video.Media.DATE_MODIFIED };
-                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                           String[] CONTENT_PROJECTION = { Video.Media.DATA,
+                                   Video.Media.DISPLAY_NAME, Video.Media.MIME_TYPE,
+                                   Video.Media.SIZE, Video.Media.DATE_MODIFIED };
+                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
+                                   null, null);
                            c.moveToFirst();
                            int index = c.getColumnIndex(Video.Media.DATA);
                            String data = c.getString(index);
                            local.add(data);
-                           remote.add(mUploadPath + c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME)));
+                           remote.add(mUploadPath +
+                                   c.getString(c.getColumnIndex(Video.Media.DISPLAY_NAME)));
                           
                        }
                        else if (mimeType.contains("audio")) {
-                           String[] CONTENT_PROJECTION = { Audio.Media.DATA, Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE, Audio.Media.SIZE };
-                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null, null, null);
+                           String[] CONTENT_PROJECTION = { Audio.Media.DATA,
+                                   Audio.Media.DISPLAY_NAME, Audio.Media.MIME_TYPE,
+                                   Audio.Media.SIZE };
+                           Cursor c = getContentResolver().query(uri, CONTENT_PROJECTION, null,
+                                   null, null);
                            c.moveToFirst();
                            int index = c.getColumnIndex(Audio.Media.DATA);
                            String data = c.getString(index);
                            local.add(data);
-                           remote.add(mUploadPath + c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME)));
+                           remote.add(mUploadPath +
+                                   c.getString(c.getColumnIndex(Audio.Media.DISPLAY_NAME)));
                         
                        }
                        else {
-                           String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() + "://", "");
-                           // cut everything whats before mnt. It occured to me that sometimes apps send their name into the URI
+                           String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
+                                   "://", "");
+                           // cut everything whats before mnt. It occurred to me that sometimes
+                           // apps send their name into the URI
                            if (filePath.contains("mnt")) {
                               String splitedFilePath[] = filePath.split("/mnt");
                               filePath = splitedFilePath[1];
@@ -413,7 +490,8 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
                        }
                         
                     } else if (uri.getScheme().equals("file")) {
-                        String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() + "://", "");
+                        String filePath = Uri.decode(uri.toString()).replace(uri.getScheme() +
+                                "://", "");
                         if (filePath.contains("mnt")) {
                            String splitedFilePath[] = filePath.split("/mnt");
                            filePath = splitedFilePath[1];
@@ -433,8 +511,9 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
             Intent intent = new Intent(getApplicationContext(), FileUploader.class);
             intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
             intent.putExtra(FileUploader.KEY_LOCAL_FILE, local.toArray(new String[local.size()]));
-            intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote.toArray(new String[remote.size()]));
-            intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);
+            intent.putExtra(FileUploader.KEY_REMOTE_FILE,
+                    remote.toArray(new String[remote.size()]));
+            intent.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
             startService(intent);
 
             //Save the path to shared preferences
@@ -447,19 +526,59 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
             }
             
         } catch (SecurityException e) {
-            String message = String.format(getString(R.string.uploader_error_forbidden_content), getString(R.string.app_name));
+            String message = String.format(getString(R.string.uploader_error_forbidden_content),
+                    getString(R.string.app_name));
             Toast.makeText(this, message, Toast.LENGTH_LONG).show();            
         }
     }
     
+    @Override
+    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+        super.onRemoteOperationFinish(operation, result);
+        
+      
+        if (operation instanceof CreateFolderOperation) {
+            onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
+        }
+        
+    }
+    
+    /**
+     * Updates the view associated to the activity after the finish of an operation
+     * trying create a new folder
+     * 
+     * @param operation     Creation operation performed.
+     * @param result        Result of the creation.
+     */
+    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()), 
+                        Toast.LENGTH_LONG); 
+                msg.show();
+
+            } catch (NotFoundException e) {
+                Log_OC.e(TAG, "Error while trying to show fail message " , e);
+            }
+        }
+    }
+    
+    
     /**
      *  Loads the target folder initialize shown to the user.
      * 
      *  The target account has to be chosen before this method is called. 
      */
     private void initTargetFolder() {
-        if (mStorageManager == null) {
-            throw new IllegalStateException("Do not call this method before initializing mStorageManager");
+        if (getStorageManager() == null) {
+            throw new IllegalStateException("Do not call this method before " +
+                    "initializing mStorageManager");
         }
         
         SharedPreferences appPreferences = PreferenceManager
@@ -476,7 +595,7 @@ public class Uploader extends SherlockListActivity implements OnItemClickListene
                 mParents.add(dir);
         }
         //Make sure that path still exists, if it doesn't pop the stack and try the previous path
-            while(!mStorageManager.fileExists(generatePath(mParents)) && mParents.size() > 1){
+            while(!getStorageManager().fileExists(generatePath(mParents)) && mParents.size() > 1){
                 mParents.pop();
             }
     }
index b1c3263..2528cb2 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -25,9 +29,6 @@ import android.widget.TextView;
 
 /**
  * TODO
- * 
- * @author masensio
- * @author David A. Velasco
  *
  */
 public class CertificateCombinedExceptionViewAdapter implements SslUntrustedCertDialog.ErrorViewAdapter {
index 93efdf1..0f2536f 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index dcd4d70..d4c1c7b 100644 (file)
@@ -1,6 +1,11 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
+ *   @author Tobias Kaminsky\r
+ *   @author David A. Velasco\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2015 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -25,6 +30,7 @@ import android.accounts.Account;
 import android.content.Context;\r
 import android.content.SharedPreferences;\r
 import android.graphics.Bitmap;\r
+import android.os.Build;\r
 import android.preference.PreferenceManager;\r
 import android.text.format.DateUtils;\r
 import android.view.LayoutInflater;\r
@@ -32,8 +38,8 @@ import android.view.View;
 import android.view.ViewGroup;\r
 import android.widget.AbsListView;\r
 import android.widget.BaseAdapter;\r
-import android.widget.GridView;\r
 import android.widget.ImageView;\r
+import android.widget.LinearLayout;\r
 import android.widget.ListAdapter;\r
 import android.widget.TextView;\r
 \r
@@ -53,10 +59,6 @@ import com.owncloud.android.utils.FileStorageUtils;
 /**\r
  * This Adapter populates a ListView with all files and folders in an ownCloud\r
  * instance.\r
- * \r
- * @author Bartek Przybylski\r
- * @author Tobias Kaminsky\r
- * @author David A. Velasco\r
  */\r
 public class FileListListAdapter extends BaseAdapter implements ListAdapter {\r
     private final static String PERMISSION_SHARED_WITH_ME = "S";\r
@@ -93,7 +95,6 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
         // Read sorting order, default to sort by name ascending\r
         FileStorageUtils.mSortOrder = mAppPreferences.getInt("sortOrder", 0);\r
         FileStorageUtils.mSortAscending = mAppPreferences.getBoolean("sortAscending", true);\r
-\r
         \r
         // initialise thumbnails cache on background thread\r
         new ThumbnailsCacheManager.InitDiskCacheTask().execute();\r
@@ -175,9 +176,13 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
         if (file != null){\r
 \r
             ImageView fileIcon = (ImageView) view.findViewById(R.id.thumbnail);\r
+\r
             fileIcon.setTag(file.getFileId());\r
             TextView fileName;\r
-            String name;\r
+            String name = file.getFileName();\r
+\r
+            LinearLayout linearLayout = (LinearLayout) view.findViewById(R.id.ListItemLayout);\r
+            linearLayout.setContentDescription("LinearLayout-" + name);\r
 \r
             switch (viewType){\r
                 case LIST_ITEM:\r
@@ -195,15 +200,19 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
 \r
                     if (!file.isFolder()) {\r
                         AbsListView parentList = (AbsListView)parent;\r
-                        if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) {\r
-                            checkBoxV.setVisibility(View.GONE);\r
-                        } else {\r
-                            if (parentList.isItemChecked(position)) {\r
-                                checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);\r
+                        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {\r
+                            if (parentList.getChoiceMode() == AbsListView.CHOICE_MODE_NONE) {\r
+                                checkBoxV.setVisibility(View.GONE);\r
                             } else {\r
-                                checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);\r
+                                if (parentList.isItemChecked(position)) {\r
+                                    checkBoxV.setImageResource(\r
+                                            android.R.drawable.checkbox_on_background);\r
+                                } else {\r
+                                    checkBoxV.setImageResource(\r
+                                            android.R.drawable.checkbox_off_background);\r
+                                }\r
+                                checkBoxV.setVisibility(View.VISIBLE);\r
                             }\r
-                            checkBoxV.setVisibility(View.VISIBLE);\r
                         }\r
 \r
                     } else { //Folder\r
@@ -229,15 +238,21 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                     // local state\r
                     ImageView localStateView = (ImageView) view.findViewById(R.id.localFileIndicator);\r
                     localStateView.bringToFront();\r
-                    FileDownloaderBinder downloaderBinder = mTransferServiceGetter.getFileDownloaderBinder();\r
-                    FileUploaderBinder uploaderBinder = mTransferServiceGetter.getFileUploaderBinder();\r
-                    boolean downloading = (downloaderBinder != null && downloaderBinder.isDownloading(mAccount, file));\r
-                    OperationsServiceBinder opsBinder = mTransferServiceGetter.getOperationsServiceBinder();\r
-                    downloading |= (opsBinder != null && opsBinder.isSynchronizing(mAccount, file.getRemotePath()));\r
+                    FileDownloaderBinder downloaderBinder =\r
+                            mTransferServiceGetter.getFileDownloaderBinder();\r
+                    FileUploaderBinder uploaderBinder =\r
+                            mTransferServiceGetter.getFileUploaderBinder();\r
+                    boolean downloading = (downloaderBinder != null &&\r
+                            downloaderBinder.isDownloading(mAccount, file));\r
+                    OperationsServiceBinder opsBinder =\r
+                            mTransferServiceGetter.getOperationsServiceBinder();\r
+                    downloading |= (opsBinder != null &&\r
+                            opsBinder.isSynchronizing(mAccount, file.getRemotePath()));\r
                     if (downloading) {\r
                         localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
                         localStateView.setVisibility(View.VISIBLE);\r
-                    } else if (uploaderBinder != null && uploaderBinder.isUploading(mAccount, file)) {\r
+                    } else if (uploaderBinder != null &&\r
+                            uploaderBinder.isUploading(mAccount, file)) {\r
                         localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
                         localStateView.setVisibility(View.VISIBLE);\r
                     } else if (file.isDown()) {\r
@@ -249,7 +264,8 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
 \r
                     // share with me icon\r
                     if (!file.isFolder()) {\r
-                        ImageView sharedWithMeIconV = (ImageView) view.findViewById(R.id.sharedWithMeIcon);\r
+                        ImageView sharedWithMeIconV = (ImageView)\r
+                                view.findViewById(R.id.sharedWithMeIcon);\r
                         sharedWithMeIconV.bringToFront();\r
                         if (checkIfFileIsSharedWithMe(file)) {\r
                             sharedWithMeIconV.setVisibility(View.VISIBLE);\r
@@ -301,8 +317,10 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                         }\r
                     }\r
                 } else {\r
-                    fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(), file.getFileName()));\r
+                    fileIcon.setImageResource(DisplayUtils.getFileTypeIconId(file.getMimetype(),\r
+                            file.getFileName()));\r
                 }\r
+\r
             } else {\r
                 // Folder\r
                 if (checkIfFileIsSharedWithMe(file)) {\r
index b61d3bf..287c5b9 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -37,14 +40,9 @@ import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.DisplayUtils;
 
-import third_parties.in.srain.cube.GridViewWithHeaderAndFooter;
-
 /**
  * This Adapter populates a ListView with all files and directories contained
  * in a local directory
- * 
- * @author David A. Velasco
- * 
  */
 public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
     
index ae4335e..b5664d5 100644 (file)
@@ -1,3 +1,22 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 package com.owncloud.android.ui.adapter;
 
 import java.io.File;
index a944ead..7165614 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -27,9 +31,6 @@ import android.widget.TextView;
 
 /**
  * TODO
- * 
- * @author masensio
- * @author David A. Velasco
  */
 public class SslCertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter {
     
index 7d2e291..7ac7144 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -24,10 +28,6 @@ import android.widget.TextView;
 
 /**
  * Dialog to show an Untrusted Certificate
- * 
- * @author masensio
- * @author David A. Velasco
- *
  */
 public class SslErrorViewAdapter implements SslUntrustedCertDialog.ErrorViewAdapter {
     
index a290dca..1c8c8c2 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -31,9 +35,6 @@ import android.view.View;
 import android.widget.TextView;
 
 /**
- * 
- * @author masensio
- * @author David A. Velasco
  *
  */
 public class X509CertificateViewAdapter implements SslUntrustedCertDialog.CertificateViewAdapter {
index eef9d09..24d7bc2 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index a9307b9..29ed390 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 91cfbfd..6cf229d 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -33,9 +36,6 @@ import com.owncloud.android.utils.DisplayUtils;
 
 /**
  * Dialog which will be displayed to user upon keep-in-sync file conflict.
- * 
- * @author Bartek Przybylski
- *
  */
 public class ConflictsResolveDialog extends SherlockDialogFragment {
 
index 29b3be2..170fe08 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -37,9 +40,7 @@ import android.widget.Toast;
 /**
  *  Dialog to input the name for a new folder to create.  
  * 
- *  Triggers the folder creation when name is confirmed. 
- *  
- *  @author David A. Velasco
+ *  Triggers the folder creation when name is confirmed.
  */
 public class CreateFolderDialogFragment 
 extends SherlockDialogFragment implements DialogInterface.OnClickListener {
index 080316b..1b99c7b 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index dbd3d99..32fa4c6 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index d0dcfb7..e8e68e7 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 2453404..c3b7ed1 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -20,9 +23,7 @@ package com.owncloud.android.ui.dialog;
 /**
  *  Dialog requiring confirmation before removing a given OCFile.  
  * 
- *  Triggers the removal according to the user response. 
- *  
- *  @author David A. Velasco
+ *  Triggers the removal according to the user response.
  */
 import java.util.Vector;
 
index d285f1e..0e7850b 100644 (file)
@@ -1,4 +1,7 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2014 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
@@ -43,9 +46,7 @@ import com.owncloud.android.ui.activity.ComponentsGetter;
 /**
  *  Dialog to input a new name for a file or folder to rename.  
  * 
- *  Triggers the rename operation when name is confirmed. 
- *  
- *  @author David A. Velasco
+ *  Triggers the rename operation when name is confirmed.
  */
 public class RenameFileDialogFragment
 extends SherlockDialogFragment implements DialogInterface.OnClickListener {
index 3e8a85f..9c34020 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Maria Asensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -35,18 +39,15 @@ import android.webkit.WebView;
 import android.widget.RelativeLayout;
 
 import com.actionbarsherlock.app.SherlockDialogFragment;
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.SsoWebViewClient;
 import com.owncloud.android.authentication.SsoWebViewClient.SsoWebViewClientListener;
-import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.utils.Log_OC;
 
 
 /**
  * Dialog to show the WebView for SAML Authentication
- * 
- * @author Maria Asensio
- * @author David A. Velasco
  */
 public class SamlWebViewDialog extends SherlockDialogFragment {
 
@@ -69,10 +70,9 @@ public class SamlWebViewDialog extends SherlockDialogFragment {
 
     /**
      * Public factory method to get dialog instances.
-     * 
-     * @param handler
-     * @param Url           Url to open at WebView
-     * @param targetURL     mBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType)
+     *
+     * @param url           Url to open at WebView
+     * @param targetUrl     mBaseUrl + AccountUtils.getWebdavPath(mDiscoveredVersion, mCurrentAuthTokenType)
      * @return              New dialog instance, ready to show.
      */
     public static SamlWebViewDialog newInstance(String url, String targetUrl) {
@@ -100,7 +100,8 @@ public class SamlWebViewDialog extends SherlockDialogFragment {
             mWebViewClient = new SsoWebViewClient(activity, mHandler, mSsoWebViewClientListener);
             
        } catch (ClassCastException e) {
-            throw new ClassCastException(activity.toString() + " must implement " + SsoWebViewClientListener.class.getSimpleName());
+            throw new ClassCastException(activity.toString() + " must implement " +
+                    SsoWebViewClientListener.class.getSimpleName());
         }
     }
 
@@ -129,11 +130,13 @@ public class SamlWebViewDialog extends SherlockDialogFragment {
     @SuppressWarnings("deprecation")
     @SuppressLint("SetJavaScriptEnabled")
     @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
         Log_OC.v(TAG, "onCreateView, savedInsanceState is " + savedInstanceState);
         
         // Inflate layout of the dialog  
-        RelativeLayout ssoRootView = (RelativeLayout) inflater.inflate(R.layout.sso_dialog, container, false);  // null parent view because it will go in the dialog layout
+        RelativeLayout ssoRootView = (RelativeLayout) inflater.inflate(R.layout.sso_dialog,
+                container, false);  // null parent view because it will go in the dialog layout
         
         if (mSsoWebView == null) {
             // initialize the WebView
@@ -147,7 +150,7 @@ public class SamlWebViewDialog extends SherlockDialogFragment {
             webSettings.setBuiltInZoomControls(false);
             webSettings.setLoadWithOverviewMode(false);
             webSettings.setSavePassword(false);
-            webSettings.setUserAgentString(OwnCloudClient.USER_AGENT);
+            webSettings.setUserAgentString(MainApp.getUserAgent());
             webSettings.setSaveFormData(false);
             
             CookieManager cookieManager = CookieManager.getInstance();
index 2876f7b..fc88e5d 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -50,8 +53,6 @@ import com.owncloud.android.ui.activity.FileActivity;
 /**
  * Dialog showing a list activities able to resolve a given Intent, 
  * filtering out the activities matching give package names.
- * 
- * @author David A. Velasco
  */
 public class ShareLinkToDialog  extends SherlockDialogFragment {
     
@@ -146,7 +147,7 @@ public class ShareLinkToDialog  extends SherlockDialogFragment {
                             } else {
                                 // Create a new share resource
                                 ((ComponentsGetter)getSherlockActivity()).getFileOperationsHelper()
-                                    .shareFileWithLinkToApp(mFile, mIntent);
+                                    .shareFileWithLinkToApp(mFile, "", mIntent);
                             }
                         }
         })
diff --git a/src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java b/src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java
new file mode 100644 (file)
index 0000000..d8f507b
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ *   ownCloud Android client application
+ *   @author masensio
+ *   Copyright (C) 2015 ownCloud Inc.
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License version 2,
+ *   as published by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package com.owncloud.android.ui.dialog;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.activity.FileActivity;
+
+/**
+ * Dialog to input the password for sharing a file/folder.
+ *
+ * Triggers the share when the password is introduced.
+ */
+
+public class SharePasswordDialogFragment extends SherlockDialogFragment
+        implements DialogInterface.OnClickListener {
+
+    private static final String ARG_FILE = "FILE";
+    private static final String ARG_SEND_INTENT = "SEND_INTENT";
+
+    public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT";
+
+    private OCFile mFile;
+    private Intent mSendIntent;
+
+    /**
+     * Public factory method to create new SharePasswordDialogFragment instances.
+     *
+     * @param file
+     * @param sendIntent
+     * @return              Dialog ready to show.
+     */
+    public static SharePasswordDialogFragment newInstance(OCFile file, Intent sendIntent) {
+        SharePasswordDialogFragment frag = new SharePasswordDialogFragment();
+        Bundle args = new Bundle();
+        args.putParcelable(ARG_FILE, file);
+        args.putParcelable(ARG_SEND_INTENT, sendIntent);
+        frag.setArguments(args);
+        return frag;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        mFile = getArguments().getParcelable(ARG_FILE);
+        mSendIntent = getArguments().getParcelable(ARG_SEND_INTENT);
+
+        // Inflate the layout for the dialog
+        LayoutInflater inflater = getActivity().getLayoutInflater();
+        View v = inflater.inflate(R.layout.password_dialog, null);
+
+        // Setup layout
+        EditText inputText = ((EditText)v.findViewById(R.id.share_password));
+        inputText.setText("");
+        inputText.requestFocus();
+
+        // Build the dialog
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        builder.setView(v)
+               .setPositiveButton(R.string.common_ok, this)
+               .setNegativeButton(R.string.common_cancel, this)
+               .setTitle(R.string.share_link_password_title);
+        Dialog d = builder.create();
+        d.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+        return d;
+    }
+
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (which == AlertDialog.BUTTON_POSITIVE) {
+            // Enable the flag "Share again"
+            ((FileActivity) getSherlockActivity()).setTryShareAgain(true);
+
+            String password =
+                    ((TextView)(getDialog().findViewById(R.id.share_password)))
+                        .getText().toString();
+
+            if (password.length() <= 0) {
+                Toast.makeText(
+                        getActivity(),
+                        R.string.share_link_empty_password,
+                        Toast.LENGTH_LONG).show();
+                return;
+            }
+
+            // Share the file
+            ((FileActivity)getSherlockActivity()).getFileOperationsHelper()
+                                    .shareFileWithLinkToApp(mFile, password, mSendIntent);
+
+        } else {
+            // Disable the flag "Share again"
+            ((FileActivity) getSherlockActivity()).setTryShareAgain(false);
+        }
+    }
+}
index 167177b..6658260 100644 (file)
@@ -1,5 +1,9 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -47,10 +51,7 @@ import com.owncloud.android.ui.adapter.X509CertificateViewAdapter;
  * to decide trust on it or not.
  * 
  * Abstract implementation of common functionality for different dialogs that
- * get the information about the error and the certificate from different classes. 
- * 
- * @author masensio
- * @author David A. Velasco
+ * get the information about the error and the certificate from different classes.
  */
 public class SslUntrustedCertDialog extends SherlockDialogFragment {
     
index db20a5c..1e31c0c 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -46,8 +49,6 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 
 /**
  * Dialog to request the user about a certificate that could not be validated with the certificates store in the system.
- * 
- * @author David A. Velasco
  */
 public class SslValidatorDialog extends Dialog {
 
index 3a71139..dae43f8 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index f096103..1552da1 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 5abf55d..5a8da70 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 8b014af..fb58be3 100644 (file)
@@ -1,4 +1,6 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
  *   Copyright (C) 2012-2015 ownCloud Inc.
  *
@@ -20,7 +22,7 @@ package com.owncloud.android.ui.fragment;
 
 import java.util.ArrayList;
 
-import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.widget.SwipeRefreshLayout;
 import android.view.LayoutInflater;
@@ -31,6 +33,7 @@ import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.GridView;
 import android.widget.ListAdapter;
+import android.widget.ListView;
 import android.widget.TextView;
 
 import com.actionbarsherlock.app.SherlockFragment;
@@ -78,10 +81,14 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
 
     private ListAdapter mAdapter;
 
-
     protected void setListAdapter(ListAdapter listAdapter) {
         mAdapter = listAdapter;
-        mCurrentListView.setAdapter(listAdapter);
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            mCurrentListView.setAdapter(listAdapter);
+        } else {
+            ((ListView)mCurrentListView).setAdapter(listAdapter);
+        }
+
         mCurrentListView.invalidate();
     }
 
@@ -214,7 +221,8 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
      */
     protected int getReferencePosition() {
         if (mCurrentListView != null) {
-            return (mCurrentListView.getFirstVisiblePosition() + mCurrentListView.getLastVisiblePosition()) / 2;
+            return (mCurrentListView.getFirstVisiblePosition() +
+                    mCurrentListView.getLastVisiblePosition()) / 2;
         } else {
             return 0;
         }
@@ -232,7 +240,8 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
             final int firstPosition = mFirstPositions.remove(mFirstPositions.size() -1);
             int top = mTops.remove(mTops.size() - 1);
 
-            Log_OC.v(TAG, "Setting selection to position: " + firstPosition + "; top: " + top + "; index: " + index);
+            Log_OC.v(TAG, "Setting selection to position: " + firstPosition + "; top: "
+                    + top + "; index: " + index);
 
             if (mCurrentListView == mListView) {
                 if (mHeightCell*index <= mListView.getHeight()) {
@@ -329,8 +338,8 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
 
     private void onCreateSwipeToRefresh(SwipeRefreshLayout refreshLayout) {
         // Colors in animations: background
-        refreshLayout.setColorScheme(R.color.background_color, R.color.background_color, R.color.background_color,
-                R.color.background_color);
+        refreshLayout.setColorScheme(R.color.background_color, R.color.background_color,
+                R.color.background_color, R.color.background_color);
 
         refreshLayout.setOnRefreshListener(this);
     }
@@ -346,10 +355,13 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
         }
     }
 
-
     protected void setChoiceMode(int choiceMode) {
-        mListView.setChoiceMode(choiceMode);
-        mGridView.setChoiceMode(choiceMode);
+        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            mListView.setChoiceMode(choiceMode);
+            mGridView.setChoiceMode(choiceMode);
+        } else {
+            ((ListView)mListView).setChoiceMode(choiceMode);
+        }
     }
 
     protected void registerForContextMenu() {
@@ -384,8 +396,8 @@ implements OnItemClickListener, OnEnforceableRefreshListener {
             mListFooterView.invalidate();
 
         } else {
-            mGridView.removeFooterView(mGridFooterView);
-            mListView.removeFooterView(mListFooterView);
+//            mGridView.removeFooterView(mGridFooterView);
+//            mListView.removeFooterView(mListFooterView);
         }
     }
 
index 30ac7e1..6a19957 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -52,9 +56,6 @@ import com.owncloud.android.utils.DisplayUtils;
 
 /**
  * This Fragment is used to display the details about a file.
- * 
- * @author Bartek Przybylski
- * @author David A. Velasco
  */
 public class FileDetailFragment extends FileFragment implements OnClickListener {
 
@@ -536,9 +537,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
 
     
     /**
-     * Helper class responsible for updating the progress bar shown for file uploading or downloading  
-     * 
-     * @author David A. Velasco
+     * Helper class responsible for updating the progress bar shown for file uploading or downloading
      */
     private class ProgressListener implements OnDatatransferProgressListener {
         int mLastPercent = 0;
index 3e6fa31..87dca25 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013  ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015  ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -30,9 +33,6 @@ import com.owncloud.android.ui.activity.ComponentsGetter;
 
 /**
  * Common methods for {@link Fragment}s containing {@link OCFile}s
- * 
- * @author David A. Velasco
- *
  */
 public class FileFragment extends SherlockFragment {
     
@@ -102,8 +102,6 @@ public class FileFragment extends SherlockFragment {
     /**
      * Interface to implement by any Activity that includes some instance of FileListFragment
      * Interface to implement by any Activity that includes some instance of FileFragment
-     * 
-     * @author David A. Velasco
      */
     public interface ContainerActivity extends ComponentsGetter {
 
index f8920c8..8a268b7 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -38,9 +41,6 @@ import com.owncloud.android.ui.adapter.LocalFileListAdapter;
 
 /**
  * A Fragment that lists all files and folders in a given LOCAL path.
- * 
- * @author David A. Velasco
- * 
  */
 public class LocalFileListFragment extends ExtendedListFragment {
     private static final String TAG = "LocalFileListFragment";
@@ -64,7 +64,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
         try {
             mContainerActivity = (ContainerActivity) activity;
         } catch (ClassCastException e) {
-            throw new ClassCastException(activity.toString() + " must implement " + LocalFileListFragment.ContainerActivity.class.getSimpleName());
+            throw new ClassCastException(activity.toString() + " must implement " +
+                    LocalFileListFragment.ContainerActivity.class.getSimpleName());
         }
     }
     
@@ -99,7 +100,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
     }
     
     /**
-     * Checks the file clicked over. Browses inside if it is a directory. Notifies the container activity in any case.
+     * Checks the file clicked over. Browses inside if it is a directory.
+     * Notifies the container activity in any case.
      */
     @Override
     public void onItemClick(AdapterView<?> l, View v, int position, long id) {
@@ -117,7 +119,7 @@ public class LocalFileListFragment extends ExtendedListFragment {
             } else {    /// Click on a file
                 ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox);
                 if (checkBoxV != null) {
-                    if (getListView().isItemChecked(position)) {
+                    if (((ListView)getListView()).isItemChecked(position)) {
                         checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
                     } else {
                         checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
@@ -182,7 +184,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
             if(mDirectory != null){
                 directory = mDirectory;
             } else {
-                directory = Environment.getExternalStorageDirectory();  // TODO be careful with the state of the storage; could not be available
+                directory = Environment.getExternalStorageDirectory();
+                // TODO be careful with the state of the storage; could not be available
                 if (directory == null) return; // no files to show
             }
         }
@@ -194,7 +197,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
             directory = directory.getParentFile();
         }
 
-        mCurrentListView.clearChoices();   // by now, only files in the same directory will be kept as selected
+        // by now, only files in the same directory will be kept as selected
+        ((ListView)mCurrentListView).clearChoices();
         mAdapter.swapDirectory(directory);
         if (mDirectory == null || !mDirectory.equals(directory)) {
             mCurrentListView.setSelection(0);
@@ -210,11 +214,12 @@ public class LocalFileListFragment extends ExtendedListFragment {
      */
     public String[] getCheckedFilePaths() {
         ArrayList<String> result = new ArrayList<String>();
-        SparseBooleanArray positions = mCurrentListView.getCheckedItemPositions();
+        SparseBooleanArray positions = ((ListView)mCurrentListView).getCheckedItemPositions();
         if (positions.size() > 0) {
             for (int i = 0; i < positions.size(); i++) {
                 if (positions.get(positions.keyAt(i)) == true) {
-                    result.add(((File) mCurrentListView.getItemAtPosition(positions.keyAt(i))).getAbsolutePath());
+                    result.add(((File) mCurrentListView.getItemAtPosition(
+                            positions.keyAt(i))).getAbsolutePath());
                 }
             }
 
@@ -226,8 +231,6 @@ public class LocalFileListFragment extends ExtendedListFragment {
     
     /**
      * Interface to implement by any Activity that includes some instance of LocalFileListFragment
-     * 
-     * @author David A. Velasco
      */
     public interface ContainerActivity {
 
@@ -239,7 +242,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
         public void onDirectoryClick(File directory);
         
         /**
-         * Callback method invoked when a file (non directory) is clicked by the user on the files list
+         * Callback method invoked when a file (non directory)
+         * is clicked by the user on the files list
          *  
          * @param file
          */
@@ -247,7 +251,8 @@ public class LocalFileListFragment extends ExtendedListFragment {
         
         
         /**
-         * Callback method invoked when the parent activity is fully created to get the directory to list firstly.
+         * Callback method invoked when the parent activity
+         * is fully created to get the directory to list firstly.
          * 
          * @return  Directory to list firstly. Can be NULL.
          */
index 3b626b6..60ac78d 100644 (file)
@@ -1,6 +1,11 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartek Przybylski
+ *   @author masensio
+ *   @author David A. Velasco
  *   Copyright (C) 2011  Bartek Przybylski
- *   Copyright (C) 2012-2014 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -50,10 +55,6 @@ import com.owncloud.android.utils.FileStorageUtils;
  * A Fragment that lists all files and folders in a given path.
  * 
  * TODO refactorize to get rid of direct dependency on FileDisplayActivity
- * 
- * @author Bartek Przybylski
- * @author masensio
- * @author David A. Velasco
  */
 public class OCFileListFragment extends ExtendedListFragment {
     
index 7af29c6..99a4d44 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
- * 
- *   Copyright (C) 2012-2013  ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015  ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -42,8 +44,6 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 
 /**
  * This Fragment is used to monitor the progress of a file downloading.
- * 
- * @author David A. Velasco
  */
 public class FileDownloadFragment extends FileFragment implements OnClickListener {
 
@@ -308,9 +308,7 @@ public class FileDownloadFragment extends FileFragment implements OnClickListene
 
     
     /**
-     * Helper class responsible for updating the progress bar shown for file uploading or downloading  
-     * 
-     * @author David A. Velasco
+     * Helper class responsible for updating the progress bar shown for file uploading or downloading
      */
     private class ProgressListener implements OnDatatransferProgressListener {
         int mLastPercent = 0;
index 213aee0..1f6ab80 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013  ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015  ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -62,8 +65,6 @@ import com.owncloud.android.utils.DisplayUtils;
 
 /**
  *  Holds a swiping galley where image files contained in an ownCloud directory are shown
- *  
- *  @author David A. Velasco
  */
 public class PreviewImageActivity extends FileActivity implements 
  FileFragment.ContainerActivity,
index 0995793..9d1cd60 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc. 
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -54,8 +57,8 @@ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.BitmapUtils;
-import com.owncloud.android.utils.TouchImageViewCustom;
 
+import third_parties.michaelOrtiz.TouchImageViewCustom;
 
 
 /**
@@ -64,8 +67,6 @@ import com.owncloud.android.utils.TouchImageViewCustom;
  * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will produce an {@link IllegalStateException}.
  * 
  * If the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on instantiation too.
- * 
- * @author David A. Velasco
  */
 public class PreviewImageFragment extends FileFragment {
 
index 3c15de7..14ae34f 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013  ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015  ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -38,9 +41,7 @@ import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.FileStorageUtils;
 
 /**
- * Adapter class that provides Fragment instances  
- * 
- * @author David A. Velasco
+ * Adapter class that provides Fragment instances
  */
 //public class PreviewImagePagerAdapter extends PagerAdapter {
 public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
index 7d6489b..d82faa5 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc. 
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -64,8 +67,6 @@ import com.owncloud.android.ui.fragment.FileFragment;
  * Trying to get an instance with NULL {@link OCFile} or ownCloud {@link Account} values will produce an {@link IllegalStateException}.
  * 
  * By now, if the {@link OCFile} passed is not downloaded, an {@link IllegalStateException} is generated on instantiation too.
- * 
- * @author David A. Velasco
  */
 public class PreviewMediaFragment extends FileFragment implements
         OnTouchListener {
index 39e8e23..938d52d 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -45,9 +48,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
  *  Used as an utility to preview video files contained in an ownCloud account.
  *  
  *  Currently, it always plays in landscape mode, full screen. When the playback ends,
- *  the activity is finished. 
- *  
- *  @author David A. Velasco
+ *  the activity is finished.
  */
 public class PreviewVideoActivity extends FileActivity implements OnCompletionListener, OnPreparedListener, OnErrorListener {
 
index 92824f4..ce7590d 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -30,8 +33,6 @@ import java.io.File;
 
 /**
  * Utility class with methods for decoding Bitmaps.
- * 
- * @author David A. Velasco
  */
 public class BitmapUtils {
     
index 999700f..905f60b 100644 (file)
@@ -1,6 +1,10 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
+ *   @author David A. Velasco\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -40,9 +44,6 @@ import com.owncloud.android.datamodel.OCFile;
 \r
 /**\r
  * A helper class for some string operations.\r
- * \r
- * @author Bartek Przybylski\r
- * @author David A. Velasco\r
  */\r
 public class DisplayUtils {\r
     \r
index 9f13804..12a1a5a 100644 (file)
@@ -1,4 +1,7 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
+ *   @author masensio
  *   Copyright (C) 2014 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
@@ -41,10 +44,8 @@ import com.owncloud.android.operations.UnshareLinkOperation;
 import com.owncloud.android.operations.UploadFileOperation;
 
 /**
- * Class to choose proper error messages to show to the user depending on the results of operations, always following the same policy
- * 
- * @author masensio
- *
+ * Class to choose proper error messages to show to the user depending on the results of operations,
+ * always following the same policy
  */
 
 public class ErrorMessageAdapter {
index b0c337d..e70302f 100644 (file)
@@ -1,5 +1,8 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2013 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   @author David A. Velasco
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -41,8 +44,6 @@ import android.webkit.MimeTypeMap;
 
 /**
  * Static methods to help in access to local file system.
- * 
- * @author David A. Velasco
  */
 public class FileStorageUtils {
     public static Integer mSortOrder;
index 13ead88..6292a2b 100644 (file)
@@ -1,6 +1,9 @@
-/* ownCloud Android client application\r
+/**\r
+ *   ownCloud Android client application\r
+ *\r
+ *   @author Bartek Przybylski\r
  *   Copyright (C) 2011  Bartek Przybylski\r
- *   Copyright (C) 2012-2013 ownCloud Inc.\r
+ *   Copyright (C) 2015 ownCloud Inc.\r
  *\r
  *   This program is free software: you can redistribute it and/or modify\r
  *   it under the terms of the GNU General Public License version 2,\r
@@ -19,9 +22,6 @@ package com.owncloud.android.utils;
 \r
 /**\r
  * Represents a session to an ownCloud instance\r
- * \r
- * @author Bartek Przybylski\r
- * \r
  */\r
 public class OwnCloudSession {\r
     private String mSessionName;\r
index be44f8f..4a70631 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
diff --git a/src/com/owncloud/android/utils/TouchImageViewCustom.java b/src/com/owncloud/android/utils/TouchImageViewCustom.java
deleted file mode 100644 (file)
index a0f7b79..0000000
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*
- * TouchImageView.java
- * By: Michael Ortiz
- * Updated By: Patrick Lackemacher
- * Updated By: Babay88
- * Updated By: @ipsilondev
- * Updated By: hank-cp
- * Updated By: singpolyma
- * -------------------
- * Extends Android ImageView to include pinch zooming, panning, fling and double tap zoom.
- */
-
-package com.owncloud.android.utils;
-
-import com.owncloud.android.ui.preview.ImageViewCustom;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.ScaleGestureDetector;
-import android.view.View;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.widget.OverScroller;
-import android.widget.Scroller;
-
-public class TouchImageViewCustom extends ImageViewCustom {
-    private static final String DEBUG = "DEBUG";
-       
-       //
-       // SuperMin and SuperMax multipliers. Determine how much the image can be
-       // zoomed below or above the zoom boundaries, before animating back to the
-       // min/max zoom boundary.
-       //
-       private static final float SUPER_MIN_MULTIPLIER = .75f;
-       private static final float SUPER_MAX_MULTIPLIER = 1.25f;
-
-    //
-    // Scale of image ranges from minScale to maxScale, where minScale == 1
-    // when the image is stretched to fit view.
-    //
-    private float normalizedScale;
-    
-    //
-    // Matrix applied to image. MSCALE_X and MSCALE_Y should always be equal.
-    // MTRANS_X and MTRANS_Y are the other values used. prevMatrix is the matrix
-    // saved prior to the screen rotating.
-    //
-       private Matrix matrix, prevMatrix;
-
-    private static enum State { NONE, DRAG, ZOOM, FLING, ANIMATE_ZOOM };
-    private State state;
-
-    private float minScale;
-    private float maxScale;
-    private float superMinScale;
-    private float superMaxScale;
-    private float[] m;
-    
-    private Context context;
-    private Fling fling;
-    
-    private ScaleType mScaleType;
-    
-    private boolean imageRenderedAtLeastOnce;
-    private boolean onDrawReady;
-    
-    private ZoomVariables delayedZoomVariables;
-
-    //
-    // Size of view and previous view size (ie before rotation)
-    //
-    private int viewWidth, viewHeight, prevViewWidth, prevViewHeight;
-    
-    //
-    // Size of image when it is stretched to fit view. Before and After rotation.
-    //
-    private float matchViewWidth, matchViewHeight, prevMatchViewWidth, prevMatchViewHeight;
-    
-    private ScaleGestureDetector mScaleDetector;
-    private GestureDetector mGestureDetector;
-    private GestureDetector.OnDoubleTapListener doubleTapListener = null;
-    private OnTouchListener userTouchListener = null;
-    private OnTouchImageViewListener touchImageViewListener = null;
-
-    public TouchImageViewCustom(Context context) {
-        super(context);
-        sharedConstructing(context);
-    }
-
-    public TouchImageViewCustom(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        sharedConstructing(context);
-    }
-    
-    public TouchImageViewCustom(Context context, AttributeSet attrs, int defStyle) {
-       super(context, attrs, defStyle);
-       sharedConstructing(context);
-    }
-    
-    private void sharedConstructing(Context context) {
-        super.setClickable(true);
-        this.context = context;
-        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
-        mGestureDetector = new GestureDetector(context, new GestureListener());
-        matrix = new Matrix();
-        prevMatrix = new Matrix();
-        m = new float[9];
-        normalizedScale = 1;
-        if (mScaleType == null) {
-               mScaleType = ScaleType.FIT_CENTER;
-        }
-        minScale = 1;
-        maxScale = 3;
-        superMinScale = SUPER_MIN_MULTIPLIER * minScale;
-        superMaxScale = SUPER_MAX_MULTIPLIER * maxScale;
-        setImageMatrix(matrix);
-        setScaleType(ScaleType.MATRIX);
-        setState(State.NONE);
-        onDrawReady = false;
-        super.setOnTouchListener(new PrivateOnTouchListener());
-    }
-
-    @Override
-    public void setOnTouchListener(View.OnTouchListener l) {
-        userTouchListener = l;
-    }
-    
-    public void setOnTouchImageViewListener(OnTouchImageViewListener l) {
-       touchImageViewListener = l;
-    }
-
-    public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener l) {
-        doubleTapListener = l;
-    }
-
-    @Override
-    public void setImageResource(int resId) {
-       super.setImageResource(resId);
-       savePreviousImageValues();
-       fitImageToView();
-    }
-    
-    @Override
-    public void setImageBitmap(Bitmap bm) {
-       super.setImageBitmap(bm);
-       savePreviousImageValues();
-       fitImageToView();
-    }
-    
-    @Override
-    public void setImageDrawable(Drawable drawable) {
-       super.setImageDrawable(drawable);
-       savePreviousImageValues();
-       fitImageToView();
-    }
-    
-    @Override
-    public void setImageURI(Uri uri) {
-       super.setImageURI(uri);
-       savePreviousImageValues();
-       fitImageToView();
-    }
-    
-    @Override
-    public void setScaleType(ScaleType type) {
-       if (type == ScaleType.FIT_START || type == ScaleType.FIT_END) {
-               throw new UnsupportedOperationException("TouchImageView does not support FIT_START or FIT_END");
-       }
-       if (type == ScaleType.MATRIX) {
-               super.setScaleType(ScaleType.MATRIX);
-               
-       } else {
-               mScaleType = type;
-               if (onDrawReady) {
-                       //
-                       // If the image is already rendered, scaleType has been called programmatically
-                       // and the TouchImageView should be updated with the new scaleType.
-                       //
-                       setZoom(this);
-               }
-       }
-    }
-    
-    @Override
-    public ScaleType getScaleType() {
-       return mScaleType;
-    }
-    
-    /**
-     * Returns false if image is in initial, unzoomed state. False, otherwise.
-     * @return true if image is zoomed
-     */
-    public boolean isZoomed() {
-       return normalizedScale != 1;
-    }
-    
-    /**
-     * Return a Rect representing the zoomed image.
-     * @return rect representing zoomed image
-     */
-    public RectF getZoomedRect() {
-       if (mScaleType == ScaleType.FIT_XY) {
-               throw new UnsupportedOperationException("getZoomedRect() not supported with FIT_XY");
-       }
-       PointF topLeft = transformCoordTouchToBitmap(0, 0, true);
-       PointF bottomRight = transformCoordTouchToBitmap(viewWidth, viewHeight, true);
-       
-       float w = getDrawable().getIntrinsicWidth();
-       float h = getDrawable().getIntrinsicHeight();
-       return new RectF(topLeft.x / w, topLeft.y / h, bottomRight.x / w, bottomRight.y / h);
-    }
-    
-    /**
-     * Save the current matrix and view dimensions
-     * in the prevMatrix and prevView variables.
-     */
-    private void savePreviousImageValues() {
-       if (matrix != null && viewHeight != 0 && viewWidth != 0) {
-               matrix.getValues(m);
-               prevMatrix.setValues(m);
-               prevMatchViewHeight = matchViewHeight;
-               prevMatchViewWidth = matchViewWidth;
-               prevViewHeight = viewHeight;
-               prevViewWidth = viewWidth;
-       }
-    }
-    
-    @Override
-    public Parcelable onSaveInstanceState() {
-       Bundle bundle = new Bundle();
-       bundle.putParcelable("instanceState", super.onSaveInstanceState());
-       bundle.putFloat("saveScale", normalizedScale);
-       bundle.putFloat("matchViewHeight", matchViewHeight);
-       bundle.putFloat("matchViewWidth", matchViewWidth);
-       bundle.putInt("viewWidth", viewWidth);
-       bundle.putInt("viewHeight", viewHeight);
-       matrix.getValues(m);
-       bundle.putFloatArray("matrix", m);
-       bundle.putBoolean("imageRendered", imageRenderedAtLeastOnce);
-       return bundle;
-    }
-    
-    @Override
-    public void onRestoreInstanceState(Parcelable state) {
-       if (state instanceof Bundle) {
-               Bundle bundle = (Bundle) state;
-               normalizedScale = bundle.getFloat("saveScale");
-               m = bundle.getFloatArray("matrix");
-               prevMatrix.setValues(m);
-               prevMatchViewHeight = bundle.getFloat("matchViewHeight");
-               prevMatchViewWidth = bundle.getFloat("matchViewWidth");
-               prevViewHeight = bundle.getInt("viewHeight");
-               prevViewWidth = bundle.getInt("viewWidth");
-               imageRenderedAtLeastOnce = bundle.getBoolean("imageRendered");
-               super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
-               return;
-       }
-
-       super.onRestoreInstanceState(state);
-    }
-    
-    @Override
-    protected void onDraw(Canvas canvas) {
-       onDrawReady = true;
-       imageRenderedAtLeastOnce = true;
-       if (delayedZoomVariables != null) {
-               setZoom(delayedZoomVariables.scale, delayedZoomVariables.focusX, delayedZoomVariables.focusY, delayedZoomVariables.scaleType);
-               delayedZoomVariables = null;
-       }
-       super.onDraw(canvas);
-    }
-    
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-       super.onConfigurationChanged(newConfig);
-       savePreviousImageValues();
-    }
-    
-    /**
-     * Get the max zoom multiplier.
-     * @return max zoom multiplier.
-     */
-    public float getMaxZoom() {
-       return maxScale;
-    }
-
-    /**
-     * Set the max zoom multiplier. Default value: 3.
-     * @param max max zoom multiplier.
-     */
-    public void setMaxZoom(float max) {
-        maxScale = max;
-        superMaxScale = SUPER_MAX_MULTIPLIER * maxScale;
-    }
-    
-    /**
-     * Get the min zoom multiplier.
-     * @return min zoom multiplier.
-     */
-    public float getMinZoom() {
-       return minScale;
-    }
-    
-    /**
-     * Get the current zoom. This is the zoom relative to the initial
-     * scale, not the original resource.
-     * @return current zoom multiplier.
-     */
-    public float getCurrentZoom() {
-       return normalizedScale;
-    }
-    
-    /**
-     * Set the min zoom multiplier. Default value: 1.
-     * @param min min zoom multiplier.
-     */
-    public void setMinZoom(float min) {
-       minScale = min;
-       superMinScale = SUPER_MIN_MULTIPLIER * minScale;
-    }
-    
-    /**
-     * Reset zoom and translation to initial state.
-     */
-    public void resetZoom() {
-       normalizedScale = 1;
-       fitImageToView();
-    }
-    
-    /**
-     * Set zoom to the specified scale. Image will be centered by default.
-     * @param scale
-     */
-    public void setZoom(float scale) {
-       setZoom(scale, 0.5f, 0.5f);
-    }
-    
-    /**
-     * Set zoom to the specified scale. Image will be centered around the point
-     * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
-     * as a fraction from the left and top of the view. For example, the top left 
-     * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
-     * @param scale
-     * @param focusX
-     * @param focusY
-     */
-    public void setZoom(float scale, float focusX, float focusY) {
-       setZoom(scale, focusX, focusY, mScaleType);
-    }
-    
-    /**
-     * Set zoom to the specified scale. Image will be centered around the point
-     * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
-     * as a fraction from the left and top of the view. For example, the top left 
-     * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
-     * @param scale
-     * @param focusX
-     * @param focusY
-     * @param scaleType
-     */
-    public void setZoom(float scale, float focusX, float focusY, ScaleType scaleType) {
-       //
-       // setZoom can be called before the image is on the screen, but at this point, 
-       // image and view sizes have not yet been calculated in onMeasure. Thus, we should
-       // delay calling setZoom until the view has been measured.
-       //
-       if (!onDrawReady) {
-               delayedZoomVariables = new ZoomVariables(scale, focusX, focusY, scaleType);
-               return;
-       }
-       
-       if (scaleType != mScaleType) {
-               setScaleType(scaleType);
-       }
-       resetZoom();
-       scaleImage(scale, viewWidth / 2, viewHeight / 2, true);
-       matrix.getValues(m);
-       m[Matrix.MTRANS_X] = -((focusX * getImageWidth()) - (viewWidth * 0.5f));
-       m[Matrix.MTRANS_Y] = -((focusY * getImageHeight()) - (viewHeight * 0.5f));
-       matrix.setValues(m);
-       fixTrans();
-       setImageMatrix(matrix);
-    }
-    
-    /**
-     * Set zoom parameters equal to another TouchImageView. Including scale, position,
-     * and ScaleType.
-     * @param TouchImageView
-     */
-    public void setZoom(TouchImageViewCustom img) {
-       PointF center = img.getScrollPosition();
-       setZoom(img.getCurrentZoom(), center.x, center.y, img.getScaleType());
-    }
-    
-    /**
-     * Return the point at the center of the zoomed image. The PointF coordinates range
-     * in value between 0 and 1 and the focus point is denoted as a fraction from the left 
-     * and top of the view. For example, the top left corner of the image would be (0, 0). 
-     * And the bottom right corner would be (1, 1).
-     * @return PointF representing the scroll position of the zoomed image.
-     */
-    public PointF getScrollPosition() {
-       Drawable drawable = getDrawable();
-       if (drawable == null) {
-               return null;
-       }
-       int drawableWidth = drawable.getIntrinsicWidth();
-        int drawableHeight = drawable.getIntrinsicHeight();
-        
-        PointF point = transformCoordTouchToBitmap(viewWidth / 2, viewHeight / 2, true);
-        point.x /= drawableWidth;
-        point.y /= drawableHeight;
-        return point;
-    }
-    
-    /**
-     * Set the focus point of the zoomed image. The focus points are denoted as a fraction from the
-     * left and top of the view. The focus points can range in value between 0 and 1. 
-     * @param focusX
-     * @param focusY
-     */
-    public void setScrollPosition(float focusX, float focusY) {
-       setZoom(normalizedScale, focusX, focusY);
-    }
-    
-    /**
-     * Performs boundary checking and fixes the image matrix if it 
-     * is out of bounds.
-     */
-    private void fixTrans() {
-        matrix.getValues(m);
-        float transX = m[Matrix.MTRANS_X];
-        float transY = m[Matrix.MTRANS_Y];
-        
-        float fixTransX = getFixTrans(transX, viewWidth, getImageWidth());
-        float fixTransY = getFixTrans(transY, viewHeight, getImageHeight());
-        
-        if (fixTransX != 0 || fixTransY != 0) {
-            matrix.postTranslate(fixTransX, fixTransY);
-        }
-    }
-    
-    /**
-     * When transitioning from zooming from focus to zoom from center (or vice versa)
-     * the image can become unaligned within the view. This is apparent when zooming
-     * quickly. When the content size is less than the view size, the content will often
-     * be centered incorrectly within the view. fixScaleTrans first calls fixTrans() and 
-     * then makes sure the image is centered correctly within the view.
-     */
-    private void fixScaleTrans() {
-       fixTrans();
-       matrix.getValues(m);
-       if (getImageWidth() < viewWidth) {
-               m[Matrix.MTRANS_X] = (viewWidth - getImageWidth()) / 2;
-       }
-       
-       if (getImageHeight() < viewHeight) {
-               m[Matrix.MTRANS_Y] = (viewHeight - getImageHeight()) / 2;
-       }
-       matrix.setValues(m);
-    }
-
-    private float getFixTrans(float trans, float viewSize, float contentSize) {
-        float minTrans, maxTrans;
-
-        if (contentSize <= viewSize) {
-            minTrans = 0;
-            maxTrans = viewSize - contentSize;
-            
-        } else {
-            minTrans = viewSize - contentSize;
-            maxTrans = 0;
-        }
-
-        if (trans < minTrans)
-            return -trans + minTrans;
-        if (trans > maxTrans)
-            return -trans + maxTrans;
-        return 0;
-    }
-    
-    private float getFixDragTrans(float delta, float viewSize, float contentSize) {
-        if (contentSize <= viewSize) {
-            return 0;
-        }
-        return delta;
-    }
-    
-    private float getImageWidth() {
-       return matchViewWidth * normalizedScale;
-    }
-    
-    private float getImageHeight() {
-       return matchViewHeight * normalizedScale;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        Drawable drawable = getDrawable();
-        if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) {
-               setMeasuredDimension(0, 0);
-               return;
-        }
-        
-        int drawableWidth = drawable.getIntrinsicWidth();
-        int drawableHeight = drawable.getIntrinsicHeight();
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        viewWidth = setViewSize(widthMode, widthSize, drawableWidth);
-        viewHeight = setViewSize(heightMode, heightSize, drawableHeight);
-        
-        //
-        // Set view dimensions
-        //
-        setMeasuredDimension(viewWidth, viewHeight);
-        
-        //
-        // Fit content within view
-        //
-        fitImageToView();
-    }
-    
-    /**
-     * If the normalizedScale is equal to 1, then the image is made to fit the screen. Otherwise,
-     * it is made to fit the screen according to the dimensions of the previous image matrix. This
-     * allows the image to maintain its zoom after rotation.
-     */
-    private void fitImageToView() {
-       Drawable drawable = getDrawable();
-        if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) {
-               return;
-        }
-        if (matrix == null || prevMatrix == null) {
-               return;
-        }
-        
-        int drawableWidth = drawable.getIntrinsicWidth();
-        int drawableHeight = drawable.getIntrinsicHeight();
-       
-       //
-       // Scale image for view
-       //
-        float scaleX = (float) viewWidth / drawableWidth;
-        float scaleY = (float) viewHeight / drawableHeight;
-        
-        switch (mScaleType) {
-        case CENTER:
-               scaleX = scaleY = 1;
-               break;
-               
-        case CENTER_CROP:
-               scaleX = scaleY = Math.max(scaleX, scaleY);
-               break;
-               
-        case CENTER_INSIDE:
-               scaleX = scaleY = Math.min(1, Math.min(scaleX, scaleY));
-               
-        case FIT_CENTER:
-               scaleX = scaleY = Math.min(scaleX, scaleY);
-               break;
-               
-        case FIT_XY:
-               break;
-               
-       default:
-               //
-               // FIT_START and FIT_END not supported
-               //
-               throw new UnsupportedOperationException("TouchImageView does not support FIT_START or FIT_END");
-               
-        }
-
-        //
-        // Center the image
-        //
-        float redundantXSpace = viewWidth - (scaleX * drawableWidth);
-        float redundantYSpace = viewHeight - (scaleY * drawableHeight);
-        matchViewWidth = viewWidth - redundantXSpace;
-        matchViewHeight = viewHeight - redundantYSpace;
-        if (!isZoomed() && !imageRenderedAtLeastOnce) {
-               //
-               // Stretch and center image to fit view
-               //
-               matrix.setScale(scaleX, scaleY);
-               matrix.postTranslate(redundantXSpace / 2, redundantYSpace / 2);
-               normalizedScale = 1;
-               
-        } else {
-               //
-               // These values should never be 0 or we will set viewWidth and viewHeight
-               // to NaN in translateMatrixAfterRotate. To avoid this, call savePreviousImageValues
-               // to set them equal to the current values.
-               //
-               if (prevMatchViewWidth == 0 || prevMatchViewHeight == 0) {
-                       savePreviousImageValues();
-               }
-               
-               prevMatrix.getValues(m);
-               
-               //
-               // Rescale Matrix after rotation
-               //
-               m[Matrix.MSCALE_X] = matchViewWidth / drawableWidth * normalizedScale;
-               m[Matrix.MSCALE_Y] = matchViewHeight / drawableHeight * normalizedScale;
-               
-               //
-               // TransX and TransY from previous matrix
-               //
-            float transX = m[Matrix.MTRANS_X];
-            float transY = m[Matrix.MTRANS_Y];
-            
-            //
-            // Width
-            //
-            float prevActualWidth = prevMatchViewWidth * normalizedScale;
-            float actualWidth = getImageWidth();
-            translateMatrixAfterRotate(Matrix.MTRANS_X, transX, prevActualWidth, actualWidth, prevViewWidth, viewWidth, drawableWidth);
-            
-            //
-            // Height
-            //
-            float prevActualHeight = prevMatchViewHeight * normalizedScale;
-            float actualHeight = getImageHeight();
-            translateMatrixAfterRotate(Matrix.MTRANS_Y, transY, prevActualHeight, actualHeight, prevViewHeight, viewHeight, drawableHeight);
-            
-            //
-            // Set the matrix to the adjusted scale and translate values.
-            //
-            matrix.setValues(m);
-        }
-        fixTrans();
-        setImageMatrix(matrix);
-    }
-    
-    /**
-     * Set view dimensions based on layout params
-     * 
-     * @param mode 
-     * @param size
-     * @param drawableWidth
-     * @return
-     */
-    private int setViewSize(int mode, int size, int drawableWidth) {
-       int viewSize;
-       switch (mode) {
-               case MeasureSpec.EXACTLY:
-                       viewSize = size;
-                       break;
-                       
-               case MeasureSpec.AT_MOST:
-                       viewSize = Math.min(drawableWidth, size);
-                       break;
-                       
-               case MeasureSpec.UNSPECIFIED:
-                       viewSize = drawableWidth;
-                       break;
-                       
-               default:
-                       viewSize = size;
-                       break;
-               }
-       return viewSize;
-    }
-    
-    /**
-     * After rotating, the matrix needs to be translated. This function finds the area of image 
-     * which was previously centered and adjusts translations so that is again the center, post-rotation.
-     * 
-     * @param axis Matrix.MTRANS_X or Matrix.MTRANS_Y
-     * @param trans the value of trans in that axis before the rotation
-     * @param prevImageSize the width/height of the image before the rotation
-     * @param imageSize width/height of the image after rotation
-     * @param prevViewSize width/height of view before rotation
-     * @param viewSize width/height of view after rotation
-     * @param drawableSize width/height of drawable
-     */
-    private void translateMatrixAfterRotate(int axis, float trans, float prevImageSize, float imageSize, int prevViewSize, int viewSize, int drawableSize) {
-       if (imageSize < viewSize) {
-               //
-               // The width/height of image is less than the view's width/height. Center it.
-               //
-               m[axis] = (viewSize - (drawableSize * m[Matrix.MSCALE_X])) * 0.5f;
-               
-        } else if (trans > 0) {
-               //
-               // The image is larger than the view, but was not before rotation. Center it.
-               //
-               m[axis] = -((imageSize - viewSize) * 0.5f);
-               
-        } else {
-               //
-               // Find the area of the image which was previously centered in the view. Determine its distance
-               // from the left/top side of the view as a fraction of the entire image's width/height. Use that percentage
-               // to calculate the trans in the new view width/height.
-               //
-               float percentage = (Math.abs(trans) + (0.5f * prevViewSize)) / prevImageSize;
-               m[axis] = -((percentage * imageSize) - (viewSize * 0.5f));
-        }
-    }
-    
-    private void setState(State state) {
-       this.state = state;
-    }
-    
-    public boolean canScrollHorizontallyFroyo(int direction) {
-        return canScrollHorizontally(direction);
-    }
-    
-    @Override
-    public boolean canScrollHorizontally(int direction) {
-       matrix.getValues(m);
-       float x = m[Matrix.MTRANS_X];
-       
-       if (getImageWidth() < viewWidth) {
-               return false;
-               
-       } else if (x >= -1 && direction < 0) {
-               return false;
-               
-       } else if (Math.abs(x) + viewWidth + 1 >= getImageWidth() && direction > 0) {
-               return false;
-       }
-       
-       return true;
-    }
-    
-    /**
-     * Gesture Listener detects a single click or long click and passes that on
-     * to the view's listener.
-     * @author Ortiz
-     *
-     */
-    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
-       
-        @Override
-        public boolean onSingleTapConfirmed(MotionEvent e)
-        {
-            if(doubleTapListener != null) {
-               return doubleTapListener.onSingleTapConfirmed(e);
-            }
-               return performClick();
-        }
-        
-        @Override
-        public void onLongPress(MotionEvent e)
-        {
-               performLongClick();
-        }
-        
-        @Override
-        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
-        {
-               if (fling != null) {
-                       //
-                       // If a previous fling is still active, it should be cancelled so that two flings
-                       // are not run simultaenously.
-                       //
-                       fling.cancelFling();
-               }
-               fling = new Fling((int) velocityX, (int) velocityY);
-               compatPostOnAnimation(fling);
-               return super.onFling(e1, e2, velocityX, velocityY);
-        }
-        
-        @Override
-        public boolean onDoubleTap(MotionEvent e) {
-               boolean consumed = false;
-            if(doubleTapListener != null) {
-               consumed = doubleTapListener.onDoubleTap(e);
-            }
-               if (state == State.NONE) {
-                       float targetZoom = (normalizedScale == minScale) ? maxScale : minScale;
-                       DoubleTapZoom doubleTap = new DoubleTapZoom(targetZoom, e.getX(), e.getY(), false);
-                       compatPostOnAnimation(doubleTap);
-                       consumed = true;
-               }
-               return consumed;
-        }
-
-        @Override
-        public boolean onDoubleTapEvent(MotionEvent e) {
-            if(doubleTapListener != null) {
-               return doubleTapListener.onDoubleTapEvent(e);
-            }
-            return false;
-        }
-    }
-    
-    public interface OnTouchImageViewListener {
-       public void onMove();
-    }
-    
-    /**
-     * Responsible for all touch events. Handles the heavy lifting of drag and also sends
-     * touch events to Scale Detector and Gesture Detector.
-     * @author Ortiz
-     *
-     */
-    private class PrivateOnTouchListener implements OnTouchListener {
-       
-       //
-        // Remember last point position for dragging
-        //
-        private PointF last = new PointF();
-       
-       @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            mScaleDetector.onTouchEvent(event);
-            mGestureDetector.onTouchEvent(event);
-            PointF curr = new PointF(event.getX(), event.getY());
-            
-            if (state == State.NONE || state == State.DRAG || state == State.FLING) {
-                   switch (event.getAction()) {
-                       case MotionEvent.ACTION_DOWN:
-                               last.set(curr);
-                           if (fling != null)
-                               fling.cancelFling();
-                           setState(State.DRAG);
-                           break;
-                           
-                       case MotionEvent.ACTION_MOVE:
-                           if (state == State.DRAG) {
-                               float deltaX = curr.x - last.x;
-                               float deltaY = curr.y - last.y;
-                               float fixTransX = getFixDragTrans(deltaX, viewWidth, getImageWidth());
-                               float fixTransY = getFixDragTrans(deltaY, viewHeight, getImageHeight());
-                               matrix.postTranslate(fixTransX, fixTransY);
-                               fixTrans();
-                               last.set(curr.x, curr.y);
-                           }
-                           break;
-       
-                       case MotionEvent.ACTION_UP:
-                       case MotionEvent.ACTION_POINTER_UP:
-                           setState(State.NONE);
-                           break;
-                   }
-            }
-            
-            setImageMatrix(matrix);
-            
-            //
-               // User-defined OnTouchListener
-               //
-               if(userTouchListener != null) {
-                       userTouchListener.onTouch(v, event);
-               }
-            
-               //
-               // OnTouchImageViewListener is set: TouchImageView dragged by user.
-               //
-               if (touchImageViewListener != null) {
-                       touchImageViewListener.onMove();
-               }
-               
-            //
-            // indicate event was handled
-            //
-            return true;
-        }
-    }
-
-    /**
-     * ScaleListener detects user two finger scaling and scales image.
-     * @author Ortiz
-     *
-     */
-    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
-        @Override
-        public boolean onScaleBegin(ScaleGestureDetector detector) {
-            setState(State.ZOOM);
-            return true;
-        }
-
-        @Override
-        public boolean onScale(ScaleGestureDetector detector) {
-               scaleImage(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY(), true);
-               
-               //
-               // OnTouchImageViewListener is set: TouchImageView pinch zoomed by user.
-               //
-               if (touchImageViewListener != null) {
-                       touchImageViewListener.onMove();
-               }
-            return true;
-        }
-        
-        @Override
-        public void onScaleEnd(ScaleGestureDetector detector) {
-               super.onScaleEnd(detector);
-               setState(State.NONE);
-               boolean animateToZoomBoundary = false;
-               float targetZoom = normalizedScale;
-               if (normalizedScale > maxScale) {
-                       targetZoom = maxScale;
-                       animateToZoomBoundary = true;
-                       
-               } else if (normalizedScale < minScale) {
-                       targetZoom = minScale;
-                       animateToZoomBoundary = true;
-               }
-               
-               if (animateToZoomBoundary) {
-                       DoubleTapZoom doubleTap = new DoubleTapZoom(targetZoom, viewWidth / 2, viewHeight / 2, true);
-                       compatPostOnAnimation(doubleTap);
-               }
-        }
-    }
-    
-    private void scaleImage(double deltaScale, float focusX, float focusY, boolean stretchImageToSuper) {
-       
-       float lowerScale, upperScale;
-       if (stretchImageToSuper) {
-               lowerScale = superMinScale;
-               upperScale = superMaxScale;
-               
-       } else {
-               lowerScale = minScale;
-               upperScale = maxScale;
-       }
-       
-       float origScale = normalizedScale;
-        normalizedScale *= deltaScale;
-        if (normalizedScale > upperScale) {
-            normalizedScale = upperScale;
-            deltaScale = upperScale / origScale;
-        } else if (normalizedScale < lowerScale) {
-            normalizedScale = lowerScale;
-            deltaScale = lowerScale / origScale;
-        }
-        
-        matrix.postScale((float) deltaScale, (float) deltaScale, focusX, focusY);
-        fixScaleTrans();
-    }
-    
-    /**
-     * DoubleTapZoom calls a series of runnables which apply
-     * an animated zoom in/out graphic to the image.
-     * @author Ortiz
-     *
-     */
-    private class DoubleTapZoom implements Runnable {
-       
-       private long startTime;
-       private static final float ZOOM_TIME = 500;
-       private float startZoom, targetZoom;
-       private float bitmapX, bitmapY;
-       private boolean stretchImageToSuper;
-       private AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
-       private PointF startTouch;
-       private PointF endTouch;
-
-       DoubleTapZoom(float targetZoom, float focusX, float focusY, boolean stretchImageToSuper) {
-               setState(State.ANIMATE_ZOOM);
-               startTime = System.currentTimeMillis();
-               this.startZoom = normalizedScale;
-               this.targetZoom = targetZoom;
-               this.stretchImageToSuper = stretchImageToSuper;
-               PointF bitmapPoint = transformCoordTouchToBitmap(focusX, focusY, false);
-               this.bitmapX = bitmapPoint.x;
-               this.bitmapY = bitmapPoint.y;
-               
-               //
-               // Used for translating image during scaling
-               //
-               startTouch = transformCoordBitmapToTouch(bitmapX, bitmapY);
-               endTouch = new PointF(viewWidth / 2, viewHeight / 2);
-       }
-
-               @Override
-               public void run() {
-                       float t = interpolate();
-                       double deltaScale = calculateDeltaScale(t);
-                       scaleImage(deltaScale, bitmapX, bitmapY, stretchImageToSuper);
-                       translateImageToCenterTouchPosition(t);
-                       fixScaleTrans();
-                       setImageMatrix(matrix);
-                       
-                       //
-                       // OnTouchImageViewListener is set: double tap runnable updates listener
-                       // with every frame.
-                       //
-                       if (touchImageViewListener != null) {
-                               touchImageViewListener.onMove();
-                       }
-                       
-                       if (t < 1f) {
-                               //
-                               // We haven't finished zooming
-                               //
-                               compatPostOnAnimation(this);
-                               
-                       } else {
-                               //
-                               // Finished zooming
-                               //
-                               setState(State.NONE);
-                       }
-               }
-               
-               /**
-                * Interpolate between where the image should start and end in order to translate
-                * the image so that the point that is touched is what ends up centered at the end
-                * of the zoom.
-                * @param t
-                */
-               private void translateImageToCenterTouchPosition(float t) {
-                       float targetX = startTouch.x + t * (endTouch.x - startTouch.x);
-                       float targetY = startTouch.y + t * (endTouch.y - startTouch.y);
-                       PointF curr = transformCoordBitmapToTouch(bitmapX, bitmapY);
-                       matrix.postTranslate(targetX - curr.x, targetY - curr.y);
-               }
-               
-               /**
-                * Use interpolator to get t
-                * @return
-                */
-               private float interpolate() {
-                       long currTime = System.currentTimeMillis();
-                       float elapsed = (currTime - startTime) / ZOOM_TIME;
-                       elapsed = Math.min(1f, elapsed);
-                       return interpolator.getInterpolation(elapsed);
-               }
-               
-               /**
-                * Interpolate the current targeted zoom and get the delta
-                * from the current zoom.
-                * @param t
-                * @return
-                */
-               private double calculateDeltaScale(float t) {
-                       double zoom = startZoom + t * (targetZoom - startZoom);
-                       return zoom / normalizedScale;
-               }
-    }
-    
-    /**
-     * This function will transform the coordinates in the touch event to the coordinate 
-     * system of the drawable that the imageview contain
-     * @param x x-coordinate of touch event
-     * @param y y-coordinate of touch event
-     * @param clipToBitmap Touch event may occur within view, but outside image content. True, to clip return value
-     *                         to the bounds of the bitmap size.
-     * @return Coordinates of the point touched, in the coordinate system of the original drawable.
-     */
-    private PointF transformCoordTouchToBitmap(float x, float y, boolean clipToBitmap) {
-         matrix.getValues(m);
-         float origW = getDrawable().getIntrinsicWidth();
-         float origH = getDrawable().getIntrinsicHeight();
-         float transX = m[Matrix.MTRANS_X];
-         float transY = m[Matrix.MTRANS_Y];
-         float finalX = ((x - transX) * origW) / getImageWidth();
-         float finalY = ((y - transY) * origH) / getImageHeight();
-         
-         if (clipToBitmap) {
-                finalX = Math.min(Math.max(finalX, 0), origW);
-                finalY = Math.min(Math.max(finalY, 0), origH);
-         }
-         
-         return new PointF(finalX , finalY);
-    }
-    
-    /**
-     * Inverse of transformCoordTouchToBitmap. This function will transform the coordinates in the
-     * drawable's coordinate system to the view's coordinate system.
-     * @param bx x-coordinate in original bitmap coordinate system
-     * @param by y-coordinate in original bitmap coordinate system
-     * @return Coordinates of the point in the view's coordinate system.
-     */
-    private PointF transformCoordBitmapToTouch(float bx, float by) {
-        matrix.getValues(m);        
-        float origW = getDrawable().getIntrinsicWidth();
-        float origH = getDrawable().getIntrinsicHeight();
-        float px = bx / origW;
-        float py = by / origH;
-        float finalX = m[Matrix.MTRANS_X] + getImageWidth() * px;
-        float finalY = m[Matrix.MTRANS_Y] + getImageHeight() * py;
-        return new PointF(finalX , finalY);
-    }
-    
-    /**
-     * Fling launches sequential runnables which apply
-     * the fling graphic to the image. The values for the translation
-     * are interpolated by the Scroller.
-     * @author Ortiz
-     *
-     */
-    private class Fling implements Runnable {
-       
-        CompatScroller scroller;
-       int currX, currY;
-       
-       Fling(int velocityX, int velocityY) {
-               setState(State.FLING);
-               scroller = new CompatScroller(context);
-               matrix.getValues(m);
-               
-               int startX = (int) m[Matrix.MTRANS_X];
-               int startY = (int) m[Matrix.MTRANS_Y];
-               int minX, maxX, minY, maxY;
-               
-               if (getImageWidth() > viewWidth) {
-                       minX = viewWidth - (int) getImageWidth();
-                       maxX = 0;
-                       
-               } else {
-                       minX = maxX = startX;
-               }
-               
-               if (getImageHeight() > viewHeight) {
-                       minY = viewHeight - (int) getImageHeight();
-                       maxY = 0;
-                       
-               } else {
-                       minY = maxY = startY;
-               }
-               
-               scroller.fling(startX, startY, (int) velocityX, (int) velocityY, minX,
-                    maxX, minY, maxY);
-               currX = startX;
-               currY = startY;
-       }
-       
-       public void cancelFling() {
-               if (scroller != null) {
-                       setState(State.NONE);
-                       scroller.forceFinished(true);
-               }
-       }
-       
-               @Override
-               public void run() {
-                       
-                       //
-                       // OnTouchImageViewListener is set: TouchImageView listener has been flung by user.
-                       // Listener runnable updated with each frame of fling animation.
-                       //
-                       if (touchImageViewListener != null) {
-                               touchImageViewListener.onMove();
-                       }
-                       
-                       if (scroller.isFinished()) {
-                       scroller = null;
-                       return;
-               }
-                       
-                       if (scroller.computeScrollOffset()) {
-                       int newX = scroller.getCurrX();
-                   int newY = scroller.getCurrY();
-                   int transX = newX - currX;
-                   int transY = newY - currY;
-                   currX = newX;
-                   currY = newY;
-                   matrix.postTranslate(transX, transY);
-                   fixTrans();
-                   setImageMatrix(matrix);
-                   compatPostOnAnimation(this);
-               }
-               }
-    }
-    
-    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
-       private class CompatScroller {
-       Scroller scroller;
-       OverScroller overScroller;
-       boolean isPreGingerbread;
-       
-       public CompatScroller(Context context) {
-               if (VERSION.SDK_INT < VERSION_CODES.GINGERBREAD) {
-                       isPreGingerbread = true;
-                       scroller = new Scroller(context);
-                       
-               } else {
-                       isPreGingerbread = false;
-                       overScroller = new OverScroller(context);
-               }
-       }
-       
-       public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) {
-               if (isPreGingerbread) {
-                       scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
-               } else {
-                       overScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
-               }
-       }
-       
-       public void forceFinished(boolean finished) {
-               if (isPreGingerbread) {
-                       scroller.forceFinished(finished);
-               } else {
-                       overScroller.forceFinished(finished);
-               }
-       }
-       
-       public boolean isFinished() {
-               if (isPreGingerbread) {
-                       return scroller.isFinished();
-               } else {
-                       return overScroller.isFinished();
-               }
-       }
-       
-       public boolean computeScrollOffset() {
-               if (isPreGingerbread) {
-                       return scroller.computeScrollOffset();
-               } else {
-                       overScroller.computeScrollOffset();
-                       return overScroller.computeScrollOffset();
-               }
-       }
-       
-       public int getCurrX() {
-               if (isPreGingerbread) {
-                       return scroller.getCurrX();
-               } else {
-                       return overScroller.getCurrX();
-               }
-       }
-       
-       public int getCurrY() {
-               if (isPreGingerbread) {
-                       return scroller.getCurrY();
-               } else {
-                       return overScroller.getCurrY();
-               }
-       }
-    }
-    
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
-       private void compatPostOnAnimation(Runnable runnable) {
-       if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
-            postOnAnimation(runnable);
-            
-        } else {
-            postDelayed(runnable, 1000/60);
-        }
-    }
-    
-    private class ZoomVariables {
-       public float scale;
-       public float focusX;
-       public float focusY;
-       public ScaleType scaleType;
-       
-       public ZoomVariables(float scale, float focusX, float focusY, ScaleType scaleType) {
-               this.scale = scale;
-               this.focusX = focusX;
-               this.focusY = focusY;
-               this.scaleType = scaleType;
-       }
-    }
-    
-    private void printMatrixInfo() {
-       float[] n = new float[9];
-       matrix.getValues(n);
-       Log.d(DEBUG, "Scale: " + n[Matrix.MSCALE_X] + " TransX: " + n[Matrix.MTRANS_X] + " TransY: " + n[Matrix.MTRANS_Y]);
-    }
-}
\ No newline at end of file
index e66d2c9..8070e36 100644 (file)
@@ -1,5 +1,7 @@
-/* ownCloud Android client application
- *   Copyright (C) 2012-2014 ownCloud Inc.
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
index 1077d15..cb0dac4 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
diff --git a/src/third_parties/michaelOrtiz/TouchImageViewCustom.java b/src/third_parties/michaelOrtiz/TouchImageViewCustom.java
new file mode 100644 (file)
index 0000000..9b0f5a0
--- /dev/null
@@ -0,0 +1,1277 @@
+/**
+ *   @author Michael Ortiz
+ *   @updated Patrick Lackemacher
+ *   @updated Babay88
+ *   @updated @ipsilondev
+ *   @updated hank-cp
+ *   @updated singpolyma
+ *   Copyright (c) 2012 Michael Ortiz
+ */
+
+package third_parties.michaelOrtiz;
+
+import com.owncloud.android.ui.preview.ImageViewCustom;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.OverScroller;
+import android.widget.Scroller;
+
+/**
+ * Extends Android ImageView to include pinch zooming, panning, fling and double tap zoom.
+ */
+public class TouchImageViewCustom extends ImageViewCustom {
+    private static final String DEBUG = "DEBUG";
+       
+       //
+       // SuperMin and SuperMax multipliers. Determine how much the image can be
+       // zoomed below or above the zoom boundaries, before animating back to the
+       // min/max zoom boundary.
+       //
+       private static final float SUPER_MIN_MULTIPLIER = .75f;
+       private static final float SUPER_MAX_MULTIPLIER = 1.25f;
+
+    //
+    // Scale of image ranges from minScale to maxScale, where minScale == 1
+    // when the image is stretched to fit view.
+    //
+    private float normalizedScale;
+    
+    //
+    // Matrix applied to image. MSCALE_X and MSCALE_Y should always be equal.
+    // MTRANS_X and MTRANS_Y are the other values used. prevMatrix is the matrix
+    // saved prior to the screen rotating.
+    //
+       private Matrix matrix, prevMatrix;
+
+    private static enum State { NONE, DRAG, ZOOM, FLING, ANIMATE_ZOOM };
+    private State state;
+
+    private float minScale;
+    private float maxScale;
+    private float superMinScale;
+    private float superMaxScale;
+    private float[] m;
+    
+    private Context context;
+    private Fling fling;
+    
+    private ScaleType mScaleType;
+    
+    private boolean imageRenderedAtLeastOnce;
+    private boolean onDrawReady;
+    
+    private ZoomVariables delayedZoomVariables;
+
+    //
+    // Size of view and previous view size (ie before rotation)
+    //
+    private int viewWidth, viewHeight, prevViewWidth, prevViewHeight;
+    
+    //
+    // Size of image when it is stretched to fit view. Before and After rotation.
+    //
+    private float matchViewWidth, matchViewHeight, prevMatchViewWidth, prevMatchViewHeight;
+    
+    private ScaleGestureDetector mScaleDetector;
+    private GestureDetector mGestureDetector;
+    private GestureDetector.OnDoubleTapListener doubleTapListener = null;
+    private OnTouchListener userTouchListener = null;
+    private OnTouchImageViewListener touchImageViewListener = null;
+
+    public TouchImageViewCustom(Context context) {
+        super(context);
+        sharedConstructing(context);
+    }
+
+    public TouchImageViewCustom(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        sharedConstructing(context);
+    }
+    
+    public TouchImageViewCustom(Context context, AttributeSet attrs, int defStyle) {
+       super(context, attrs, defStyle);
+       sharedConstructing(context);
+    }
+    
+    private void sharedConstructing(Context context) {
+        super.setClickable(true);
+        this.context = context;
+        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+        mGestureDetector = new GestureDetector(context, new GestureListener());
+        matrix = new Matrix();
+        prevMatrix = new Matrix();
+        m = new float[9];
+        normalizedScale = 1;
+        if (mScaleType == null) {
+               mScaleType = ScaleType.FIT_CENTER;
+        }
+        minScale = 1;
+        maxScale = 3;
+        superMinScale = SUPER_MIN_MULTIPLIER * minScale;
+        superMaxScale = SUPER_MAX_MULTIPLIER * maxScale;
+        setImageMatrix(matrix);
+        setScaleType(ScaleType.MATRIX);
+        setState(State.NONE);
+        onDrawReady = false;
+        super.setOnTouchListener(new PrivateOnTouchListener());
+    }
+
+    @Override
+    public void setOnTouchListener(View.OnTouchListener l) {
+        userTouchListener = l;
+    }
+    
+    public void setOnTouchImageViewListener(OnTouchImageViewListener l) {
+       touchImageViewListener = l;
+    }
+
+    public void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener l) {
+        doubleTapListener = l;
+    }
+
+    @Override
+    public void setImageResource(int resId) {
+       super.setImageResource(resId);
+       savePreviousImageValues();
+       fitImageToView();
+    }
+    
+    @Override
+    public void setImageBitmap(Bitmap bm) {
+       super.setImageBitmap(bm);
+       savePreviousImageValues();
+       fitImageToView();
+    }
+    
+    @Override
+    public void setImageDrawable(Drawable drawable) {
+       super.setImageDrawable(drawable);
+       savePreviousImageValues();
+       fitImageToView();
+    }
+    
+    @Override
+    public void setImageURI(Uri uri) {
+       super.setImageURI(uri);
+       savePreviousImageValues();
+       fitImageToView();
+    }
+    
+    @Override
+    public void setScaleType(ScaleType type) {
+       if (type == ScaleType.FIT_START || type == ScaleType.FIT_END) {
+               throw new UnsupportedOperationException("TouchImageView does not support FIT_START or FIT_END");
+       }
+       if (type == ScaleType.MATRIX) {
+               super.setScaleType(ScaleType.MATRIX);
+               
+       } else {
+               mScaleType = type;
+               if (onDrawReady) {
+                       //
+                       // If the image is already rendered, scaleType has been called programmatically
+                       // and the TouchImageView should be updated with the new scaleType.
+                       //
+                       setZoom(this);
+               }
+       }
+    }
+    
+    @Override
+    public ScaleType getScaleType() {
+       return mScaleType;
+    }
+    
+    /**
+     * Returns false if image is in initial, unzoomed state. False, otherwise.
+     * @return true if image is zoomed
+     */
+    public boolean isZoomed() {
+       return normalizedScale != 1;
+    }
+    
+    /**
+     * Return a Rect representing the zoomed image.
+     * @return rect representing zoomed image
+     */
+    public RectF getZoomedRect() {
+       if (mScaleType == ScaleType.FIT_XY) {
+               throw new UnsupportedOperationException("getZoomedRect() not supported with FIT_XY");
+       }
+       PointF topLeft = transformCoordTouchToBitmap(0, 0, true);
+       PointF bottomRight = transformCoordTouchToBitmap(viewWidth, viewHeight, true);
+       
+       float w = getDrawable().getIntrinsicWidth();
+       float h = getDrawable().getIntrinsicHeight();
+       return new RectF(topLeft.x / w, topLeft.y / h, bottomRight.x / w, bottomRight.y / h);
+    }
+    
+    /**
+     * Save the current matrix and view dimensions
+     * in the prevMatrix and prevView variables.
+     */
+    private void savePreviousImageValues() {
+       if (matrix != null && viewHeight != 0 && viewWidth != 0) {
+               matrix.getValues(m);
+               prevMatrix.setValues(m);
+               prevMatchViewHeight = matchViewHeight;
+               prevMatchViewWidth = matchViewWidth;
+               prevViewHeight = viewHeight;
+               prevViewWidth = viewWidth;
+       }
+    }
+    
+    @Override
+    public Parcelable onSaveInstanceState() {
+       Bundle bundle = new Bundle();
+       bundle.putParcelable("instanceState", super.onSaveInstanceState());
+       bundle.putFloat("saveScale", normalizedScale);
+       bundle.putFloat("matchViewHeight", matchViewHeight);
+       bundle.putFloat("matchViewWidth", matchViewWidth);
+       bundle.putInt("viewWidth", viewWidth);
+       bundle.putInt("viewHeight", viewHeight);
+       matrix.getValues(m);
+       bundle.putFloatArray("matrix", m);
+       bundle.putBoolean("imageRendered", imageRenderedAtLeastOnce);
+       return bundle;
+    }
+    
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+       if (state instanceof Bundle) {
+               Bundle bundle = (Bundle) state;
+               normalizedScale = bundle.getFloat("saveScale");
+               m = bundle.getFloatArray("matrix");
+               prevMatrix.setValues(m);
+               prevMatchViewHeight = bundle.getFloat("matchViewHeight");
+               prevMatchViewWidth = bundle.getFloat("matchViewWidth");
+               prevViewHeight = bundle.getInt("viewHeight");
+               prevViewWidth = bundle.getInt("viewWidth");
+               imageRenderedAtLeastOnce = bundle.getBoolean("imageRendered");
+               super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
+               return;
+       }
+
+       super.onRestoreInstanceState(state);
+    }
+    
+    @Override
+    protected void onDraw(Canvas canvas) {
+       onDrawReady = true;
+       imageRenderedAtLeastOnce = true;
+       if (delayedZoomVariables != null) {
+               setZoom(delayedZoomVariables.scale, delayedZoomVariables.focusX, delayedZoomVariables.focusY, delayedZoomVariables.scaleType);
+               delayedZoomVariables = null;
+       }
+       super.onDraw(canvas);
+    }
+    
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+       super.onConfigurationChanged(newConfig);
+       savePreviousImageValues();
+    }
+    
+    /**
+     * Get the max zoom multiplier.
+     * @return max zoom multiplier.
+     */
+    public float getMaxZoom() {
+       return maxScale;
+    }
+
+    /**
+     * Set the max zoom multiplier. Default value: 3.
+     * @param max max zoom multiplier.
+     */
+    public void setMaxZoom(float max) {
+        maxScale = max;
+        superMaxScale = SUPER_MAX_MULTIPLIER * maxScale;
+    }
+    
+    /**
+     * Get the min zoom multiplier.
+     * @return min zoom multiplier.
+     */
+    public float getMinZoom() {
+       return minScale;
+    }
+    
+    /**
+     * Get the current zoom. This is the zoom relative to the initial
+     * scale, not the original resource.
+     * @return current zoom multiplier.
+     */
+    public float getCurrentZoom() {
+       return normalizedScale;
+    }
+    
+    /**
+     * Set the min zoom multiplier. Default value: 1.
+     * @param min min zoom multiplier.
+     */
+    public void setMinZoom(float min) {
+       minScale = min;
+       superMinScale = SUPER_MIN_MULTIPLIER * minScale;
+    }
+    
+    /**
+     * Reset zoom and translation to initial state.
+     */
+    public void resetZoom() {
+       normalizedScale = 1;
+       fitImageToView();
+    }
+    
+    /**
+     * Set zoom to the specified scale. Image will be centered by default.
+     * @param scale
+     */
+    public void setZoom(float scale) {
+       setZoom(scale, 0.5f, 0.5f);
+    }
+    
+    /**
+     * Set zoom to the specified scale. Image will be centered around the point
+     * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
+     * as a fraction from the left and top of the view. For example, the top left 
+     * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
+     * @param scale
+     * @param focusX
+     * @param focusY
+     */
+    public void setZoom(float scale, float focusX, float focusY) {
+       setZoom(scale, focusX, focusY, mScaleType);
+    }
+    
+    /**
+     * Set zoom to the specified scale. Image will be centered around the point
+     * (focusX, focusY). These floats range from 0 to 1 and denote the focus point
+     * as a fraction from the left and top of the view. For example, the top left 
+     * corner of the image would be (0, 0). And the bottom right corner would be (1, 1).
+     * @param scale
+     * @param focusX
+     * @param focusY
+     * @param scaleType
+     */
+    public void setZoom(float scale, float focusX, float focusY, ScaleType scaleType) {
+       //
+       // setZoom can be called before the image is on the screen, but at this point, 
+       // image and view sizes have not yet been calculated in onMeasure. Thus, we should
+       // delay calling setZoom until the view has been measured.
+       //
+       if (!onDrawReady) {
+               delayedZoomVariables = new ZoomVariables(scale, focusX, focusY, scaleType);
+               return;
+       }
+       
+       if (scaleType != mScaleType) {
+               setScaleType(scaleType);
+       }
+       resetZoom();
+       scaleImage(scale, viewWidth / 2, viewHeight / 2, true);
+       matrix.getValues(m);
+       m[Matrix.MTRANS_X] = -((focusX * getImageWidth()) - (viewWidth * 0.5f));
+       m[Matrix.MTRANS_Y] = -((focusY * getImageHeight()) - (viewHeight * 0.5f));
+       matrix.setValues(m);
+       fixTrans();
+       setImageMatrix(matrix);
+    }
+    
+    /**
+     * Set zoom parameters equal to another TouchImageView. Including scale, position,
+     * and ScaleType.
+     * @param img
+     */
+    public void setZoom(TouchImageViewCustom img) {
+       PointF center = img.getScrollPosition();
+       setZoom(img.getCurrentZoom(), center.x, center.y, img.getScaleType());
+    }
+    
+    /**
+     * Return the point at the center of the zoomed image. The PointF coordinates range
+     * in value between 0 and 1 and the focus point is denoted as a fraction from the left 
+     * and top of the view. For example, the top left corner of the image would be (0, 0). 
+     * And the bottom right corner would be (1, 1).
+     * @return PointF representing the scroll position of the zoomed image.
+     */
+    public PointF getScrollPosition() {
+       Drawable drawable = getDrawable();
+       if (drawable == null) {
+               return null;
+       }
+       int drawableWidth = drawable.getIntrinsicWidth();
+        int drawableHeight = drawable.getIntrinsicHeight();
+        
+        PointF point = transformCoordTouchToBitmap(viewWidth / 2, viewHeight / 2, true);
+        point.x /= drawableWidth;
+        point.y /= drawableHeight;
+        return point;
+    }
+    
+    /**
+     * Set the focus point of the zoomed image. The focus points are denoted as a fraction from the
+     * left and top of the view. The focus points can range in value between 0 and 1. 
+     * @param focusX
+     * @param focusY
+     */
+    public void setScrollPosition(float focusX, float focusY) {
+       setZoom(normalizedScale, focusX, focusY);
+    }
+    
+    /**
+     * Performs boundary checking and fixes the image matrix if it 
+     * is out of bounds.
+     */
+    private void fixTrans() {
+        matrix.getValues(m);
+        float transX = m[Matrix.MTRANS_X];
+        float transY = m[Matrix.MTRANS_Y];
+        
+        float fixTransX = getFixTrans(transX, viewWidth, getImageWidth());
+        float fixTransY = getFixTrans(transY, viewHeight, getImageHeight());
+        
+        if (fixTransX != 0 || fixTransY != 0) {
+            matrix.postTranslate(fixTransX, fixTransY);
+        }
+    }
+    
+    /**
+     * When transitioning from zooming from focus to zoom from center (or vice versa)
+     * the image can become unaligned within the view. This is apparent when zooming
+     * quickly. When the content size is less than the view size, the content will often
+     * be centered incorrectly within the view. fixScaleTrans first calls fixTrans() and 
+     * then makes sure the image is centered correctly within the view.
+     */
+    private void fixScaleTrans() {
+       fixTrans();
+       matrix.getValues(m);
+       if (getImageWidth() < viewWidth) {
+               m[Matrix.MTRANS_X] = (viewWidth - getImageWidth()) / 2;
+       }
+       
+       if (getImageHeight() < viewHeight) {
+               m[Matrix.MTRANS_Y] = (viewHeight - getImageHeight()) / 2;
+       }
+       matrix.setValues(m);
+    }
+
+    private float getFixTrans(float trans, float viewSize, float contentSize) {
+        float minTrans, maxTrans;
+
+        if (contentSize <= viewSize) {
+            minTrans = 0;
+            maxTrans = viewSize - contentSize;
+            
+        } else {
+            minTrans = viewSize - contentSize;
+            maxTrans = 0;
+        }
+
+        if (trans < minTrans)
+            return -trans + minTrans;
+        if (trans > maxTrans)
+            return -trans + maxTrans;
+        return 0;
+    }
+    
+    private float getFixDragTrans(float delta, float viewSize, float contentSize) {
+        if (contentSize <= viewSize) {
+            return 0;
+        }
+        return delta;
+    }
+    
+    private float getImageWidth() {
+       return matchViewWidth * normalizedScale;
+    }
+    
+    private float getImageHeight() {
+       return matchViewHeight * normalizedScale;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        Drawable drawable = getDrawable();
+        if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) {
+               setMeasuredDimension(0, 0);
+               return;
+        }
+        
+        int drawableWidth = drawable.getIntrinsicWidth();
+        int drawableHeight = drawable.getIntrinsicHeight();
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        viewWidth = setViewSize(widthMode, widthSize, drawableWidth);
+        viewHeight = setViewSize(heightMode, heightSize, drawableHeight);
+        
+        //
+        // Set view dimensions
+        //
+        setMeasuredDimension(viewWidth, viewHeight);
+        
+        //
+        // Fit content within view
+        //
+        fitImageToView();
+    }
+    
+    /**
+     * If the normalizedScale is equal to 1, then the image is made to fit the screen. Otherwise,
+     * it is made to fit the screen according to the dimensions of the previous image matrix. This
+     * allows the image to maintain its zoom after rotation.
+     */
+    private void fitImageToView() {
+       Drawable drawable = getDrawable();
+        if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0) {
+               return;
+        }
+        if (matrix == null || prevMatrix == null) {
+               return;
+        }
+        
+        int drawableWidth = drawable.getIntrinsicWidth();
+        int drawableHeight = drawable.getIntrinsicHeight();
+       
+       //
+       // Scale image for view
+       //
+        float scaleX = (float) viewWidth / drawableWidth;
+        float scaleY = (float) viewHeight / drawableHeight;
+        
+        switch (mScaleType) {
+        case CENTER:
+               scaleX = scaleY = 1;
+               break;
+               
+        case CENTER_CROP:
+               scaleX = scaleY = Math.max(scaleX, scaleY);
+               break;
+               
+        case CENTER_INSIDE:
+               scaleX = scaleY = Math.min(1, Math.min(scaleX, scaleY));
+               
+        case FIT_CENTER:
+               scaleX = scaleY = Math.min(scaleX, scaleY);
+               break;
+               
+        case FIT_XY:
+               break;
+               
+       default:
+               //
+               // FIT_START and FIT_END not supported
+               //
+               throw new UnsupportedOperationException("TouchImageView does not support FIT_START or FIT_END");
+               
+        }
+
+        //
+        // Center the image
+        //
+        float redundantXSpace = viewWidth - (scaleX * drawableWidth);
+        float redundantYSpace = viewHeight - (scaleY * drawableHeight);
+        matchViewWidth = viewWidth - redundantXSpace;
+        matchViewHeight = viewHeight - redundantYSpace;
+        if (!isZoomed() && !imageRenderedAtLeastOnce) {
+               //
+               // Stretch and center image to fit view
+               //
+               matrix.setScale(scaleX, scaleY);
+               matrix.postTranslate(redundantXSpace / 2, redundantYSpace / 2);
+               normalizedScale = 1;
+               
+        } else {
+               //
+               // These values should never be 0 or we will set viewWidth and viewHeight
+               // to NaN in translateMatrixAfterRotate. To avoid this, call savePreviousImageValues
+               // to set them equal to the current values.
+               //
+               if (prevMatchViewWidth == 0 || prevMatchViewHeight == 0) {
+                       savePreviousImageValues();
+               }
+               
+               prevMatrix.getValues(m);
+               
+               //
+               // Rescale Matrix after rotation
+               //
+               m[Matrix.MSCALE_X] = matchViewWidth / drawableWidth * normalizedScale;
+               m[Matrix.MSCALE_Y] = matchViewHeight / drawableHeight * normalizedScale;
+               
+               //
+               // TransX and TransY from previous matrix
+               //
+            float transX = m[Matrix.MTRANS_X];
+            float transY = m[Matrix.MTRANS_Y];
+            
+            //
+            // Width
+            //
+            float prevActualWidth = prevMatchViewWidth * normalizedScale;
+            float actualWidth = getImageWidth();
+            translateMatrixAfterRotate(Matrix.MTRANS_X, transX, prevActualWidth, actualWidth, prevViewWidth, viewWidth, drawableWidth);
+            
+            //
+            // Height
+            //
+            float prevActualHeight = prevMatchViewHeight * normalizedScale;
+            float actualHeight = getImageHeight();
+            translateMatrixAfterRotate(Matrix.MTRANS_Y, transY, prevActualHeight, actualHeight, prevViewHeight, viewHeight, drawableHeight);
+            
+            //
+            // Set the matrix to the adjusted scale and translate values.
+            //
+            matrix.setValues(m);
+        }
+        fixTrans();
+        setImageMatrix(matrix);
+    }
+    
+    /**
+     * Set view dimensions based on layout params
+     * 
+     * @param mode 
+     * @param size
+     * @param drawableWidth
+     * @return
+     */
+    private int setViewSize(int mode, int size, int drawableWidth) {
+       int viewSize;
+       switch (mode) {
+               case MeasureSpec.EXACTLY:
+                       viewSize = size;
+                       break;
+                       
+               case MeasureSpec.AT_MOST:
+                       viewSize = Math.min(drawableWidth, size);
+                       break;
+                       
+               case MeasureSpec.UNSPECIFIED:
+                       viewSize = drawableWidth;
+                       break;
+                       
+               default:
+                       viewSize = size;
+                       break;
+               }
+       return viewSize;
+    }
+    
+    /**
+     * After rotating, the matrix needs to be translated. This function finds the area of image 
+     * which was previously centered and adjusts translations so that is again the center, post-rotation.
+     * 
+     * @param axis Matrix.MTRANS_X or Matrix.MTRANS_Y
+     * @param trans the value of trans in that axis before the rotation
+     * @param prevImageSize the width/height of the image before the rotation
+     * @param imageSize width/height of the image after rotation
+     * @param prevViewSize width/height of view before rotation
+     * @param viewSize width/height of view after rotation
+     * @param drawableSize width/height of drawable
+     */
+    private void translateMatrixAfterRotate(int axis, float trans, float prevImageSize, float imageSize, int prevViewSize, int viewSize, int drawableSize) {
+       if (imageSize < viewSize) {
+               //
+               // The width/height of image is less than the view's width/height. Center it.
+               //
+               m[axis] = (viewSize - (drawableSize * m[Matrix.MSCALE_X])) * 0.5f;
+               
+        } else if (trans > 0) {
+               //
+               // The image is larger than the view, but was not before rotation. Center it.
+               //
+               m[axis] = -((imageSize - viewSize) * 0.5f);
+               
+        } else {
+               //
+               // Find the area of the image which was previously centered in the view. Determine its distance
+               // from the left/top side of the view as a fraction of the entire image's width/height. Use that percentage
+               // to calculate the trans in the new view width/height.
+               //
+               float percentage = (Math.abs(trans) + (0.5f * prevViewSize)) / prevImageSize;
+               m[axis] = -((percentage * imageSize) - (viewSize * 0.5f));
+        }
+    }
+    
+    private void setState(State state) {
+       this.state = state;
+    }
+    
+    public boolean canScrollHorizontallyFroyo(int direction) {
+        return canScrollHorizontally(direction);
+    }
+    
+    @Override
+    public boolean canScrollHorizontally(int direction) {
+       matrix.getValues(m);
+       float x = m[Matrix.MTRANS_X];
+       
+       if (getImageWidth() < viewWidth) {
+               return false;
+               
+       } else if (x >= -1 && direction < 0) {
+               return false;
+               
+       } else if (Math.abs(x) + viewWidth + 1 >= getImageWidth() && direction > 0) {
+               return false;
+       }
+       
+       return true;
+    }
+    
+    /**
+     * Gesture Listener detects a single click or long click and passes that on
+     * to the view's listener.
+     * @author Ortiz
+     *
+     */
+    private class GestureListener extends GestureDetector.SimpleOnGestureListener {
+       
+        @Override
+        public boolean onSingleTapConfirmed(MotionEvent e)
+        {
+            if(doubleTapListener != null) {
+               return doubleTapListener.onSingleTapConfirmed(e);
+            }
+               return performClick();
+        }
+        
+        @Override
+        public void onLongPress(MotionEvent e)
+        {
+               performLongClick();
+        }
+        
+        @Override
+        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
+        {
+               if (fling != null) {
+                       //
+                       // If a previous fling is still active, it should be cancelled so that two flings
+                       // are not run simultaenously.
+                       //
+                       fling.cancelFling();
+               }
+               fling = new Fling((int) velocityX, (int) velocityY);
+               compatPostOnAnimation(fling);
+               return super.onFling(e1, e2, velocityX, velocityY);
+        }
+        
+        @Override
+        public boolean onDoubleTap(MotionEvent e) {
+               boolean consumed = false;
+            if(doubleTapListener != null) {
+               consumed = doubleTapListener.onDoubleTap(e);
+            }
+               if (state == State.NONE) {
+                       float targetZoom = (normalizedScale == minScale) ? maxScale : minScale;
+                       DoubleTapZoom doubleTap = new DoubleTapZoom(targetZoom, e.getX(), e.getY(), false);
+                       compatPostOnAnimation(doubleTap);
+                       consumed = true;
+               }
+               return consumed;
+        }
+
+        @Override
+        public boolean onDoubleTapEvent(MotionEvent e) {
+            if(doubleTapListener != null) {
+               return doubleTapListener.onDoubleTapEvent(e);
+            }
+            return false;
+        }
+    }
+    
+    public interface OnTouchImageViewListener {
+       public void onMove();
+    }
+    
+    /**
+     * Responsible for all touch events. Handles the heavy lifting of drag and also sends
+     * touch events to Scale Detector and Gesture Detector.
+     * @author Ortiz
+     *
+     */
+    private class PrivateOnTouchListener implements OnTouchListener {
+       
+       //
+        // Remember last point position for dragging
+        //
+        private PointF last = new PointF();
+       
+       @Override
+        public boolean onTouch(View v, MotionEvent event) {
+            mScaleDetector.onTouchEvent(event);
+            mGestureDetector.onTouchEvent(event);
+            PointF curr = new PointF(event.getX(), event.getY());
+            
+            if (state == State.NONE || state == State.DRAG || state == State.FLING) {
+                   switch (event.getAction()) {
+                       case MotionEvent.ACTION_DOWN:
+                               last.set(curr);
+                           if (fling != null)
+                               fling.cancelFling();
+                           setState(State.DRAG);
+                           break;
+                           
+                       case MotionEvent.ACTION_MOVE:
+                           if (state == State.DRAG) {
+                               float deltaX = curr.x - last.x;
+                               float deltaY = curr.y - last.y;
+                               float fixTransX = getFixDragTrans(deltaX, viewWidth, getImageWidth());
+                               float fixTransY = getFixDragTrans(deltaY, viewHeight, getImageHeight());
+                               matrix.postTranslate(fixTransX, fixTransY);
+                               fixTrans();
+                               last.set(curr.x, curr.y);
+                           }
+                           break;
+       
+                       case MotionEvent.ACTION_UP:
+                       case MotionEvent.ACTION_POINTER_UP:
+                           setState(State.NONE);
+                           break;
+                   }
+            }
+            
+            setImageMatrix(matrix);
+            
+            //
+               // User-defined OnTouchListener
+               //
+               if(userTouchListener != null) {
+                       userTouchListener.onTouch(v, event);
+               }
+            
+               //
+               // OnTouchImageViewListener is set: TouchImageView dragged by user.
+               //
+               if (touchImageViewListener != null) {
+                       touchImageViewListener.onMove();
+               }
+               
+            //
+            // indicate event was handled
+            //
+            return true;
+        }
+    }
+
+    /**
+     * ScaleListener detects user two finger scaling and scales image.
+     * @author Ortiz
+     *
+     */
+    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+        @Override
+        public boolean onScaleBegin(ScaleGestureDetector detector) {
+            setState(State.ZOOM);
+            return true;
+        }
+
+        @Override
+        public boolean onScale(ScaleGestureDetector detector) {
+               scaleImage(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY(), true);
+               
+               //
+               // OnTouchImageViewListener is set: TouchImageView pinch zoomed by user.
+               //
+               if (touchImageViewListener != null) {
+                       touchImageViewListener.onMove();
+               }
+            return true;
+        }
+        
+        @Override
+        public void onScaleEnd(ScaleGestureDetector detector) {
+               super.onScaleEnd(detector);
+               setState(State.NONE);
+               boolean animateToZoomBoundary = false;
+               float targetZoom = normalizedScale;
+               if (normalizedScale > maxScale) {
+                       targetZoom = maxScale;
+                       animateToZoomBoundary = true;
+                       
+               } else if (normalizedScale < minScale) {
+                       targetZoom = minScale;
+                       animateToZoomBoundary = true;
+               }
+               
+               if (animateToZoomBoundary) {
+                       DoubleTapZoom doubleTap = new DoubleTapZoom(targetZoom, viewWidth / 2, viewHeight / 2, true);
+                       compatPostOnAnimation(doubleTap);
+               }
+        }
+    }
+    
+    private void scaleImage(double deltaScale, float focusX, float focusY, boolean stretchImageToSuper) {
+       
+       float lowerScale, upperScale;
+       if (stretchImageToSuper) {
+               lowerScale = superMinScale;
+               upperScale = superMaxScale;
+               
+       } else {
+               lowerScale = minScale;
+               upperScale = maxScale;
+       }
+       
+       float origScale = normalizedScale;
+        normalizedScale *= deltaScale;
+        if (normalizedScale > upperScale) {
+            normalizedScale = upperScale;
+            deltaScale = upperScale / origScale;
+        } else if (normalizedScale < lowerScale) {
+            normalizedScale = lowerScale;
+            deltaScale = lowerScale / origScale;
+        }
+        
+        matrix.postScale((float) deltaScale, (float) deltaScale, focusX, focusY);
+        fixScaleTrans();
+    }
+    
+    /**
+     * DoubleTapZoom calls a series of runnables which apply
+     * an animated zoom in/out graphic to the image.
+     * @author Ortiz
+     *
+     */
+    private class DoubleTapZoom implements Runnable {
+       
+       private long startTime;
+       private static final float ZOOM_TIME = 500;
+       private float startZoom, targetZoom;
+       private float bitmapX, bitmapY;
+       private boolean stretchImageToSuper;
+       private AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
+       private PointF startTouch;
+       private PointF endTouch;
+
+       DoubleTapZoom(float targetZoom, float focusX, float focusY, boolean stretchImageToSuper) {
+               setState(State.ANIMATE_ZOOM);
+               startTime = System.currentTimeMillis();
+               this.startZoom = normalizedScale;
+               this.targetZoom = targetZoom;
+               this.stretchImageToSuper = stretchImageToSuper;
+               PointF bitmapPoint = transformCoordTouchToBitmap(focusX, focusY, false);
+               this.bitmapX = bitmapPoint.x;
+               this.bitmapY = bitmapPoint.y;
+               
+               //
+               // Used for translating image during scaling
+               //
+               startTouch = transformCoordBitmapToTouch(bitmapX, bitmapY);
+               endTouch = new PointF(viewWidth / 2, viewHeight / 2);
+       }
+
+               @Override
+               public void run() {
+                       float t = interpolate();
+                       double deltaScale = calculateDeltaScale(t);
+                       scaleImage(deltaScale, bitmapX, bitmapY, stretchImageToSuper);
+                       translateImageToCenterTouchPosition(t);
+                       fixScaleTrans();
+                       setImageMatrix(matrix);
+                       
+                       //
+                       // OnTouchImageViewListener is set: double tap runnable updates listener
+                       // with every frame.
+                       //
+                       if (touchImageViewListener != null) {
+                               touchImageViewListener.onMove();
+                       }
+                       
+                       if (t < 1f) {
+                               //
+                               // We haven't finished zooming
+                               //
+                               compatPostOnAnimation(this);
+                               
+                       } else {
+                               //
+                               // Finished zooming
+                               //
+                               setState(State.NONE);
+                       }
+               }
+               
+               /**
+                * Interpolate between where the image should start and end in order to translate
+                * the image so that the point that is touched is what ends up centered at the end
+                * of the zoom.
+                * @param t
+                */
+               private void translateImageToCenterTouchPosition(float t) {
+                       float targetX = startTouch.x + t * (endTouch.x - startTouch.x);
+                       float targetY = startTouch.y + t * (endTouch.y - startTouch.y);
+                       PointF curr = transformCoordBitmapToTouch(bitmapX, bitmapY);
+                       matrix.postTranslate(targetX - curr.x, targetY - curr.y);
+               }
+               
+               /**
+                * Use interpolator to get t
+                * @return
+                */
+               private float interpolate() {
+                       long currTime = System.currentTimeMillis();
+                       float elapsed = (currTime - startTime) / ZOOM_TIME;
+                       elapsed = Math.min(1f, elapsed);
+                       return interpolator.getInterpolation(elapsed);
+               }
+               
+               /**
+                * Interpolate the current targeted zoom and get the delta
+                * from the current zoom.
+                * @param t
+                * @return
+                */
+               private double calculateDeltaScale(float t) {
+                       double zoom = startZoom + t * (targetZoom - startZoom);
+                       return zoom / normalizedScale;
+               }
+    }
+    
+    /**
+     * This function will transform the coordinates in the touch event to the coordinate 
+     * system of the drawable that the imageview contain
+     * @param x x-coordinate of touch event
+     * @param y y-coordinate of touch event
+     * @param clipToBitmap Touch event may occur within view, but outside image content. True, to clip return value
+     *                         to the bounds of the bitmap size.
+     * @return Coordinates of the point touched, in the coordinate system of the original drawable.
+     */
+    private PointF transformCoordTouchToBitmap(float x, float y, boolean clipToBitmap) {
+         matrix.getValues(m);
+         float origW = getDrawable().getIntrinsicWidth();
+         float origH = getDrawable().getIntrinsicHeight();
+         float transX = m[Matrix.MTRANS_X];
+         float transY = m[Matrix.MTRANS_Y];
+         float finalX = ((x - transX) * origW) / getImageWidth();
+         float finalY = ((y - transY) * origH) / getImageHeight();
+         
+         if (clipToBitmap) {
+                finalX = Math.min(Math.max(finalX, 0), origW);
+                finalY = Math.min(Math.max(finalY, 0), origH);
+         }
+         
+         return new PointF(finalX , finalY);
+    }
+    
+    /**
+     * Inverse of transformCoordTouchToBitmap. This function will transform the coordinates in the
+     * drawable's coordinate system to the view's coordinate system.
+     * @param bx x-coordinate in original bitmap coordinate system
+     * @param by y-coordinate in original bitmap coordinate system
+     * @return Coordinates of the point in the view's coordinate system.
+     */
+    private PointF transformCoordBitmapToTouch(float bx, float by) {
+        matrix.getValues(m);        
+        float origW = getDrawable().getIntrinsicWidth();
+        float origH = getDrawable().getIntrinsicHeight();
+        float px = bx / origW;
+        float py = by / origH;
+        float finalX = m[Matrix.MTRANS_X] + getImageWidth() * px;
+        float finalY = m[Matrix.MTRANS_Y] + getImageHeight() * py;
+        return new PointF(finalX , finalY);
+    }
+    
+    /**
+     * Fling launches sequential runnables which apply
+     * the fling graphic to the image. The values for the translation
+     * are interpolated by the Scroller.
+     * @author Ortiz
+     *
+     */
+    private class Fling implements Runnable {
+       
+        CompatScroller scroller;
+       int currX, currY;
+       
+       Fling(int velocityX, int velocityY) {
+               setState(State.FLING);
+               scroller = new CompatScroller(context);
+               matrix.getValues(m);
+               
+               int startX = (int) m[Matrix.MTRANS_X];
+               int startY = (int) m[Matrix.MTRANS_Y];
+               int minX, maxX, minY, maxY;
+               
+               if (getImageWidth() > viewWidth) {
+                       minX = viewWidth - (int) getImageWidth();
+                       maxX = 0;
+                       
+               } else {
+                       minX = maxX = startX;
+               }
+               
+               if (getImageHeight() > viewHeight) {
+                       minY = viewHeight - (int) getImageHeight();
+                       maxY = 0;
+                       
+               } else {
+                       minY = maxY = startY;
+               }
+               
+               scroller.fling(startX, startY, (int) velocityX, (int) velocityY, minX,
+                    maxX, minY, maxY);
+               currX = startX;
+               currY = startY;
+       }
+       
+       public void cancelFling() {
+               if (scroller != null) {
+                       setState(State.NONE);
+                       scroller.forceFinished(true);
+               }
+       }
+       
+               @Override
+               public void run() {
+                       
+                       //
+                       // OnTouchImageViewListener is set: TouchImageView listener has been flung by user.
+                       // Listener runnable updated with each frame of fling animation.
+                       //
+                       if (touchImageViewListener != null) {
+                               touchImageViewListener.onMove();
+                       }
+                       
+                       if (scroller.isFinished()) {
+                       scroller = null;
+                       return;
+               }
+                       
+                       if (scroller.computeScrollOffset()) {
+                       int newX = scroller.getCurrX();
+                   int newY = scroller.getCurrY();
+                   int transX = newX - currX;
+                   int transY = newY - currY;
+                   currX = newX;
+                   currY = newY;
+                   matrix.postTranslate(transX, transY);
+                   fixTrans();
+                   setImageMatrix(matrix);
+                   compatPostOnAnimation(this);
+               }
+               }
+    }
+    
+    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+       private class CompatScroller {
+       Scroller scroller;
+       OverScroller overScroller;
+       boolean isPreGingerbread;
+       
+       public CompatScroller(Context context) {
+               if (VERSION.SDK_INT < VERSION_CODES.GINGERBREAD) {
+                       isPreGingerbread = true;
+                       scroller = new Scroller(context);
+                       
+               } else {
+                       isPreGingerbread = false;
+                       overScroller = new OverScroller(context);
+               }
+       }
+       
+       public void fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY) {
+               if (isPreGingerbread) {
+                       scroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
+               } else {
+                       overScroller.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY);
+               }
+       }
+       
+       public void forceFinished(boolean finished) {
+               if (isPreGingerbread) {
+                       scroller.forceFinished(finished);
+               } else {
+                       overScroller.forceFinished(finished);
+               }
+       }
+       
+       public boolean isFinished() {
+               if (isPreGingerbread) {
+                       return scroller.isFinished();
+               } else {
+                       return overScroller.isFinished();
+               }
+       }
+       
+       public boolean computeScrollOffset() {
+               if (isPreGingerbread) {
+                       return scroller.computeScrollOffset();
+               } else {
+                       overScroller.computeScrollOffset();
+                       return overScroller.computeScrollOffset();
+               }
+       }
+       
+       public int getCurrX() {
+               if (isPreGingerbread) {
+                       return scroller.getCurrX();
+               } else {
+                       return overScroller.getCurrX();
+               }
+       }
+       
+       public int getCurrY() {
+               if (isPreGingerbread) {
+                       return scroller.getCurrY();
+               } else {
+                       return overScroller.getCurrY();
+               }
+       }
+    }
+    
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+       private void compatPostOnAnimation(Runnable runnable) {
+       if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
+            postOnAnimation(runnable);
+            
+        } else {
+            postDelayed(runnable, 1000/60);
+        }
+    }
+    
+    private class ZoomVariables {
+       public float scale;
+       public float focusX;
+       public float focusY;
+       public ScaleType scaleType;
+       
+       public ZoomVariables(float scale, float focusX, float focusY, ScaleType scaleType) {
+               this.scale = scale;
+               this.focusX = focusX;
+               this.focusY = focusY;
+               this.scaleType = scaleType;
+       }
+    }
+    
+    private void printMatrixInfo() {
+       float[] n = new float[9];
+       matrix.getValues(n);
+       Log.d(DEBUG, "Scale: " + n[Matrix.MSCALE_X] + " TransX: " + n[Matrix.MTRANS_X] + " TransY: " + n[Matrix.MTRANS_Y]);
+    }
+}
\ No newline at end of file
index fc6dc21..769b98b 100644 (file)
@@ -1,6 +1,8 @@
-/* ownCloud Android client application
+/**
+ *   ownCloud Android client application
+ *
  *   Copyright (C) 2012  Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,