Merge remote-tracking branch 'remotes/upstream/material_buttons' into beta
authortobiasKaminsky <tobias@kaminsky.me>
Fri, 27 Nov 2015 16:48:20 +0000 (17:48 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Fri, 27 Nov 2015 16:48:20 +0000 (17:48 +0100)
254 files changed:
.gitignore
.travis.yml
AndroidManifest.xml
CHANGELOG.md
README.md
SETUP.md
THIRD_PARTY.txt
apks/latest [new file with mode: 0644]
apks/latest.apk [new file with mode: 0644]
apks/owncloud-beta-2015-10-26.apk [new file with mode: 0644]
apks/owncloud-beta-2015-10-29.apk [new file with mode: 0644]
apks/owncloud-beta-2015-10-30.apk [new file with mode: 0644]
apks/owncloud-beta-2015-10-31-10-00-00.apk [new file with mode: 0644]
apks/owncloud-beta-2015-10-31.apk [new file with mode: 0644]
apks/owncloud-beta-2015-11-01.apk [new file with mode: 0644]
apks/owncloud-beta-2015-11-02.apk [new file with mode: 0644]
apks/owncloud-beta-20151105.apk [new file with mode: 0644]
apks/owncloud-beta-20151109.apk [new file with mode: 0644]
apks/owncloud-beta-20151113.apk [new file with mode: 0644]
apks/owncloud-beta-20151118.apk [new file with mode: 0644]
apks/owncloud-beta-20151120.apk [new file with mode: 0644]
apks/owncloud-beta-20151121.apk [new file with mode: 0644]
apks/owncloud-beta-20151124.apk [new file with mode: 0644]
apks/owncloud-beta-20151125.apk [new file with mode: 0644]
build.gradle
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/.classpath [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/AndroidManifest.xml [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/R.txt [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/aapt/AndroidManifest.xml [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/annotations.zip [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/build.xml [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/jars/classes.jar [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/libs/classes.jar [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/proguard.txt [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/project.properties [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_mini.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_normal.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_mini.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_normal.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_mini.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_normal.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_mini.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_normal.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_mini.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_normal.png [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/values/values.xml [new file with mode: 0644]
libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/src/.readme [new file with mode: 0644]
oc_jb_workaround/build.gradle
owncloud-android-library
project.properties
res/drawable-hdpi-v9/ic_action_download.png [deleted file]
res/drawable-hdpi-v9/ic_action_refresh.png [deleted file]
res/drawable-hdpi-v9/ic_action_settings.png [deleted file]
res/drawable-hdpi/ic_action_download_grey.png [new file with mode: 0644]
res/drawable-hdpi/ic_checkbox_blank_outline.png
res/drawable-hdpi/ic_checkbox_marked.png
res/drawable-hdpi/ic_import.png [new file with mode: 0644]
res/drawable-hdpi/ic_play_arrow.png [new file with mode: 0644]
res/drawable-hdpi/ic_view_list.png [new file with mode: 0644]
res/drawable-hdpi/ic_view_module.png [new file with mode: 0644]
res/drawable-hdpi/icon.png
res/drawable-hdpi/view_play.png [new file with mode: 0644]
res/drawable-mdpi-v9/ic_action_download.png [deleted file]
res/drawable-mdpi-v9/ic_action_refresh.png [deleted file]
res/drawable-mdpi-v9/ic_action_settings.png [deleted file]
res/drawable-mdpi/ic_action_download_grey.png [new file with mode: 0644]
res/drawable-mdpi/ic_checkbox_blank_outline.png [new file with mode: 0644]
res/drawable-mdpi/ic_checkbox_marked.png [new file with mode: 0644]
res/drawable-mdpi/ic_import.png [new file with mode: 0644]
res/drawable-mdpi/ic_play_arrow.png [new file with mode: 0644]
res/drawable-mdpi/ic_view_list.png [new file with mode: 0644]
res/drawable-mdpi/ic_view_module.png [new file with mode: 0644]
res/drawable-mdpi/icon.png
res/drawable-mdpi/view_play.png [new file with mode: 0644]
res/drawable-xhdpi/ic_action_download_grey.png [new file with mode: 0644]
res/drawable-xhdpi/ic_action_settings.png [new file with mode: 0644]
res/drawable-xhdpi/ic_import.png [new file with mode: 0644]
res/drawable-xhdpi/ic_play_arrow.png [new file with mode: 0644]
res/drawable-xhdpi/ic_view_list.png [new file with mode: 0644]
res/drawable-xhdpi/ic_view_module.png [new file with mode: 0644]
res/drawable-xhdpi/icon.png
res/drawable-xhdpi/view_play.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_action_download_grey.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_action_settings.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_import.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_play_arrow.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_settings.png [deleted file]
res/drawable-xxhdpi/ic_sort_variant.png [new file with mode: 0644]
res/drawable-xxhdpi/icon.png [new file with mode: 0644]
res/drawable-xxhdpi/view_play.png [new file with mode: 0644]
res/drawable-xxxhdpi/icon.png [new file with mode: 0644]
res/drawable-xxxhdpi/view_play.png [new file with mode: 0644]
res/drawable/fab_label_background.xml [new file with mode: 0644]
res/layout/error_send.xml [new file with mode: 0644]
res/layout/grid_image.xml
res/layout/grid_item.xml
res/layout/list_footer.xml
res/layout/list_fragment.xml
res/layout/migration_layout.xml [new file with mode: 0644]
res/layout/share_file_layout.xml
res/layout/upload_files_layout.xml
res/layout/uploader_layout.xml
res/layout/uploader_list_item_layout.xml
res/menu/file_actions_menu.xml
res/menu/main_menu.xml
res/menu/multiple_file_actions_menu.xml [new file with mode: 0644]
res/menu/uploader_menu.xml [new file with mode: 0644]
res/values-af-rZA/strings.xml
res/values-ar/strings.xml
res/values-az/strings.xml
res/values-bg-rBG/strings.xml
res/values-bn-rBD/strings.xml
res/values-bn-rIN/strings.xml
res/values-bs/strings.xml
res/values-ca/strings.xml
res/values-cs-rCZ/strings.xml
res/values-cy-rGB/strings.xml
res/values-da/strings.xml
res/values-de-rAT/strings.xml
res/values-de-rCH/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-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-hi/strings.xml
res/values-hr/strings.xml
res/values-hu-rHU/strings.xml
res/values-hy/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-lb/strings.xml
res/values-lt-rLT/strings.xml
res/values-lv/strings.xml
res/values-mk/strings.xml
res/values-mn/strings.xml
res/values-ms-rMY/strings.xml
res/values-my/strings.xml
res/values-nb-rNO/strings.xml
res/values-nl/strings.xml
res/values-nn-rNO/strings.xml
res/values-oc/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-rRU/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-rSP/strings.xml
res/values-sr/strings.xml
res/values-sv/strings.xml
res/values-ta-rLK/strings.xml
res/values-th-rTH/strings.xml
res/values-tr/strings.xml
res/values-tzl/strings.xml [deleted file]
res/values-ug/strings.xml
res/values-uk/strings.xml
res/values-ur-rPK/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/attrs.xml
res/values/colors.xml
res/values/drawer_resources.xml
res/values/setup.xml
res/values/strings.xml
res/values/styles.xml
res/xml/preferences.xml
setup_env.bat
setup_env.sh
src/com/owncloud/android/MainApp.java
src/com/owncloud/android/authentication/PassCodeManager.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/files/FileMenuFilter.java
src/com/owncloud/android/files/FileOperationsHelper.java
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java
src/com/owncloud/android/files/services/FileUploader.java
src/com/owncloud/android/media/MediaService.java
src/com/owncloud/android/operations/CreateFolderOperation.java
src/com/owncloud/android/operations/CreateShareViaLinkOperation.java
src/com/owncloud/android/operations/GetSharesForFileOperation.java
src/com/owncloud/android/operations/RefreshFolderOperation.java
src/com/owncloud/android/operations/SynchronizeFolderOperation.java
src/com/owncloud/android/operations/UnshareOperation.java
src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java [new file with mode: 0644]
src/com/owncloud/android/operations/UploadFileOperation.java
src/com/owncloud/android/services/OperationsService.java
src/com/owncloud/android/ui/activity/ErrorReportActivity.java [new file with mode: 0644]
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/LocalDirectorySelectorActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/PassCodeActivity.java
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/ShareActivity.java
src/com/owncloud/android/ui/activity/StorageMigrationActivity.java [new file with mode: 0644]
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/DiskLruImageCache.java
src/com/owncloud/android/ui/adapter/DiskLruImageCacheFileProvider.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/FileListListAdapter.java
src/com/owncloud/android/ui/adapter/LocalFileListAdapter.java
src/com/owncloud/android/ui/dialog/AccountActionsDialogFragment.java
src/com/owncloud/android/ui/dialog/ExpirationDatePickerDialogFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/dialog/OwnCloudListPreference.java [new file with mode: 0644]
src/com/owncloud/android/ui/dialog/RemoveFileDialogFragment.java
src/com/owncloud/android/ui/dialog/RemoveFilesDialogFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/dialog/ShareLinkToDialog.java
src/com/owncloud/android/ui/dialog/SharePasswordDialogFragment.java
src/com/owncloud/android/ui/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/FileDetailFragment.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java
src/com/owncloud/android/ui/fragment/ShareFileFragment.java
src/com/owncloud/android/ui/preview/ImageViewCustom.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/PreviewTextFragment.java
src/com/owncloud/android/ui/preview/PreviewVideoActivity.java
src/com/owncloud/android/utils/DisplayUtils.java
src/com/owncloud/android/utils/ErrorMessageAdapter.java
src/com/owncloud/android/utils/ExceptionHandler.java [new file with mode: 0644]
src/com/owncloud/android/utils/FileStorageUtils.java
src/third_parties/daveKoeller/AlphanumComparator.java

index 8346dbf..009ead4 100644 (file)
@@ -1,5 +1,4 @@
 # built application files
-*.apk
 *.ap_
 
 # files for the dex VM
@@ -14,6 +13,7 @@ build/
 *.iml
 gen/
 target/
+build/
 
 # Local configuration files (sdk path, etc)
 local.properties
@@ -39,4 +39,4 @@ tests/proguard-project.txt
 build
 
 # Actionbarsherlock is now ignored since scripts takes care of init the sub-modules.
-actionbarsherlock
\ No newline at end of file
+actionbarsherlock
index 0db9b1e..1d64863 100644 (file)
@@ -8,6 +8,6 @@ before_install:
   - rm pom.xml
 script:
   - ./setup_env.sh ant
-  - ant clean
-  - ant debug
+  - ant clean -Djava.source=7 -Djava.target=7
+  - ant debug -Djava.source=7 -Djava.target=7
   
index 805e9ce..761afad 100644 (file)
 
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.owncloud.android"
-    android:versionCode="10800000"
-    android:versionName="1.8.0" >
+ -->
+<manifest package="com.owncloud.android"
+    android:versionCode="20151125"
+    android:versionName="ownCloud beta" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-sdk
         android:minSdkVersion="14"
             </intent-filter>
         </activity>
         <activity android:name=".ui.activity.UploadFilesActivity" />
-        <activity android:name=".ui.activity.Uploader" >
+        <activity android:name=".ui.activity.LocalDirectorySelectorActivity" />
+        <activity android:name=".ui.activity.StorageMigrationActivity" />
+        <activity android:name=".ui.activity.Uploader"
+            android:label="@string/uploader_top_message"
+            android:theme="@style/Theme.ownCloud">
             <intent-filter>
                 <action android:name="android.intent.action.SEND" />
 
             android:name=".providers.FileContentProvider"
             android:authorities="@string/authority"
             android:enabled="true"
-            android:exported="false"
+            android:exported="true"
             android:label="@string/sync_string_files"
             android:syncable="true" />
 
             android:exported="false"
             android:label="@string/search_users_and_groups_hint" />
 
+        <provider
+            android:name=".ui.adapter.DiskLruImageCacheFileProvider"
+            android:authorities="@string/authorityCache"
+            android:exported="true">
+        </provider>
+
         <activity
             android:name=".authentication.AuthenticatorActivity"
             android:exported="true"
         <service android:name=".media.MediaService" />
 
         <activity android:name=".ui.activity.PassCodeActivity" />
-        <activity android:name=".ui.activity.ConflictsResolveActivity" />
-        <activity android:name=".ui.activity.GenericExplanationActivity" />
-        <activity android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity" />
-        <activity android:name=".ui.activity.LogHistoryActivity" />
-
-        <receiver android:name=".files.InstantUploadBroadcastReceiver" >
+        <activity android:name=".ui.activity.ConflictsResolveActivity"/>
+        <activity android:name=".ui.activity.GenericExplanationActivity"/>
+        <activity android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity"/>
+        
+        <activity android:name=".ui.activity.LogHistoryActivity"/>
+        <activity android:name=".ui.activity.ErrorReportActivity"/>
+
+        <receiver android:name=".files.InstantUploadBroadcastReceiver">
             <intent-filter>
 
                 <!-- unofficially supported by many Android phones but not by HTC devices: -->
             <intent-filter>
                 <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
             </intent-filter>
+            <intent-filter>
+                               <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
+                           <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
+                       </intent-filter>
         </receiver>
         <receiver android:name=".files.BootupBroadcastReceiver" >
             <intent-filter>
index 099a445..c81530a 100644 (file)
@@ -1,60 +1,60 @@
-## 1.8.0 (September 2015)
-- New MATERIAL DESIGN theme
-- Updated FILE TYPE ICONS
-- Preview TXT files within the app
-- COPY files & folders
-- Preview the full file/folder name from the long press menu
-- Set a file as FAVORITE (kept-in-sync) from the CONTEXT MENU
-- Updated CONFLICT RESOLUTION dialog (wording)
-- Updated background for images with TRANSPARENCY in GALLERY
-- Hidden files will not enforce list view instead of GRID VIEW (folders from Picasa & others)
-- Security:
-  + Updated network stack with security fixes (Jackrabbit 2.10.1)
-- Bugs fixed:
-  + Fixed crash when ETag is lost
-  + Passcode creation not restarted on device rotation
-  + Recovered share icon shown on folders 'shared with me'
-  + User name added to subject when sending a share link through e-mail (fixed on SAMLed apps)
-
-## 1.7.2 (July 2015)
-- New navigation drawer
-- Improved Passcode
-- Automatic grid view just for folders full of images
-- More characters allowed in file names
-- Support for servers in same domain, different path
-- Bugs fixed:
-  + Frequent crashes in folder with several images
-  + Sync error in servers with huge quota and external storage enable
-  + Share by link error 
-  + Some other crashes and minor bugs
-
-## 1.7.1 (April 2015)
-
-- Share link even with password enforced by server
-- Get the app ready for oc 8.1 servers
-- Added option to create new folder in uploads from external apps
-- Improved management of deleted users
-- Bugs fixed
-  + Fixed crash on Android 2.x devices
-  + Improvements on uploads
-
-## 1.7.0 (February 2015)
-
-- Download full folders
-- Grid view for images
-- Remote thumbnails (OC Server 8.0+)
-- Added number of files and folders at the end of the list
-- "Open with" in contextual menu
-- Downloads added to Media Provider
-- Uploads:
-  + Local thumbnails in section "Files"
-  + Multiple selection in "Content from other apps" (Android 4.3+)
-- Gallery: 
-  + proper handling of EXIF
-  + obey sorting in the list of files
-- Settings view updated
-- Improved subjects in e-mails
-- Bugs fixed
-
-
-
+# 2015-11-21
+- fix #1297
+- update all PR
+- try for #1278
+
+# 2015-11-20
+- PR [#1293] (https://github.com/owncloud/android/pull/1293) "External SD by przybylski" merged
+- PR [#1296] (https://github.com/owncloud/android/pull/1296) "Don't allow to remove passcode without entering it. Don't allow to set incomplete passcode by przybylski" merged
+
+# 2015-11-18
+- update all PR
+- fix #1259
+
+# 2015-11-13
+- update all PR
+
+# 2015-11-10
+- update master
+- PR [#1277] (https://github.com/owncloud/android/pull/1277) "Optimized uploader layout and user configured sorting" merged
+
+# 2015-11-05
+- update master
+- fix #1244
+- add changelog
+- add check for update of beta version
+
+# 2015-11-02
+- PR [#1240](https://github.com/owncloud/android/pull/1240) "Set as wallpaper" merged
+- updated other PRs
+
+# 2015-11-01
+- PR [#1236](https://github.com/owncloud/android/pull/1236) "Streaming video/audio" merged
+- PR [#1035](https://github.com/owncloud/android/pull/1035) "Enable video thumbnail" merged
+
+# 2015-10-31
+- updated all PR
+- bugfix: #1234, #1230
+- implement Crash Handler
+- implement direct download of latest apk in settings -> last item on bottom
+
+# 2015-10-30
+- fixed problem with Authority
+
+# 2015-10-29
+- PR [#1099](https://github.com/owncloud/android/pull/1099) "Switch list vs grid" merged
+- PR [#1100](https://github.com/owncloud/android/pull/1100) "Material FAB with speed dial implementation" merged
+- PR [#1209](https://github.com/owncloud/android/pull/1209) "Material buttons - before in #1090" merged
+- PR [#1205](https://github.com/owncloud/android/pull/1205) "Switch between online and offline files" merged
+- PR [#1195](https://github.com/owncloud/android/pull/1195) "Resize Cache" merged
+- PR [#1187](https://github.com/owncloud/android/pull/1187) "Video: Big thumbnails" merged
+- PR [#1058](https://github.com/owncloud/android/pull/1058) "add sort to UploadFileActiviy" merged
+- PR [#1168](https://github.com/owncloud/android/pull/1168) "Avoid duplicate files" merged
+- PR [#1176](https://github.com/owncloud/android/pull/1176) "Multi select" merged
+
+
+# 2015-10-26
+- start of branch
+- PR [#745](https://github.com/owncloud/android/pull/745) merged
+- PR [#1044](https://github.com/owncloud/android/pull/1044) merged: < 8.1: GalleryPlus app needed, >= 8.2 Gallery app needed
+- PR [#1111](https://github.com/owncloud/android/pull/1111) merged
\ No newline at end of file
index e3ff535..a239144 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,11 +1,18 @@
-#This is the Android client for [ownCloud][0]
+#This is the BETA Android client for [ownCloud][0]
+
+The BETA app is only intended to be used by experienced users that want to use and test the latest features.
+All pull requests labeled "3 - to review" or higher will be included into the branch.
+
+If you find a bug please verify first if it is *really* a bug in beta, then comment in the corresponding pull request or create a new issue with the prefix "Beta YYYY-MM-DD:".
+
+The compiled APKs can be found [here][2]
+
+The changelog is found [here][3]
 
 The app performs file synchronization with an ownCloud server. Other ownCloud features may be added in the future, but they are not a priority right now.
 
 ## Build Status on
-Git master: ![Build Status](https://api.travis-ci.org/owncloud/android.svg?branch=master)
-
-Git stable:  ![Build Status](https://api.travis-ci.org/owncloud/android.svg?branch=stable)
+Git beta: ![Build Status](https://api.travis-ci.org/owncloud/android.svg?branch=beta)
 
 ## Development
 
@@ -14,6 +21,8 @@ Make sure you read [SETUP.md][1] when you start working on this project.
 
 [0]: https://github.com/owncloud/core
 [1]: https://github.com/owncloud/android/blob/master/SETUP.md
+[2]: https://github.com/owncloud/android/tree/beta/apks/
+[3]: https://github.com/owncloud/android/blob/beta/CHANGELOG.md
 
 ### Contributing
 Please see [Contribution Guidelines](https://owncloud.org/contribute/). Fork this repository and contribute back using
index 0f1bc8e..64c04c9 100644 (file)
--- a/SETUP.md
+++ b/SETUP.md
@@ -90,6 +90,7 @@ The generated APK file is saved in android/build/outputs/apk as android-debug.ap
 * Choose the projects with the next names under the 'New Project Name' column:
 ** owncloud-android 
 ** android-support-appcompat-v7-exploded-aar
+** com-getbase-floatingactionbutton-1-10-0-exploded-aar
 ** owncloud-android-workaround-accounts        (optional)
 ** ownCloud Android Library
 ** ownCloud Sample Client (optional)
@@ -102,11 +103,12 @@ The generated APK file is saved in android/build/outputs/apk as android-debug.ap
 * If any error persists, clean and build manually the next projects in order:
 ** ownCloud Android Library
 ** android-support-appcompat-v7-exploded-aar
+** com-getbase-floatingactionbutton-1-10-0-exploded-aar
 ** owncloud-android
 * If any error on those projects persists, check the project properties. In the 'Android' section, API Level should be
 ** ownCloud Android Library    -> API level 19
 ** android-support-appcompat-v7-exploded-aa -> API level 22
-** owncloud-android    -> API level 22 ; in this project, two library projects should appear referred in the bottom of the dialog: libs\android-support-appcompat-v7-exploded-aar and owncloud-android-library. Add them if needed.
+** owncloud-android    -> API level 22 ; in this project, three library projects should appear referred in the bottom of the dialog: libs\android-support-appcompat-v7-exploded-aar, ** com-getbase-floatingactionbutton-1-10-0-exploded-aar and owncloud-android-library. Add them if needed.
 * After those actions you should be good to go. HAVE FUN!
 
 
index 6fd3e5b..034ecb3 100644 (file)
@@ -59,4 +59,8 @@ The third party software included and used by this project is:
    modifications com.ortiz.touch.ExtendedViewPager and com.ortiz.touch.TouchImageView classes. 
    See https://github.com/MikeOrtiz/TouchImageView
  
\ No newline at end of file
+ * floatingactionbutton 1.10.0.
+   Copyright (c) 2014 Jerzy Chalupski
+   Licensed under Apache License, Version 2.0.
+   placed at libs/com-getbase-floatingactionbutton-1-10-0-exploded-aar has been exploded by ownCloud Inc.
+   See https://github.com/futuresimple/android-floating-action-button 
\ No newline at end of file
diff --git a/apks/latest b/apks/latest
new file mode 100644 (file)
index 0000000..024060d
--- /dev/null
@@ -0,0 +1 @@
+20151125
diff --git a/apks/latest.apk b/apks/latest.apk
new file mode 100644 (file)
index 0000000..aa2cf9d
Binary files /dev/null and b/apks/latest.apk differ
diff --git a/apks/owncloud-beta-2015-10-26.apk b/apks/owncloud-beta-2015-10-26.apk
new file mode 100644 (file)
index 0000000..61a3b3b
Binary files /dev/null and b/apks/owncloud-beta-2015-10-26.apk differ
diff --git a/apks/owncloud-beta-2015-10-29.apk b/apks/owncloud-beta-2015-10-29.apk
new file mode 100644 (file)
index 0000000..0b07ac8
Binary files /dev/null and b/apks/owncloud-beta-2015-10-29.apk differ
diff --git a/apks/owncloud-beta-2015-10-30.apk b/apks/owncloud-beta-2015-10-30.apk
new file mode 100644 (file)
index 0000000..6ebbf4e
Binary files /dev/null and b/apks/owncloud-beta-2015-10-30.apk differ
diff --git a/apks/owncloud-beta-2015-10-31-10-00-00.apk b/apks/owncloud-beta-2015-10-31-10-00-00.apk
new file mode 100644 (file)
index 0000000..ab15cda
Binary files /dev/null and b/apks/owncloud-beta-2015-10-31-10-00-00.apk differ
diff --git a/apks/owncloud-beta-2015-10-31.apk b/apks/owncloud-beta-2015-10-31.apk
new file mode 100644 (file)
index 0000000..f8e7bab
Binary files /dev/null and b/apks/owncloud-beta-2015-10-31.apk differ
diff --git a/apks/owncloud-beta-2015-11-01.apk b/apks/owncloud-beta-2015-11-01.apk
new file mode 100644 (file)
index 0000000..567891a
Binary files /dev/null and b/apks/owncloud-beta-2015-11-01.apk differ
diff --git a/apks/owncloud-beta-2015-11-02.apk b/apks/owncloud-beta-2015-11-02.apk
new file mode 100644 (file)
index 0000000..924f626
Binary files /dev/null and b/apks/owncloud-beta-2015-11-02.apk differ
diff --git a/apks/owncloud-beta-20151105.apk b/apks/owncloud-beta-20151105.apk
new file mode 100644 (file)
index 0000000..aa2cf9d
Binary files /dev/null and b/apks/owncloud-beta-20151105.apk differ
diff --git a/apks/owncloud-beta-20151109.apk b/apks/owncloud-beta-20151109.apk
new file mode 100644 (file)
index 0000000..e770472
Binary files /dev/null and b/apks/owncloud-beta-20151109.apk differ
diff --git a/apks/owncloud-beta-20151113.apk b/apks/owncloud-beta-20151113.apk
new file mode 100644 (file)
index 0000000..6f1f3b8
Binary files /dev/null and b/apks/owncloud-beta-20151113.apk differ
diff --git a/apks/owncloud-beta-20151118.apk b/apks/owncloud-beta-20151118.apk
new file mode 100644 (file)
index 0000000..9641cf6
Binary files /dev/null and b/apks/owncloud-beta-20151118.apk differ
diff --git a/apks/owncloud-beta-20151120.apk b/apks/owncloud-beta-20151120.apk
new file mode 100644 (file)
index 0000000..056d0ec
Binary files /dev/null and b/apks/owncloud-beta-20151120.apk differ
diff --git a/apks/owncloud-beta-20151121.apk b/apks/owncloud-beta-20151121.apk
new file mode 100644 (file)
index 0000000..31fc126
Binary files /dev/null and b/apks/owncloud-beta-20151121.apk differ
diff --git a/apks/owncloud-beta-20151124.apk b/apks/owncloud-beta-20151124.apk
new file mode 100644 (file)
index 0000000..26535e0
Binary files /dev/null and b/apks/owncloud-beta-20151124.apk differ
diff --git a/apks/owncloud-beta-20151125.apk b/apks/owncloud-beta-20151125.apk
new file mode 100644 (file)
index 0000000..5eb3ff1
Binary files /dev/null and b/apks/owncloud-beta-20151125.apk differ
index d96997a..23816a1 100644 (file)
@@ -3,13 +3,12 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
+        classpath 'com.android.tools.build:gradle:1.3.0'
     }
 }
 
 apply plugin: 'com.android.application'
 
-
 repositories {
     mavenCentral()
 
@@ -24,11 +23,19 @@ dependencies {
     compile 'com.android.support:support-v4:22.2.1'
     compile 'com.jakewharton:disklrucache:2.0.2'
     compile 'com.android.support:appcompat-v7:22.2.1'
+    compile 'com.getbase:floatingactionbutton:1.10.1'
 }
 
 android {
     compileSdkVersion 22
     buildToolsVersion "22.0.1"
+
+    defaultConfig {
+        applicationId "com.owncloud.android.beta"
+        versionCode 20151125
+        versionName "ownCloud beta"
+    }
+
     sourceSets {
         main {
             manifest.srcFile 'AndroidManifest.xml'
@@ -65,10 +72,20 @@ android {
     packagingOptions {
         exclude 'META-INF/LICENSE.txt'
     }
-}
-
-
-
 
+    signingConfigs {
+        release {
+            storeFile file(RELEASE_STORE_FILE)
+            storePassword RELEASE_STORE_PASSWORD
+            keyAlias RELEASE_KEY_ALIAS
+            keyPassword RELEASE_KEY_PASSWORD
+        }
+    }
 
+     buildTypes {
+        release {
+            signingConfig signingConfigs.release
+        }
+    }
 
+}
\ No newline at end of file
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/.classpath b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/.classpath
new file mode 100644 (file)
index 0000000..7bc01d9
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="gen"/>
+       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+       <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/AndroidManifest.xml b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..f29e987
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+    package="com.getbase.floatingactionbutton"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="15"
+    android:versionName="1.10.1" >
+
+    <uses-sdk
+        android:minSdkVersion="14"
+        android:targetSdkVersion="22" />
+
+    <application />
+
+</manifest>
\ No newline at end of file
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/R.txt b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/R.txt
new file mode 100644 (file)
index 0000000..c6d5664
--- /dev/null
@@ -0,0 +1,55 @@
+int attr fab_addButtonColorNormal 0x7f010009
+int attr fab_addButtonColorPressed 0x7f010008
+int attr fab_addButtonPlusIconColor 0x7f01000b
+int attr fab_addButtonSize 0x7f01000a
+int attr fab_addButtonStrokeVisible 0x7f01000c
+int attr fab_colorDisabled 0x7f010002
+int attr fab_colorNormal 0x7f010003
+int attr fab_colorPressed 0x7f010001
+int attr fab_expandDirection 0x7f01000f
+int attr fab_icon 0x7f010004
+int attr fab_labelStyle 0x7f01000d
+int attr fab_labelsPosition 0x7f01000e
+int attr fab_plusIconColor 0x7f010000
+int attr fab_size 0x7f010005
+int attr fab_stroke_visible 0x7f010007
+int attr fab_title 0x7f010006
+int dimen fab_actions_spacing 0x7f030000
+int dimen fab_icon_size 0x7f030001
+int dimen fab_labels_margin 0x7f030002
+int dimen fab_plus_icon_size 0x7f030003
+int dimen fab_plus_icon_stroke 0x7f030004
+int dimen fab_shadow_offset 0x7f030005
+int dimen fab_shadow_radius 0x7f030006
+int dimen fab_size_mini 0x7f030007
+int dimen fab_size_normal 0x7f030008
+int dimen fab_stroke_width 0x7f030009
+int drawable fab_bg_mini 0x7f020000
+int drawable fab_bg_normal 0x7f020001
+int id down 0x7f040006
+int id fab_expand_menu_button 0x7f040000
+int id fab_label 0x7f040001
+int id left 0x7f040004
+int id mini 0x7f040002
+int id normal 0x7f040003
+int id right 0x7f040005
+int id up 0x7f040007
+int[] styleable AddFloatingActionButton { 0x7f010000 }
+int styleable AddFloatingActionButton_fab_plusIconColor 0
+int[] styleable FloatingActionButton { 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004, 0x7f010005, 0x7f010006, 0x7f010007 }
+int styleable FloatingActionButton_fab_colorDisabled 1
+int styleable FloatingActionButton_fab_colorNormal 2
+int styleable FloatingActionButton_fab_colorPressed 0
+int styleable FloatingActionButton_fab_icon 3
+int styleable FloatingActionButton_fab_size 4
+int styleable FloatingActionButton_fab_stroke_visible 6
+int styleable FloatingActionButton_fab_title 5
+int[] styleable FloatingActionsMenu { 0x7f010008, 0x7f010009, 0x7f01000a, 0x7f01000b, 0x7f01000c, 0x7f01000d, 0x7f01000e, 0x7f01000f }
+int styleable FloatingActionsMenu_fab_addButtonColorNormal 1
+int styleable FloatingActionsMenu_fab_addButtonColorPressed 0
+int styleable FloatingActionsMenu_fab_addButtonPlusIconColor 3
+int styleable FloatingActionsMenu_fab_addButtonSize 2
+int styleable FloatingActionsMenu_fab_addButtonStrokeVisible 4
+int styleable FloatingActionsMenu_fab_expandDirection 7
+int styleable FloatingActionsMenu_fab_labelStyle 5
+int styleable FloatingActionsMenu_fab_labelsPosition 6
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/aapt/AndroidManifest.xml b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/aapt/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..f29e987
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest
+    package="com.getbase.floatingactionbutton"
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="15"
+    android:versionName="1.10.1" >
+
+    <uses-sdk
+        android:minSdkVersion="14"
+        android:targetSdkVersion="22" />
+
+    <application />
+
+</manifest>
\ No newline at end of file
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/annotations.zip b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/annotations.zip
new file mode 100644 (file)
index 0000000..a46d2ce
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/annotations.zip differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/build.xml b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/build.xml
new file mode 100644 (file)
index 0000000..4317fb0
--- /dev/null
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="com-getbase-floatingactionbutton-1-10-0-exploded-aar" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/jars/classes.jar b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/jars/classes.jar
new file mode 100644 (file)
index 0000000..723d01e
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/jars/classes.jar differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/libs/classes.jar b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/libs/classes.jar
new file mode 100644 (file)
index 0000000..723d01e
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/libs/classes.jar differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/proguard.txt b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/proguard.txt
new file mode 100644 (file)
index 0000000..b542959
--- /dev/null
@@ -0,0 +1,5 @@
+# keep getters/setters in RotatingDrawable so that animations can still work.
+-keepclassmembers class com.getbase.floatingactionbutton.FloatingActionsMenu$RotatingDrawable {
+   void set*(***);
+   *** get*();
+}
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/project.properties b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/project.properties
new file mode 100644 (file)
index 0000000..362a0a3
--- /dev/null
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-22
+android.library=true
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_mini.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_mini.png
new file mode 100644 (file)
index 0000000..4b48351
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_mini.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_normal.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_normal.png
new file mode 100644 (file)
index 0000000..4daec66
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-hdpi-v4/fab_bg_normal.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_mini.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_mini.png
new file mode 100644 (file)
index 0000000..218cf04
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_mini.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_normal.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_normal.png
new file mode 100644 (file)
index 0000000..c157df3
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-mdpi-v4/fab_bg_normal.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_mini.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_mini.png
new file mode 100644 (file)
index 0000000..d56bfe8
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_mini.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_normal.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_normal.png
new file mode 100644 (file)
index 0000000..41614b9
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xhdpi-v4/fab_bg_normal.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_mini.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_mini.png
new file mode 100644 (file)
index 0000000..1cdd2b1
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_mini.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_normal.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_normal.png
new file mode 100644 (file)
index 0000000..14608ff
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxhdpi-v4/fab_bg_normal.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_mini.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_mini.png
new file mode 100644 (file)
index 0000000..6fea674
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_mini.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_normal.png b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_normal.png
new file mode 100644 (file)
index 0000000..0e78ff6
Binary files /dev/null and b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/drawable-xxxhdpi-v4/fab_bg_normal.png differ
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/values/values.xml b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/res/values/values.xml
new file mode 100644 (file)
index 0000000..8139c61
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="AddFloatingActionButton"><attr format="color" name="fab_plusIconColor"/></declare-styleable>
+    <declare-styleable name="FloatingActionButton"><attr format="color" name="fab_colorPressed"/><attr format="color" name="fab_colorDisabled"/><attr format="color" name="fab_colorNormal"/><attr format="reference" name="fab_icon"/><attr format="enum" name="fab_size"><enum name="normal" value="0"/><enum name="mini" value="1"/></attr><attr format="string" name="fab_title"/><attr format="boolean" name="fab_stroke_visible"/></declare-styleable>
+    <declare-styleable name="FloatingActionsMenu"><attr format="color" name="fab_addButtonColorPressed"/><attr format="color" name="fab_addButtonColorNormal"/><attr format="enum" name="fab_addButtonSize"><enum name="normal" value="0"/><enum name="mini" value="1"/></attr><attr format="color" name="fab_addButtonPlusIconColor"/><attr format="boolean" name="fab_addButtonStrokeVisible"/><attr format="reference" name="fab_labelStyle"/><attr format="enum" name="fab_labelsPosition"><enum name="left" value="0"/><enum name="right" value="1"/></attr><attr format="enum" name="fab_expandDirection"><enum name="up" value="0"/><enum name="down" value="1"/><enum name="left" value="2"/><enum name="right" value="3"/></attr></declare-styleable>
+    <!-- From: file:/Users/chalup/src/android-floating-action-button/library/src/main/res/values/dimens.xml -->
+    <eat-comment/>
+    <dimen name="fab_actions_spacing">16dp</dimen>
+    <dimen name="fab_icon_size">24dp</dimen>
+    <dimen name="fab_labels_margin">8dp</dimen>
+    <dimen name="fab_plus_icon_size">14dp</dimen>
+    <dimen name="fab_plus_icon_stroke">2dp</dimen>
+    <dimen name="fab_shadow_offset">3dp</dimen>
+    <dimen name="fab_shadow_radius">9dp</dimen>
+    <dimen name="fab_size_mini">40dp</dimen>
+    <dimen name="fab_size_normal">56dp</dimen>
+    <dimen name="fab_stroke_width">1dp</dimen>
+    <!-- From: file:/Users/chalup/src/android-floating-action-button/library/src/main/res/values/ids.xml -->
+    <eat-comment/>
+    <item name="fab_expand_menu_button" type="id"/>
+    <item name="fab_label" type="id"/>
+</resources>
\ No newline at end of file
diff --git a/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/src/.readme b/libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar/src/.readme
new file mode 100644 (file)
index 0000000..4bcebad
--- /dev/null
@@ -0,0 +1,2 @@
+This hidden file is there to ensure there is an src folder.
+Once we support binary library this will go away.
\ No newline at end of file
index 2fcc9f6..4a48a29 100644 (file)
@@ -3,7 +3,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
+        classpath 'com.android.tools.build:gradle:1.3.0'
     }
 }
 apply plugin: 'com.android.library'
index b09969d..8966dbc 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b09969d078b3a790b01c8d61a7298a37439a9f24
+Subproject commit 8966dbcee044cec726633fdfd208ea106cf176c0
index b7cabdd..3b4370c 100644 (file)
@@ -11,3 +11,4 @@
 target=android-22
 android.library.reference.1=owncloud-android-library
 android.library.reference.2=libs/android-support-appcompat-v7-exploded-aar
+android.library.reference.3=libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar
diff --git a/res/drawable-hdpi-v9/ic_action_download.png b/res/drawable-hdpi-v9/ic_action_download.png
deleted file mode 100644 (file)
index 25476cd..0000000
Binary files a/res/drawable-hdpi-v9/ic_action_download.png and /dev/null differ
diff --git a/res/drawable-hdpi-v9/ic_action_refresh.png b/res/drawable-hdpi-v9/ic_action_refresh.png
deleted file mode 100644 (file)
index a7fdc0d..0000000
Binary files a/res/drawable-hdpi-v9/ic_action_refresh.png and /dev/null differ
diff --git a/res/drawable-hdpi-v9/ic_action_settings.png b/res/drawable-hdpi-v9/ic_action_settings.png
deleted file mode 100644 (file)
index 86b54f4..0000000
Binary files a/res/drawable-hdpi-v9/ic_action_settings.png and /dev/null differ
diff --git a/res/drawable-hdpi/ic_action_download_grey.png b/res/drawable-hdpi/ic_action_download_grey.png
new file mode 100644 (file)
index 0000000..4ac1e26
Binary files /dev/null and b/res/drawable-hdpi/ic_action_download_grey.png differ
index 198568d..164dcb5 100644 (file)
Binary files a/res/drawable-hdpi/ic_checkbox_blank_outline.png and b/res/drawable-hdpi/ic_checkbox_blank_outline.png differ
index 92d4109..330d7b9 100644 (file)
Binary files a/res/drawable-hdpi/ic_checkbox_marked.png and b/res/drawable-hdpi/ic_checkbox_marked.png differ
diff --git a/res/drawable-hdpi/ic_import.png b/res/drawable-hdpi/ic_import.png
new file mode 100644 (file)
index 0000000..ad72837
Binary files /dev/null and b/res/drawable-hdpi/ic_import.png differ
diff --git a/res/drawable-hdpi/ic_play_arrow.png b/res/drawable-hdpi/ic_play_arrow.png
new file mode 100644 (file)
index 0000000..57c9fa5
Binary files /dev/null and b/res/drawable-hdpi/ic_play_arrow.png differ
diff --git a/res/drawable-hdpi/ic_view_list.png b/res/drawable-hdpi/ic_view_list.png
new file mode 100644 (file)
index 0000000..64ad8e1
Binary files /dev/null and b/res/drawable-hdpi/ic_view_list.png differ
diff --git a/res/drawable-hdpi/ic_view_module.png b/res/drawable-hdpi/ic_view_module.png
new file mode 100644 (file)
index 0000000..7982e38
Binary files /dev/null and b/res/drawable-hdpi/ic_view_module.png differ
index 6fe153b..2430c94 100644 (file)
Binary files a/res/drawable-hdpi/icon.png and b/res/drawable-hdpi/icon.png differ
diff --git a/res/drawable-hdpi/view_play.png b/res/drawable-hdpi/view_play.png
new file mode 100644 (file)
index 0000000..5371724
Binary files /dev/null and b/res/drawable-hdpi/view_play.png differ
diff --git a/res/drawable-mdpi-v9/ic_action_download.png b/res/drawable-mdpi-v9/ic_action_download.png
deleted file mode 100644 (file)
index 2684c83..0000000
Binary files a/res/drawable-mdpi-v9/ic_action_download.png and /dev/null differ
diff --git a/res/drawable-mdpi-v9/ic_action_refresh.png b/res/drawable-mdpi-v9/ic_action_refresh.png
deleted file mode 100644 (file)
index bb9d855..0000000
Binary files a/res/drawable-mdpi-v9/ic_action_refresh.png and /dev/null differ
diff --git a/res/drawable-mdpi-v9/ic_action_settings.png b/res/drawable-mdpi-v9/ic_action_settings.png
deleted file mode 100644 (file)
index 47ef3f4..0000000
Binary files a/res/drawable-mdpi-v9/ic_action_settings.png and /dev/null differ
diff --git a/res/drawable-mdpi/ic_action_download_grey.png b/res/drawable-mdpi/ic_action_download_grey.png
new file mode 100644 (file)
index 0000000..29103c5
Binary files /dev/null and b/res/drawable-mdpi/ic_action_download_grey.png differ
diff --git a/res/drawable-mdpi/ic_checkbox_blank_outline.png b/res/drawable-mdpi/ic_checkbox_blank_outline.png
new file mode 100644 (file)
index 0000000..d4ca47c
Binary files /dev/null and b/res/drawable-mdpi/ic_checkbox_blank_outline.png differ
diff --git a/res/drawable-mdpi/ic_checkbox_marked.png b/res/drawable-mdpi/ic_checkbox_marked.png
new file mode 100644 (file)
index 0000000..99df274
Binary files /dev/null and b/res/drawable-mdpi/ic_checkbox_marked.png differ
diff --git a/res/drawable-mdpi/ic_import.png b/res/drawable-mdpi/ic_import.png
new file mode 100644 (file)
index 0000000..3bc69d1
Binary files /dev/null and b/res/drawable-mdpi/ic_import.png differ
diff --git a/res/drawable-mdpi/ic_play_arrow.png b/res/drawable-mdpi/ic_play_arrow.png
new file mode 100644 (file)
index 0000000..c61e948
Binary files /dev/null and b/res/drawable-mdpi/ic_play_arrow.png differ
diff --git a/res/drawable-mdpi/ic_view_list.png b/res/drawable-mdpi/ic_view_list.png
new file mode 100644 (file)
index 0000000..4aca55c
Binary files /dev/null and b/res/drawable-mdpi/ic_view_list.png differ
diff --git a/res/drawable-mdpi/ic_view_module.png b/res/drawable-mdpi/ic_view_module.png
new file mode 100644 (file)
index 0000000..f308a32
Binary files /dev/null and b/res/drawable-mdpi/ic_view_module.png differ
index 9008b9d..2d7ab66 100644 (file)
Binary files a/res/drawable-mdpi/icon.png and b/res/drawable-mdpi/icon.png differ
diff --git a/res/drawable-mdpi/view_play.png b/res/drawable-mdpi/view_play.png
new file mode 100644 (file)
index 0000000..77b2027
Binary files /dev/null and b/res/drawable-mdpi/view_play.png differ
diff --git a/res/drawable-xhdpi/ic_action_download_grey.png b/res/drawable-xhdpi/ic_action_download_grey.png
new file mode 100644 (file)
index 0000000..29103c5
Binary files /dev/null and b/res/drawable-xhdpi/ic_action_download_grey.png differ
diff --git a/res/drawable-xhdpi/ic_action_settings.png b/res/drawable-xhdpi/ic_action_settings.png
new file mode 100644 (file)
index 0000000..a19fc5c
Binary files /dev/null and b/res/drawable-xhdpi/ic_action_settings.png differ
diff --git a/res/drawable-xhdpi/ic_import.png b/res/drawable-xhdpi/ic_import.png
new file mode 100644 (file)
index 0000000..bf2f72e
Binary files /dev/null and b/res/drawable-xhdpi/ic_import.png differ
diff --git a/res/drawable-xhdpi/ic_play_arrow.png b/res/drawable-xhdpi/ic_play_arrow.png
new file mode 100644 (file)
index 0000000..a3c80e7
Binary files /dev/null and b/res/drawable-xhdpi/ic_play_arrow.png differ
diff --git a/res/drawable-xhdpi/ic_view_list.png b/res/drawable-xhdpi/ic_view_list.png
new file mode 100644 (file)
index 0000000..b81d910
Binary files /dev/null and b/res/drawable-xhdpi/ic_view_list.png differ
diff --git a/res/drawable-xhdpi/ic_view_module.png b/res/drawable-xhdpi/ic_view_module.png
new file mode 100644 (file)
index 0000000..b354853
Binary files /dev/null and b/res/drawable-xhdpi/ic_view_module.png differ
index 041efc6..a135cc2 100644 (file)
Binary files a/res/drawable-xhdpi/icon.png and b/res/drawable-xhdpi/icon.png differ
diff --git a/res/drawable-xhdpi/view_play.png b/res/drawable-xhdpi/view_play.png
new file mode 100644 (file)
index 0000000..8482788
Binary files /dev/null and b/res/drawable-xhdpi/view_play.png differ
diff --git a/res/drawable-xxhdpi/ic_action_download_grey.png b/res/drawable-xxhdpi/ic_action_download_grey.png
new file mode 100644 (file)
index 0000000..c4d0b0c
Binary files /dev/null and b/res/drawable-xxhdpi/ic_action_download_grey.png differ
diff --git a/res/drawable-xxhdpi/ic_action_settings.png b/res/drawable-xxhdpi/ic_action_settings.png
new file mode 100644 (file)
index 0000000..6a70402
Binary files /dev/null and b/res/drawable-xxhdpi/ic_action_settings.png differ
diff --git a/res/drawable-xxhdpi/ic_import.png b/res/drawable-xxhdpi/ic_import.png
new file mode 100644 (file)
index 0000000..a4412aa
Binary files /dev/null and b/res/drawable-xxhdpi/ic_import.png differ
diff --git a/res/drawable-xxhdpi/ic_play_arrow.png b/res/drawable-xxhdpi/ic_play_arrow.png
new file mode 100644 (file)
index 0000000..547ef30
Binary files /dev/null and b/res/drawable-xxhdpi/ic_play_arrow.png differ
diff --git a/res/drawable-xxhdpi/ic_settings.png b/res/drawable-xxhdpi/ic_settings.png
deleted file mode 100644 (file)
index 6a70402..0000000
Binary files a/res/drawable-xxhdpi/ic_settings.png and /dev/null differ
diff --git a/res/drawable-xxhdpi/ic_sort_variant.png b/res/drawable-xxhdpi/ic_sort_variant.png
new file mode 100644 (file)
index 0000000..2918126
Binary files /dev/null and b/res/drawable-xxhdpi/ic_sort_variant.png differ
diff --git a/res/drawable-xxhdpi/icon.png b/res/drawable-xxhdpi/icon.png
new file mode 100644 (file)
index 0000000..ad0fd25
Binary files /dev/null and b/res/drawable-xxhdpi/icon.png differ
diff --git a/res/drawable-xxhdpi/view_play.png b/res/drawable-xxhdpi/view_play.png
new file mode 100644 (file)
index 0000000..fea738b
Binary files /dev/null and b/res/drawable-xxhdpi/view_play.png differ
diff --git a/res/drawable-xxxhdpi/icon.png b/res/drawable-xxxhdpi/icon.png
new file mode 100644 (file)
index 0000000..c0ec25c
Binary files /dev/null and b/res/drawable-xxxhdpi/icon.png differ
diff --git a/res/drawable-xxxhdpi/view_play.png b/res/drawable-xxxhdpi/view_play.png
new file mode 100644 (file)
index 0000000..3786b4d
Binary files /dev/null and b/res/drawable-xxxhdpi/view_play.png differ
diff --git a/res/drawable/fab_label_background.xml b/res/drawable/fab_label_background.xml
new file mode 100644 (file)
index 0000000..4460dab
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/black_semi_transparent"/>
+    <padding
+        android:left="@dimen/standard_padding"
+        android:top="4dp"
+        android:right="@dimen/standard_padding"
+        android:bottom="4dp"/>
+    <corners
+        android:radius="2dp"/>
+</shape>
\ No newline at end of file
diff --git a/res/layout/error_send.xml b/res/layout/error_send.xml
new file mode 100644 (file)
index 0000000..7a80166
--- /dev/null
@@ -0,0 +1,77 @@
+<?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"
+    android:orientation="vertical"
+    android:weightSum="1" >
+
+    <ScrollView
+        android:id="@+id/scrollView1"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_weight="1">
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingLeft="@dimen/standard_padding"
+            android:paddingRight="@dimen/standard_padding">
+
+            <TextView
+                android:id="@+id/logTV"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:text="@string/empty"
+                android:typeface="monospace"/>
+        </LinearLayout>
+    </ScrollView>
+
+    <LinearLayout
+        android:id="@+id/historyButtonBar"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_marginLeft="@dimen/standard_margin"
+        android:layout_marginRight="@dimen/standard_margin">
+
+    <Button
+        android:id="@+id/cancelErrorLogButton"
+        android:theme="@style/Button"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:layout_weight="1"
+        android:text="@string/error_log_exit" />
+
+    <android.support.v7.widget.AppCompatButton
+        android:id="@+id/sendErrorLogButton"
+        android:theme="@style/Button.Primary"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:layout_weight="1"
+        android:text="@string/error_log_send" />
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
index 15a9baf..9f93a3e 100644 (file)
             android:layout_marginBottom="4dp"\r
             android:layout_marginRight="4dp"\r
             android:src="@drawable/ic_favorite" />\r
+\r
+        <ImageView\r
+            android:id="@+id/custom_checkbox"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_gravity="center_vertical|bottom"\r
+            android:layout_marginLeft="4dp"\r
+            android:layout_marginRight="4dp"\r
+            android:gravity=""\r
+            android:src="@android:drawable/checkbox_off_background" />\r
     </FrameLayout>\r
 \r
 </LinearLayout>
\ No newline at end of file
index 6bec560..0f27f90 100644 (file)
             android:layout_marginRight="2dp"\r
             android:src="@drawable/ic_favorite" />\r
 \r
-\r
+        <ImageView\r
+            android:id="@+id/custom_checkbox"\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:layout_gravity="center_vertical|bottom"\r
+            android:layout_marginLeft="4dp"\r
+            android:layout_marginRight="4dp"\r
+            android:gravity=""\r
+            android:src="@android:drawable/checkbox_off_background"\r
+            android:elevation="30dp" />\r
 \r
     </FrameLayout>\r
 \r
index a5a0e26..964b845 100644 (file)
@@ -14,7 +14,7 @@
         android:padding="@dimen/standard_padding"
         android:layout_gravity="center"
         android:gravity="center"
-        android:textColor="@color/setup_text_hint"
+        android:textColor="@color/secondaryTextColor"
         />
 
 </LinearLayout> 
\ No newline at end of file
index 7160b32..bd8b12d 100644 (file)
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:fab="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
+    xmlns:fab="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_weight="1" >
+    android:layout_height="match_parent">
 
     <android.support.v4.widget.SwipeRefreshLayout
         android:id="@+id/swipe_containing_list"
         android:layout_width="match_parent"
-        android:layout_height="match_parent" 
-        android:layout_weight="1"
+        android:layout_height="match_parent"
         android:footerDividersEnabled="false"
         android:visibility="visible" >
         
             </ScrollView>
     </android.support.v4.widget.SwipeRefreshLayout>
 
-</FrameLayout>
\ No newline at end of file
+</FrameLayout>
+    <com.getbase.floatingactionbutton.FloatingActionsMenu
+        android:id="@+id/fab_main"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentEnd="true"
+        fab:fab_addButtonColorNormal="@color/owncloud_blue_accent"
+        fab:fab_addButtonColorPressed="@color/owncloud_blue"
+        fab:fab_addButtonPlusIconColor="@color/white"
+        fab:fab_labelStyle="@style/menu_labels_style"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_marginRight="@dimen/standard_margin"
+        android:layout_marginEnd="@dimen/standard_margin"
+        android:visibility="gone">
+
+        <com.getbase.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_upload"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            fab:fab_size="mini"
+            fab:fab_icon="@drawable/ic_action_upload"
+            fab:fab_colorNormal="@color/owncloud_blue_accent"
+            fab:fab_colorPressed="@color/owncloud_blue"
+            fab:fab_title=""/>
+
+        <com.getbase.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_mkdir"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            fab:fab_size="mini"
+            fab:fab_icon="@drawable/ic_action_create_dir"
+            fab:fab_colorNormal="@color/owncloud_blue_accent"
+            fab:fab_colorPressed="@color/owncloud_blue"
+            fab:fab_title=""/>
+
+        <com.getbase.floatingactionbutton.FloatingActionButton
+            android:id="@+id/fab_upload_from_app"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            fab:fab_size="mini"
+            fab:fab_icon="@drawable/ic_import"
+            fab:fab_colorNormal="@color/owncloud_blue_accent"
+            fab:fab_colorPressed="@color/owncloud_blue"
+            fab:fab_title=""/>
+
+    </com.getbase.floatingactionbutton.FloatingActionsMenu>
+</RelativeLayout>
diff --git a/res/layout/migration_layout.xml b/res/layout/migration_layout.xml
new file mode 100644 (file)
index 0000000..84b5c22
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:gravity="center_vertical">
+
+    <ProgressBar
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:id="@+id/migrationProgress"
+        android:layout_gravity="center_horizontal"
+        android:progress="50"
+        android:paddingLeft="30dp"
+        android:paddingRight="30dp"/>
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textAppearance="?android:attr/textAppearanceMedium"
+        android:text=""
+        android:id="@+id/migrationText"
+        android:layout_gravity="center_horizontal"/>
+
+    <Button
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/drawer_close"
+        android:id="@+id/finishButton"
+        android:layout_gravity="center_horizontal"/>
+</LinearLayout>
\ No newline at end of file
index feaddb3..27a6133 100644 (file)
   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"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context="com.owncloud.android.ui.fragment.ShareFileFragment">
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            xmlns:tools="http://schemas.android.com/tools"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            tools:context="com.owncloud.android.ui.fragment.ShareFileFragment"
+            android:id="@+id/shareScroll">
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:background="@color/background_material_light"
-        android:orientation="vertical">
+        android:orientation="vertical"
+        >
 
         <RelativeLayout
             android:id="@+id/shareHeaderContainer"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="@string/placeholder_filename"
-                android:textSize="16dip"
+                android:textSize="16sp"
                 android:layout_gravity="center_vertical"
                 android:layout_marginLeft="4dp"
+                android:layout_marginStart="4dp"
                 android:layout_marginRight="8dp"
+                android:layout_marginEnd="8dp"
                 android:layout_toRightOf="@+id/shareFileIcon"
                 android:layout_toEndOf="@+id/shareFileIcon"
                 android:singleLine="true"
@@ -64,7 +68,7 @@
             <TextView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:textSize="12dip"
+                android:textSize="12sp"
                 android:text="@string/placeholder_filesize"
                 android:id="@+id/shareFileSize"
                 android:layout_below="@+id/shareFileName"
@@ -72,6 +76,7 @@
                 android:layout_toEndOf="@+id/shareFileIcon"
                 android:layout_marginTop="4dp"
                 android:layout_marginLeft="4dp"
+                android:layout_marginStart="4dp"
                 android:layout_marginBottom="12dp"
                 android:layout_gravity="center_vertical"/>
 
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:textSize="16dip"
+            android:textSize="16sp"
             android:text="@string/share_with_user_section_title"
             android:id="@+id/shareWithUsersSectionTitle"
-            android:layout_gravity="left"
+            android:layout_gravity="start"
             android:padding="8dp"
             android:background="@color/actionbar_start_color"
             android:textColor="@color/white"/>
             android:layout_height="wrap_content"
             android:id="@+id/shareNoUsers"
             android:text="@string/share_no_users"
-            android:textSize="12dip"
+            android:textSize="12sp"
             android:padding="12dp" />
 
         <android.support.v7.widget.AppCompatButton
             android:text="@string/share_add_user_or_group"
             android:contentDescription="shareAddUserButton"/>
 
+        <Switch
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="16sp"
+            android:text="@string/share_via_link_section_title"
+            android:id="@+id/shareViaLinkSectionSwitch"
+            android:layout_gravity="start"
+            android:padding="8dp"
+            android:background="@color/actionbar_start_color"
+            android:textColor="@color/white"/>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/shareViaLinkExpirationSection"
+            >
+
+            <Switch
+                android:id="@+id/shareViaLinkExpirationSwitch"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
+                android:layout_centerInParent="true"
+                android:padding="8dp"
+                />
+
+            <TextView
+                android:id="@+id/shareViaLinkExpirationLabel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@id/shareViaLinkExpirationSwitch"
+                android:layout_toStartOf="@id/shareViaLinkExpirationSwitch"
+                android:paddingTop="8dp"
+                android:paddingLeft="8dp"
+                android:paddingRight="8dp"
+                android:text="@string/share_via_link_expiration_date_label"
+                android:textSize="16sp"
+                />
+
+            <TextView
+                android:id="@+id/shareViaLinkExpirationValue"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@id/shareViaLinkExpirationSwitch"
+                android:layout_toStartOf="@id/shareViaLinkExpirationSwitch"
+                android:layout_below="@id/shareViaLinkExpirationLabel"
+                android:paddingLeft="8dp"
+                android:paddingRight="8dp"
+                android:paddingBottom="8dp"
+                android:textSize="12sp"
+                />
+
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:id="@+id/shareViaLinkPasswordSection"
+            >
+
+            <Switch
+                android:id="@+id/shareViaLinkPasswordSwitch"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:layout_alignParentEnd="true"
+                android:layout_centerInParent="true"
+                android:padding="8dp"
+            />
+
+            <TextView
+                android:id="@+id/shareViaLinkPasswordLabel"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@id/shareViaLinkPasswordSwitch"
+                android:layout_toStartOf="@id/shareViaLinkPasswordSwitch"
+                android:paddingTop="8dp"
+                android:paddingLeft="8dp"
+                android:paddingRight="8dp"
+                android:text="@string/share_via_link_password_label"
+                android:textSize="16sp"
+                />
+
+            <TextView
+                android:id="@+id/shareViaLinkPasswordValue"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentLeft="true"
+                android:layout_alignParentStart="true"
+                android:layout_toLeftOf="@id/shareViaLinkPasswordSwitch"
+                android:layout_toStartOf="@id/shareViaLinkPasswordSwitch"
+                android:layout_below="@id/shareViaLinkPasswordLabel"
+                android:paddingLeft="8dp"
+                android:paddingRight="8dp"
+                android:paddingBottom="8dp"
+                android:text="@string/share_via_link_password_title"
+                android:textSize="12sp"
+                android:visibility="invisible"
+                />
+
+        </RelativeLayout>
+
+        <android.support.v7.widget.AppCompatButton
+            android:id="@+id/shareViaLinkGetLinkButton"
+            style="@style/ownCloud.Button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:text="@string/share_get_public_link_button"
+            android:contentDescription="shareGetLinkButton"/>
+
     </LinearLayout>
-</FrameLayout>
+
+</ScrollView>
\ No newline at end of file
index 121fd64..fbf9cee 100644 (file)
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:layout_height="wrap_content"\r
+        android:orientation="horizontal">\r
+\r
+        <ImageView\r
+            android:layout_width="match_parent"\r
+            android:layout_height="1dp"\r
+            android:src="@drawable/uploader_list_separator"/>\r
+\r
+    </LinearLayout>\r
+\r
+    <LinearLayout\r
+        android:orientation="horizontal"\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:paddingTop="8dp"\r
+        android:paddingLeft="16dp"\r
+        android:paddingRight="16dp">\r
+\r
+        <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"\r
+            android:id="@+id/drawer_radio_group"\r
+            android:layout_width="fill_parent"\r
+            android:layout_height="wrap_content"\r
+            android:gravity="center"\r
+            android:orientation="horizontal">\r
+\r
+            <RadioButton\r
+                android:layout_width="wrap_content"\r
+                android:layout_height="wrap_content"\r
+                android:text="@string/upload_copy_files"\r
+                android:id="@+id/upload_radio_copy"\r
+                android:paddingRight="8dp"\r
+                android:checked="false" />\r
+\r
+            <RadioButton\r
+                android:layout_width="wrap_content"\r
+                android:layout_height="wrap_content"\r
+                android:text="@string/upload_move_files"\r
+                android:id="@+id/upload_radio_move"\r
+                android:paddingRight="8dp"\r
+                android:checked="false" />\r
+        </RadioGroup>\r
+    </LinearLayout>\r
+\r
+    <LinearLayout\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
         android:gravity="center"\r
-        android:orientation="horizontal" >\r
+        android:orientation="horizontal"\r
+        android:paddingLeft="16dp"\r
+        android:paddingRight="16dp"\r
+        android:paddingBottom="16dp">\r
 \r
         <android.support.v7.widget.AppCompatButton\r
             android:id="@+id/upload_files_btn_cancel"\r
index 1c2b6cc..51122ec 100644 (file)
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
  -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-       android:layout_height="wrap_content" android:orientation="vertical"
-       android:layout_width="wrap_content" android:background="#fefefe"
+       android:layout_height="wrap_content"
+       android:orientation="vertical"
+       android:layout_width="wrap_content"
+       android:background="@color/white"
        android:gravity="center">
 
-       <TextView android:layout_width="fill_parent"
-               android:text="@string/uploader_top_message"
-               android:layout_height="wrap_content"
-               android:id="@+id/drawer_username"
-               android:textColor="@android:color/black"
-               android:gravity="center_horizontal">
-       </TextView>
-
-       <FrameLayout android:layout_height="fill_parent"
+       <FrameLayout
+               android:layout_height="fill_parent"
                android:layout_width="fill_parent"
-               android:id="@+id/frameLayout1"
-               android:layout_below="@+id/drawer_username"
-               android:layout_above="@+id/linearLayout1">
+               android:id="@+id/upload_list"
+               android:layout_above="@+id/upload_actions">
 
-               <ListView android:id="@android:id/list"
+               <ListView
+                       android:id="@android:id/list"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:divider="@color/list_divider_background"
-                       android:dividerHeight="1dip">
+                       android:dividerHeight="1dp">
                </ListView>
 
        </FrameLayout>
 
        <LinearLayout
-           android:id="@+id/linearLayout1"
+           android:id="@+id/upload_actions"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
index b66df44..9f6f5ba 100644 (file)
   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="fill_parent"
-       android:background="#fefefe"
-       android:orientation="horizontal"
-       android:layout_height="72dp"
-    android:padding="@dimen/standard_padding">
-  
-    <ImageView 
-        android:layout_width="@dimen/file_icon_size"
-        android:layout_height="@dimen/file_icon_size"
-        android:layout_gravity="center_vertical|center"
-        android:src="@drawable/ic_menu_archive" 
-        android:id="@+id/thumbnail"
-        android:layout_marginRight="@dimen/standard_padding"/>
-    
-    <TextView 
-        android:text="TextView" 
-        android:layout_width="fill_parent" 
-        android:id="@+id/filename"
-        android:layout_height="wrap_content" 
-        android:textColor="@android:color/black"
-               android:layout_gravity="center_vertical"
-        android:textSize="20dip"/>
-    
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="72dp"
+    android:background="@drawable/list_selector"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:layout_width="60dp"
+        android:layout_height="72dp"
+        android:orientation="horizontal">
+
+        <ImageView
+            android:id="@+id/thumbnail"
+            android:layout_width="@dimen/file_icon_size"
+            android:layout_height="@dimen/file_icon_size"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="12dp"
+            android:src="@drawable/ic_menu_archive" />
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:gravity="top"
+        android:paddingTop="@dimen/standard_padding"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/filename"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginRight="4dp"
+            android:ellipsize="middle"
+            android:singleLine="true"
+            android:text="TextView"
+            android:textColor="@color/textColor"
+            android:textSize="16sp" />
+
+        <TextView
+            android:id="@+id/last_mod"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="4dp"
+            android:text="TextView"
+            android:textColor="@color/list_item_lastmod_and_filesize_text"
+            android:textSize="14sp" />
+
+    </LinearLayout>
+
 </LinearLayout>
index 586ec4a..894dc33 100644 (file)
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
 
     <item
         android:id="@+id/action_share_file"
-        android:title="@string/action_share_file"
+        android:title="@string/action_share"
         android:icon="@android:drawable/ic_menu_share"
         android:orderInCategory="1" />
     <item
-        android:id="@+id/action_unshare_file"
-        android:title="@string/action_unshare_file"
-        android:icon="@android:drawable/ic_menu_share"
-        android:orderInCategory="1" />
-    <item
-        android:id="@+id/action_share_with_users"
-        android:title="@string/action_share_with_users"
+        android:id="@+id/action_stream_file"
+        android:title="@string/action_stream_file"
+        android:icon="@android:drawable/ic_menu_view"
         android:orderInCategory="1" />
-
     <item
         android:id="@+id/action_open_file_with"
         android:title="@string/actionbar_open_with"
         android:icon="@android:drawable/ic_menu_set_as"
         android:orderInCategory="1" />
     <item
+        android:id="@+id/action_set_as_wallpaper"
+        android:title="@string/set_picture_as"
+        android:icon="@android:drawable/ic_menu_set_as"
+        android:orderInCategory="1" />
+    <item
         android:id="@+id/action_see_details"
         android:title="@string/actionbar_see_details"
         android:icon="@android:drawable/ic_menu_info_details"
index 236bfd6..097807a 100644 (file)
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <item
-        android:id="@+id/action_upload"
-        android:icon="@drawable/ic_action_upload"
-        android:orderInCategory="2"
-        app:showAsAction="always"
-        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"
-        app:showAsAction="always"
+        android:orderInCategory="1"
+        app:showAsAction="never"
         android:title="@string/actionbar_mkdir"
         android:contentDescription="@string/actionbar_mkdir"/>
     <item
+        android:id="@+id/action_switch_view"
+        android:icon="@drawable/ic_view_module"
+        android:orderInCategory="2"
+        app:showAsAction="never"
+        android:title="@string/action_switch_grid_view" />
+    <item
         android:id="@+id/action_sync_account"
         android:icon="@drawable/ic_action_refresh"
-        android:orderInCategory="2"
+        android:orderInCategory="1"
         app:showAsAction="never"
         android:title="@string/actionbar_sync"
         android:contentDescription="@string/actionbar_sync"/>
        <item
         android:id="@+id/action_sort"
-        android:icon="@android:drawable/ic_menu_sort_by_size"
-        android:orderInCategory="2"
+        android:icon="@drawable/ic_sort_variant"
+        android:orderInCategory="1"
         app:showAsAction="never"
         android:title="@string/actionbar_sort"
         android:contentDescription="@string/actionbar_sort"/>
diff --git a/res/menu/multiple_file_actions_menu.xml b/res/menu/multiple_file_actions_menu.xml
new file mode 100644 (file)
index 0000000..fce1654
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ownCloud Android client application
+
+  Copyright (C) 2012  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,
+  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/>.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/action_download_file"
+        android:title="@string/filedetails_download"
+        android:icon="@drawable/ic_action_download"
+        android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_move"
+        android:title="@string/actionbar_move"
+        android:icon="@android:drawable/ic_menu_set_as"
+        android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_copy"
+        android:title="@android:string/copy"
+        android:icon="@android:drawable/ic_menu_set_as"
+        android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_remove_file"
+        android:title="@string/common_remove"
+        android:icon="@android:drawable/ic_menu_delete"
+        android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_favorite_file"
+        android:title="@string/favorite"
+        android:icon="@android:drawable/ic_menu_set_as"
+        android:orderInCategory="1" />
+    <item
+        android:id="@+id/action_unfavorite_file"
+        android:title="@string/unfavorite"
+        android:icon="@android:drawable/ic_menu_set_as"
+        android:orderInCategory="1" />
+</menu>
diff --git a/res/menu/uploader_menu.xml b/res/menu/uploader_menu.xml
new file mode 100644 (file)
index 0000000..a721c7b
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application
+
+  Copyright (C) 2012  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,
+  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/>.
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/action_sort"
+        android:icon="@android:drawable/ic_menu_sort_by_size"
+        android:orderInCategory="2"
+        app:showAsAction="always"
+        android:title="@string/actionbar_sort"
+        android:contentDescription="@string/actionbar_sort"/>
+</menu>
\ No newline at end of file
index 7706aa7..96f97b8 100644 (file)
@@ -11,6 +11,7 @@
   <string name="auth_username">Gebruikersnaam</string>
   <string name="auth_password">Wagwoord</string>
   <string name="file_list_seconds_ago">sekondes gelede</string>
+  <string name="action_share">Deel</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nee</string>
   <string name="common_ok">OK</string>
@@ -19,4 +20,6 @@
   <string name="activity_chooser_send_file_title">Stuur</string>
   <string name="empty"></string>
   <string name="folder_picker_choose_button_text">Kies</string>
+  <string name="share_via_link_expiration_date_label">Stel verval datum</string>
+  <string name="share_via_link_password_label">Beskerm met Wagwoord</string>
 </resources>
index d4c9e6f..c55da81 100644 (file)
@@ -78,8 +78,7 @@
   <string name="filedetails_modified">عُدل في :</string>
   <string name="filedetails_download">تحميل</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="action_share">شارك</string>
   <string name="common_yes">نعم</string>
   <string name="common_no">لا</string>
   <string name="common_ok">تم</string>
   <string name="favorite">المفضلة</string>
   <string name="common_rename">إعادة التسمية</string>
   <string name="common_remove">حذف</string>
-  <string name="confirmation_remove_alert">هل تريد حقاً حذف %1$s ؟</string>
+  <string name="confirmation_remove_file_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="prefs_category_security">الأمان</string>
   <string name="auth_host_address">عنوان الخادم</string>
   <string name="share_dialog_title">مشاركة</string>
+  <string name="share_via_link_section_title">شارك الرابط</string>
+  <string name="share_via_link_expiration_date_label">تعيين تاريخ إنتهاء الصلاحية</string>
+  <string name="share_via_link_password_label">حماية كلمة السر</string>
   <string name="share_search">البحث</string>
 </resources>
index daa55fa..207fa46 100644 (file)
@@ -73,8 +73,7 @@
   <string name="filedetails_modified">Dəyişdirildi:</string>
   <string name="filedetails_download">Yüklə</string>
   <string name="filedetails_renamed_in_upload_msg">Yüklənmə müddətində fayl buna %1$s yeniləndi</string>
-  <string name="action_share_file">Linki yayımla</string>
-  <string name="action_unshare_file">Link yayımlanmasını dayandır</string>
+  <string name="action_share">Paylaş</string>
   <string name="common_yes">Bəli</string>
   <string name="common_no">Xeyir</string>
   <string name="common_ok">Oldu</string>
@@ -181,7 +180,7 @@ Aşağıda göstərilən %5$s-də olan daxili və xarici fayl(lar) link edilmiş
   <string name="favorite">İstəkli</string>
   <string name="common_rename">Adı dəyiş</string>
   <string name="common_remove">Sil</string>
-  <string name="confirmation_remove_alert">Siz həqiqətən %1$s silmək istəyirsiniz?</string>
+  <string name="confirmation_remove_file_alert">Siz həqiqətən %1$s silmək istəyirsiniz?</string>
   <string name="confirmation_remove_folder_alert">Siz həqiqətəndə %1$s və onun kontentini silmək istəyirsiniz?</string>
   <string name="confirmation_remove_local">Yalnız daxili</string>
   <string name="confirmation_remove_folder_local">Yalnız daxili</string>
@@ -289,5 +288,6 @@ inzibatçınızla əlaqə saxlayasınız.</string>
   <string name="auth_refresh_button">Qoşulmanı yenilə</string>
   <string name="auth_host_address">Server ünvanı</string>
   <string name="share_dialog_title">Paylaşılır</string>
+  <string name="share_via_link_section_title">Linki yayımla</string>
   <string name="share_search">Axtarış</string>
 </resources>
index 1500f25..30e03e4 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Изтегляне</string>
   <string name="filedetails_renamed_in_upload_msg">Файлът беше преименуван на %1$s по време на качването.</string>
   <string name="list_layout">Списък с изгледи</string>
-  <string name="action_share_file">Връзка за споделяне</string>
-  <string name="action_unshare_file">Премахване връзка за споделяне</string>
+  <string name="action_share">Споделяне</string>
   <string name="common_yes">Да</string>
   <string name="common_no">Не</string>
   <string name="common_ok">ОК</string>
   <string name="favorite">Любими</string>
   <string name="common_rename">Преименуване</string>
   <string name="common_remove">Премахване</string>
-  <string name="confirmation_remove_alert">Наистина ли искате да изтриете %1$s ?</string>
+  <string name="confirmation_remove_file_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="file_list__footer__files_and_folder">%1$d файла, 1 папка</string>
   <string name="file_list__footer__files_and_folders">%1$d файла, %2$d папки</string>
   <string name="share_dialog_title">Споделяне</string>
+  <string name="share_via_link_section_title">Връзка за споделяне</string>
+  <string name="share_via_link_expiration_date_label">Задаване на дата на изтичане</string>
+  <string name="share_via_link_password_label">Защитено с парола</string>
   <string name="share_search">Търсене</string>
 </resources>
index 637cad4..a4b0aad 100644 (file)
@@ -64,8 +64,7 @@
   <string name="filedetails_modified">পরিবর্তিতঃ</string>
   <string name="filedetails_download">ডাউনলোড</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="action_share">ভাগাভাগি কর</string>
   <string name="common_yes">হ্যাঁ</string>
   <string name="common_no">না</string>
   <string name="common_ok">তথাস্তু</string>
   <string name="favorite">প্রিয়জন</string>
   <string name="common_rename">পূনঃনামকরণ</string>
   <string name="common_remove">অপসারণ</string>
-  <string name="confirmation_remove_alert">আপনি কি সত্যিই %1$s অপসারণ করতে চান?</string>
+  <string name="confirmation_remove_file_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="prefs_category_security">নিরাপত্তা</string>
   <string name="auth_host_address">সার্ভার ঠিকানা</string>
   <string name="share_dialog_title">ভাগাভাগিরত</string>
+  <string name="share_via_link_section_title">লিংক ভাগাভাগি করেন</string>
+  <string name="share_via_link_expiration_date_label">মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ করুন</string>
+  <string name="share_via_link_password_label">কূটশব্দ সুরক্ষিত</string>
   <string name="share_search">অনুসন্ধান</string>
 </resources>
index 87b4b20..d8eddb6 100644 (file)
@@ -17,6 +17,7 @@
   <string name="sync_string_files">ফাইলস</string>
   <string name="uploader_btn_new_folder_text">নতুন ফোল্ডার</string>
   <string name="filedetails_download">ডাউনলোড করুন</string>
+  <string name="action_share">শেয়ার</string>
   <string name="common_cancel">বাতিল করা</string>
   <string name="common_error">ভুল</string>
   <string name="uploader_info_dirname">ফোল্ডারের নাম</string>
index 4ce4a45..569bff0 100644 (file)
@@ -20,7 +20,7 @@
   <string name="uploader_btn_upload_text">Učitaj</string>
   <string name="uploader_btn_new_folder_text">Novi direktorij</string>
   <string name="filedetails_download">Preuzmite</string>
-  <string name="action_share_file">Podijelite vezu</string>
+  <string name="action_share">Dijeli</string>
   <string name="common_yes">Da</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">Ok</string>
@@ -39,5 +39,8 @@
   <string name="prefs_category_security">Sigurnost</string>
   <string name="auth_host_address">Adresa servera</string>
   <string name="share_dialog_title">Dijeljenje</string>
+  <string name="share_via_link_section_title">Podijelite vezu</string>
+  <string name="share_via_link_expiration_date_label">Postavite datum isteka</string>
+  <string name="share_via_link_password_label">Zaštitita lozinkom</string>
   <string name="share_search">Potraži</string>
 </resources>
index 289848d..e54eda6 100644 (file)
@@ -73,8 +73,7 @@
   <string name="filedetails_modified">Modificat:</string>
   <string name="filedetails_download">Baixa</string>
   <string name="filedetails_renamed_in_upload_msg">L\'arxiu s\'ha canviat de nom a %1$s durant la càrrega</string>
-  <string name="action_share_file">Enllaç de compartició</string>
-  <string name="action_unshare_file">Deixa de compartir l\'enllaç</string>
+  <string name="action_share">Comparteix</string>
   <string name="common_yes">Sí</string>
   <string name="common_no">No</string>
   <string name="common_ok">D\'acord</string>
   <string name="favorite">Preferits</string>
   <string name="common_rename">Reanomena</string>
   <string name="common_remove">Elimina</string>
-  <string name="confirmation_remove_alert">Esteu segur que voleu eliminar %1$s?</string>
+  <string name="confirmation_remove_file_alert">Esteu segur que voleu eliminar %1$s?</string>
   <string name="confirmation_remove_folder_alert">Estàs segur que vols esborrar %1$s i els seus continguts?</string>
   <string name="confirmation_remove_local">Només local</string>
   <string name="confirmation_remove_folder_local">Només local</string>
   <string name="prefs_category_security">Seguretat</string>
   <string name="auth_host_address">Adreça del servidor</string>
   <string name="share_dialog_title">Compartir</string>
+  <string name="share_via_link_section_title">Comparteix l\'enllaç</string>
+  <string name="share_via_link_expiration_date_label">Estableix la data de venciment</string>
+  <string name="share_via_link_password_label">Protegir amb contrasenya</string>
   <string name="share_search">Cerca</string>
 </resources>
index 4453c48..77aba36 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Synchronizovat</string>
   <string name="filedetails_renamed_in_upload_msg">Soubor byl v průběhu odesílání přejmenován na %1$s</string>
   <string name="list_layout">Náhled seznamu</string>
-  <string name="action_share_file">Sdílet odkaz</string>
-  <string name="action_unshare_file">Zrušit sdílení odkazu</string>
-  <string name="action_share_with_users">Sdílet s uživateli</string>
+  <string name="action_share">Sdílet</string>
   <string name="common_yes">Ano</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Odebrat z oblíbených</string>
   <string name="common_rename">Přejmenovat</string>
   <string name="common_remove">Odstranit</string>
-  <string name="confirmation_remove_alert">Opravdu chcete odstranit %1$s ?</string>
+  <string name="confirmation_remove_file_alert">Opravdu chcete odstranit %1$s ?</string>
   <string name="confirmation_remove_folder_alert">Opravdu chcete odstranit %1$s a jeho obsah?</string>
   <string name="confirmation_remove_local">Pouze místní</string>
   <string name="confirmation_remove_folder_local">Pouze místní</string>
-  <string name="confirmation_remove_remote">Ze serveru</string>
+  <string name="confirmation_remove_file_remote">Ze serveru</string>
   <string name="confirmation_remove_remote_and_local">Vzdálený &amp; místní</string>
   <string name="remove_success_msg">Úspěšně odstraněno</string>
   <string name="remove_fail_msg">Odstranění nelze dokončit</string>
@@ -273,6 +271,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="update_link_file_no_exist">Nelze aktulizovat. Ověřte že soubor existuje</string>
+  <string name="update_link_file_error">Došlo k chybě při pokusu aktualizovat sdílený odkaz</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>
@@ -289,6 +289,7 @@ správce systému.</string>
   <string name="forbidden_permissions_delete">smazat tento soubor</string>
   <string name="share_link_forbidden_permissions">sdílet tento soubor</string>
   <string name="unshare_link_forbidden_permissions">zrušit sdílení tohoto souboru</string>
+  <string name="update_link_forbidden_permissions">aktualizovat tento sdílený odkaz</string>
   <string name="forbidden_permissions_create">vytvořit tento soubor</string>
   <string name="uploader_upload_forbidden_permissions">nahrávat do tohoto adresáře</string>
   <string name="downloader_download_file_not_found">Tento soubor již není dostupný na serveru</string>
@@ -339,6 +340,11 @@ správce systému.</string>
   <string name="share_with_user_section_title">Sdílet s uživateli a skupinami</string>
   <string name="share_no_users">Zatím nebyla s uživateli sdílena žádná data</string>
   <string name="share_add_user_or_group">Přidat uživatele nebo skupinu</string>
+  <string name="share_via_link_section_title">Sdílet odkaz</string>
+  <string name="share_via_link_expiration_date_label">Nastavit datum vypršení platnosti</string>
+  <string name="share_via_link_password_label">Chránit heslem</string>
+  <string name="share_via_link_password_title">Zabezpečeno</string>
+  <string name="share_get_public_link_button">Vytvořit odkaz</string>
   <string name="share_search">Hledat</string>
   <string name="search_users_and_groups_hint">Prohledat uživatele a skupiny</string>
   <string name="share_group_clarification">%1$s (skupina)</string>
index d3b885d..5a47c64 100644 (file)
@@ -39,6 +39,7 @@
   <string name="filedetails_modified">Addaswyd:</string>
   <string name="filedetails_download">Llwytho i lawr</string>
   <string name="filedetails_renamed_in_upload_msg">Ailenwyd y ffeil i %1$s wrth lwytho i fyny</string>
+  <string name="action_share">Rhannu</string>
   <string name="common_yes">Ie</string>
   <string name="common_no">Na</string>
   <string name="common_ok">Iawn</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">Cyfrifon</string>
   <string name="folder_picker_choose_button_text">Dewisiwch</string>
+  <string name="share_via_link_expiration_date_label">Gosod dyddiad dod i ben</string>
+  <string name="share_via_link_password_label">Diogelu cyfrinair</string>
   <string name="share_search">Chwilio</string>
 </resources>
index 6f719c0..2697926 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Hent</string>
   <string name="filedetails_renamed_in_upload_msg">Filen blev omdøbt til %1$s under upload</string>
   <string name="list_layout">Listevisning</string>
-  <string name="action_share_file">Del link</string>
-  <string name="action_unshare_file">Ophæv deling</string>
+  <string name="action_share">Del</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nej</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Fjern markering som foretrukket</string>
   <string name="common_rename">Omdøb</string>
   <string name="common_remove">Fjern</string>
-  <string name="confirmation_remove_alert">Er du sikker på at du vil fjerne %1$s ?</string>
+  <string name="confirmation_remove_file_alert">Er du sikker på at du vil fjerne %1$s ?</string>
   <string name="confirmation_remove_folder_alert">Ønsker du virkelig at slette %1$s og dets indhold?</string>
   <string name="confirmation_remove_local">Kun lokal</string>
   <string name="confirmation_remove_folder_local">Kun lokal</string>
-  <string name="confirmation_remove_remote">Fra server</string>
+  <string name="confirmation_remove_file_remote">Fra server</string>
   <string name="confirmation_remove_remote_and_local">Fjernbeliggende og lokalt</string>
   <string name="remove_success_msg">Vellykket fjernelse</string>
   <string name="remove_fail_msg">Fjernelse kunne ikke fuldføres</string>
   <string name="file_list__footer__files_and_folder">%1$d filer, 1 mape</string>
   <string name="file_list__footer__files_and_folders">%1$d filer, %2$d mapper</string>
   <string name="share_dialog_title">Deling</string>
+  <string name="share_via_link_section_title">Del link</string>
+  <string name="share_via_link_expiration_date_label">Vælg udløbsdato</string>
+  <string name="share_via_link_password_label">Beskyt med adgangskode</string>
   <string name="share_search">Søg</string>
 </resources>
index 4396346..98dcaff 100644 (file)
@@ -59,8 +59,7 @@
   <string name="filedetails_created">Erstellt am:</string>
   <string name="filedetails_modified">Verändert am:</string>
   <string name="filedetails_download">Herunterladen</string>
-  <string name="action_share_file">Link teilen</string>
-  <string name="action_unshare_file">Link nicht mehr teilen</string>
+  <string name="action_share">Freigeben</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nein</string>
   <string name="common_ok">OK</string>
   <string name="empty"></string>
   <string name="prefs_category_accounts">Konten</string>
   <string name="auth_host_address">Adresse des Servers</string>
+  <string name="share_via_link_section_title">Link teilen</string>
 </resources>
index 2039297..375303f 100644 (file)
   <string name="common_remove">Löschen</string>
   <string name="confirmation_remove_local">Nur lokal</string>
   <string name="confirmation_remove_folder_local">Nur lokale Inhalte</string>
-  <string name="confirmation_remove_remote">Vom Server entfernen</string>
+  <string name="confirmation_remove_file_remote">Vom Server entfernen</string>
   <string name="confirmation_remove_remote_and_local">Lokal und auf dem Server</string>
   <string name="remove_success_msg">Erfolgreich gelöscht</string>
   <string name="remove_fail_msg">Der Löschvorgang konnte nicht beendet werden</string>
index 2364d77..fac8a64 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Herunterladen</string>
   <string name="filedetails_renamed_in_upload_msg">Datei wurde wärend des Uploads zu %1$s umbenannt</string>
   <string name="list_layout">Listen-Layout</string>
-  <string name="action_share_file">Link teilen</string>
-  <string name="action_unshare_file">Link nicht mehr teilen</string>
+  <string name="action_share">Share</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nein</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Nicht mehr favorisieren</string>
   <string name="common_rename">Umbenennen</string>
   <string name="common_remove">Löschen</string>
-  <string name="confirmation_remove_alert">Möchten Sie %1$s wirklich löschen?</string>
+  <string name="confirmation_remove_file_alert">Möchten Sie %1$s wirklich löschen?</string>
   <string name="confirmation_remove_folder_alert">Möchten Sie wirklich %1$s und dessen Inhalte entfernen?</string>
   <string name="confirmation_remove_local">Nur lokal</string>
   <string name="confirmation_remove_folder_local">Nur lokal</string>
   <string name="file_list__footer__files_and_folder">%1$d Dateien, 1 Ordner</string>
   <string name="file_list__footer__files_and_folders">%1$d Dateien, %2$d Ordner</string>
   <string name="share_dialog_title">Teilen</string>
+  <string name="share_via_link_section_title">Link teilen</string>
+  <string name="share_via_link_expiration_date_label">Ein Ablaufdatum setzen</string>
+  <string name="share_via_link_password_label">Passwortschutz</string>
   <string name="share_search">Suche</string>
 </resources>
index 134e8a4..0618cc4 100644 (file)
@@ -81,8 +81,7 @@
   <string name="filedetails_download">Herunterladen</string>
   <string name="filedetails_renamed_in_upload_msg">Datei wurde wärend des Uploads zu %1$s umbenannt</string>
   <string name="list_layout">Listen-Layout</string>
-  <string name="action_share_file">Link teilen</string>
-  <string name="action_unshare_file">Link nicht mehr freigeben</string>
+  <string name="action_share">Teilen</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nein</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Favorit entfernen</string>
   <string name="common_rename">Umbenennen</string>
   <string name="common_remove">Löschen</string>
-  <string name="confirmation_remove_alert">Möchtest Du %1$s wirklich löschen?</string>
+  <string name="confirmation_remove_file_alert">Möchtest Du %1$s wirklich löschen?</string>
   <string name="confirmation_remove_folder_alert">Möchtest Du wirklich %1$s und dessen Inhalte entfernen?</string>
   <string name="confirmation_remove_local">Nur lokal</string>
   <string name="confirmation_remove_folder_local">Nur lokal</string>
   <string name="file_list__footer__files_and_folder">%1$d Dateien, 1 Ordner</string>
   <string name="file_list__footer__files_and_folders">%1$d Dateien, %2$d Ordner</string>
   <string name="share_dialog_title">Teilen</string>
+  <string name="share_no_users">Es wurden noch keine Dateien mit Benutzern geteilt</string>
+  <string name="share_add_user_or_group">Benutzer oder Gruppe hinzufügen</string>
+  <string name="share_via_link_section_title">Link teilen</string>
+  <string name="share_via_link_expiration_date_label">Setze ein Ablaufdatum</string>
+  <string name="share_via_link_password_label">Passwortschutz</string>
   <string name="share_search">Suche</string>
 </resources>
index 0f258a6..19cdf9d 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Συγχρονισμός</string>
   <string name="filedetails_renamed_in_upload_msg">Το αρχείο μετονομάστηκε σε %1$s κατά τη μεταφόρτωση</string>
   <string name="list_layout">Διάταξη Λίστας</string>
-  <string name="action_share_file">Διαμοιρασμός συνδέσμου</string>
-  <string name="action_unshare_file">Ακύρωση διαμοιρασμού συνδέσμου</string>
-  <string name="action_share_with_users">Διαμοιρασμός με χρήστες</string>
+  <string name="action_share">Διαμοιράστε</string>
   <string name="common_yes">Ναι</string>
   <string name="common_no">Όχι</string>
   <string name="common_ok">ΟΚ</string>
   <string name="unfavorite">Κατάργηση από τα αγαπημένα</string>
   <string name="common_rename">Μετονομασία</string>
   <string name="common_remove">Αφαίρεση</string>
-  <string name="confirmation_remove_alert">Θέλετε στ\' αλήθεια να αφαιρέσετε το  %1$s;</string>
+  <string name="confirmation_remove_file_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_file_remote">Από το διακομιστή</string>
   <string name="confirmation_remove_remote_and_local">Απομακρυσμένα &amp; τοπικά</string>
   <string name="remove_success_msg">Αφαίρεση επιτυχής</string>
   <string name="remove_fail_msg">Η αφαίρεση απέτυχε</string>
   <string name="file_list__footer__files_and_folder">%1$d αρχεία, 1 φάκελος</string>
   <string name="file_list__footer__files_and_folders">%1$d αρχεία, %2$d φάκελοι</string>
   <string name="share_dialog_title">Διαμοιρασμός</string>
-  <string name="share_with_user_section_title">Διαμοιρασμός με χρήστες και ομάδες</string>
   <string name="share_no_users">Δεν έχουν διαμοιραστεί ακόμα δεδομένα με τους χρήστες</string>
   <string name="share_add_user_or_group">Προσθήκη χρήστη ή ομάδας</string>
+  <string name="share_via_link_section_title">Διαμοιρασμός συνδέσμου</string>
+  <string name="share_via_link_expiration_date_label">Ορισμός ημ. λήξης</string>
+  <string name="share_via_link_password_label">Προστασία συνθηματικού</string>
   <string name="share_search">Αναζήτηση</string>
   <string name="search_users_and_groups_hint">Αναζήτηση χρηστών και ομάδων</string>
   <string name="share_group_clarification">%1$s (ομάδα)</string>
index ddcc145..c87a88a 100644 (file)
@@ -74,8 +74,7 @@
   <string name="filedetails_modified">Modified:</string>
   <string name="filedetails_download">Download</string>
   <string name="filedetails_renamed_in_upload_msg">File was renamed to %1$s during upload</string>
-  <string name="action_share_file">Share link</string>
-  <string name="action_unshare_file">Unshare link</string>
+  <string name="action_share">Share</string>
   <string name="common_yes">Yes</string>
   <string name="common_no">No</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Unfavourite</string>
   <string name="common_rename">Rename</string>
   <string name="common_remove">Remove</string>
-  <string name="confirmation_remove_alert">Do you really want to remove %1$s?</string>
+  <string name="confirmation_remove_file_alert">Do you really want to remove %1$s?</string>
   <string name="confirmation_remove_folder_alert">Do you really want to remove %1$s and its contents?</string>
   <string name="confirmation_remove_local">Local only</string>
   <string name="confirmation_remove_folder_local">Local only</string>
   <string name="auth_host_address">Server address</string>
   <string name="common_error_out_memory">Not enough memory</string>
   <string name="share_dialog_title">Sharing</string>
+  <string name="share_via_link_section_title">Share link</string>
+  <string name="share_via_link_expiration_date_label">Set expiration date</string>
+  <string name="share_via_link_password_label">Password protect</string>
   <string name="share_search">Search</string>
 </resources>
index fb94653..f9cabdf 100644 (file)
@@ -48,8 +48,7 @@
   <string name="filedetails_modified">Modifita je:</string>
   <string name="filedetails_download">Elŝuti</string>
   <string name="filedetails_renamed_in_upload_msg">La dosiero alinomiĝis al %1$s dum alŝuto</string>
-  <string name="action_share_file">Konhavigi ligilon</string>
-  <string name="action_unshare_file">Malkunhavigi ligilon</string>
+  <string name="action_share">Kunhavigi</string>
   <string name="common_yes">Jes</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">Akcepti</string>
   <string name="unfavorite">Nefavoratigi</string>
   <string name="common_rename">Alinomigi</string>
   <string name="common_remove">Forigi</string>
-  <string name="confirmation_remove_alert">Ĉu vi vere volas forigi %1$s?</string>
+  <string name="confirmation_remove_file_alert">Ĉu vi vere volas forigi %1$s?</string>
   <string name="confirmation_remove_folder_alert">Ĉu vi vere volas forigi %1$s kaj ĝia enhavo?</string>
   <string name="confirmation_remove_local">Nur loka</string>
   <string name="confirmation_remove_folder_local">Nur loka</string>
   <string name="file_list__footer__file">1 dosiero</string>
   <string name="file_list__footer__files">%1$d dosieroj</string>
   <string name="share_dialog_title">Kunhavigo</string>
+  <string name="share_via_link_section_title">Kunhavigi ligilon</string>
+  <string name="share_via_link_expiration_date_label">Agordi limdaton</string>
+  <string name="share_via_link_password_label">Protekti per pasvorto</string>
   <string name="share_search">Serĉi</string>
 </resources>
index db21c45..5686138 100644 (file)
@@ -21,6 +21,7 @@
        <item>Biggest - Smallest</item>-->
   <!--TODO re-enable when "Accounts" is available in Navigation Drawer-->
   <!--<string name="drawer_item_accounts">Accounts</string>-->
+  <string name="drawer_item_all_files">Todos los archivos</string>
   <!--TODO re-enable when "On Device" is available
     <string name="drawer_item_on_device">On device</string>-->
   <string name="drawer_open">Abrir</string>
@@ -73,8 +74,7 @@
   <string name="filedetails_modified">Modificado:</string>
   <string name="filedetails_download">Descargar</string>
   <string name="filedetails_renamed_in_upload_msg">El archivo fue renombrado como %1$s durante la subida</string>
-  <string name="action_share_file">Compartir vínculo</string>
-  <string name="action_unshare_file">Dejar de compartir vínculo</string>
+  <string name="action_share">Compartir</string>
   <string name="common_yes">Sí</string>
   <string name="common_no">No</string>
   <string name="common_ok">Aceptar</string>
   <string name="favorite">Favorito</string>
   <string name="common_rename">Renombrar</string>
   <string name="common_remove">Borrar</string>
-  <string name="confirmation_remove_alert">¿Realmente quieres eliminar %1$s?</string>
+  <string name="confirmation_remove_file_alert">¿Realmente quieres eliminar %1$s?</string>
   <string name="confirmation_remove_folder_alert">¿Realmente deseas eliminar %1$s y todo su contenido?</string>
   <string name="confirmation_remove_local">Sólo local</string>
   <string name="confirmation_remove_folder_local">Sólo local</string>
   <string name="prefs_instant_video_upload_path_title">Dirección de subida del video</string>
   <string name="auth_host_address">Dirección del servidor</string>
   <string name="share_dialog_title">Compartiendo</string>
+  <string name="share_via_link_section_title">Compartir vínculo</string>
+  <string name="share_via_link_expiration_date_label">Asignar fecha de vencimiento</string>
+  <string name="share_via_link_password_label">Proteger con contraseña </string>
   <string name="share_search">Buscar</string>
 </resources>
index ed6cbbd..2ba28fd 100644 (file)
@@ -44,6 +44,7 @@
   <string name="filedetails_modified">Modificado:</string>
   <string name="filedetails_download">Descargar</string>
   <string name="filedetails_renamed_in_upload_msg">El archivo fue renombrado a %1$s durante la subida</string>
+  <string name="action_share">Compartir</string>
   <string name="common_yes">Si</string>
   <string name="common_no">No</string>
   <string name="common_ok">OK</string>
   <string name="auth_unauthorized">usuario o clave incorrecta</string>
   <string name="common_rename">Renombrar</string>
   <string name="common_remove">Remover</string>
-  <string name="confirmation_remove_alert">¿Realmente desea eliminar %1$s?</string>
+  <string name="confirmation_remove_file_alert">¿Realmente desea eliminar %1$s?</string>
   <string name="confirmation_remove_folder_alert">¿Realmente desea eliminar el archivo %1$s y su contenido?</string>
   <string name="confirmation_remove_local">Solo local</string>
   <string name="confirmation_remove_folder_local">Solo local</string>
index dc31f88..2a287bc 100644 (file)
@@ -59,7 +59,7 @@
   <string name="filedetails_modified">Modificado:</string>
   <string name="filedetails_download">Descargar</string>
   <string name="filedetails_renamed_in_upload_msg">El archivo fue renombrado como %1$s durante la subida</string>
-  <string name="action_share_file">Enlace compartido</string>
+  <string name="action_share">Compartir</string>
   <string name="common_yes">Sí</string>
   <string name="common_no">No</string>
   <string name="common_ok">Aceptar</string>
   <string name="prefs_category_security">Seguridad</string>
   <string name="auth_host_address">Dirección del servidor</string>
   <string name="share_dialog_title">Compartiendo</string>
+  <string name="share_via_link_section_title">Enlace compartido</string>
+  <string name="share_via_link_expiration_date_label">Establecer fecha de caducidad</string>
+  <string name="share_via_link_password_label">Protección con contraseña</string>
   <string name="share_search">Buscar</string>
 </resources>
index cd766c0..ae326b4 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Sincronizar</string>
   <string name="filedetails_renamed_in_upload_msg">El fichero fue renombrado como %1$s durante la subida</string>
   <string name="list_layout">Diseño de lista</string>
-  <string name="action_share_file">Compartir con enlace</string>
-  <string name="action_unshare_file">Dejar de compartir</string>
-  <string name="action_share_with_users">Compartir con usuarios</string>
+  <string name="action_share">Compartir</string>
   <string name="common_yes">Sí</string>
   <string name="common_no">No</string>
   <string name="common_ok">Aceptar</string>
   <string name="unfavorite">No-favorito</string>
   <string name="common_rename">Renombrar</string>
   <string name="common_remove">Borrar</string>
-  <string name="confirmation_remove_alert">¿Realmente desea eliminar %1$s?</string>
+  <string name="confirmation_remove_file_alert">¿Realmente desea eliminar %1$s?</string>
   <string name="confirmation_remove_folder_alert">¿Realmente desea eliminar %1$s y todo su contenido?</string>
   <string name="confirmation_remove_local">Sólo local</string>
   <string name="confirmation_remove_folder_local">Sólo local</string>
-  <string name="confirmation_remove_remote">Desde el servidor</string>
+  <string name="confirmation_remove_file_remote">Desde el servidor</string>
   <string name="confirmation_remove_remote_and_local">Remoto &amp; local</string>
   <string name="remove_success_msg">Borrado correctamente</string>
   <string name="remove_fail_msg">El borrado no pudo ser completado</string>
   <string name="file_list__footer__files_and_folder">%1$d archivos, 1 carpeta</string>
   <string name="file_list__footer__files_and_folders">%1$d archivos, %2$d carpetas</string>
   <string name="share_dialog_title">Compartiendo</string>
-  <string name="share_with_user_section_title">Compartir con Usuarios y Grupos</string>
   <string name="share_no_users">Aún no se ha compartido con ningún usuario.</string>
   <string name="share_add_user_or_group">Añadir usuario o grupo</string>
+  <string name="share_via_link_section_title">Compartir enlace</string>
+  <string name="share_via_link_expiration_date_label">Establecer fecha de caducidad</string>
+  <string name="share_via_link_password_label">Protección con contraseña</string>
   <string name="share_search">Buscar</string>
   <string name="search_users_and_groups_hint">Buscar usuarios y grupos</string>
   <string name="share_group_clarification">%1$s (grupo)</string>
index 9691363..1cf4e6c 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Lae alla</string>
   <string name="filedetails_renamed_in_upload_msg">Fail nimetati üleslaadimise käigus ümber %1$ </string>
   <string name="list_layout">Nimekirja paigutus</string>
-  <string name="action_share_file">Jaga linki</string>
-  <string name="action_unshare_file">Tühista lingi jagamine</string>
+  <string name="action_share">Jaga</string>
   <string name="common_yes">Jah</string>
   <string name="common_no">Ei</string>
   <string name="common_ok">OK</string>
@@ -199,11 +198,11 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
   <string name="unfavorite">Eemalda lemmik</string>
   <string name="common_rename">Nimeta ümber</string>
   <string name="common_remove">Eemalda</string>
-  <string name="confirmation_remove_alert">Oled sa kindel, et soovid %1$s eemaldada?</string>
+  <string name="confirmation_remove_file_alert">Oled sa kindel, et soovid %1$s eemaldada?</string>
   <string name="confirmation_remove_folder_alert">Kas sa tõesti soovid eemaldada %1$s ja selle sisu?</string>
   <string name="confirmation_remove_local">Ainult kohalik</string>
   <string name="confirmation_remove_folder_local">Ainult kohalik</string>
-  <string name="confirmation_remove_remote">Serverist</string>
+  <string name="confirmation_remove_file_remote">Serverist</string>
   <string name="confirmation_remove_remote_and_local">Kaugfail &amp; kohalik</string>
   <string name="remove_success_msg">Eemaldamine oli edukas</string>
   <string name="remove_fail_msg">Eemaldamine ebaõnnestus</string>
@@ -333,5 +332,8 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
   <string name="file_list__footer__files_and_folder">%1$d faili, 1 kaust</string>
   <string name="file_list__footer__files_and_folders">%1$d faili, %2$d kausta</string>
   <string name="share_dialog_title">Jagamine</string>
+  <string name="share_via_link_section_title">Jaga linki</string>
+  <string name="share_via_link_expiration_date_label">Määra aegumise kuupäev</string>
+  <string name="share_via_link_password_label">Parooliga kaitstud</string>
   <string name="share_search">Otsi</string>
 </resources>
index c4ff565..c9879c6 100644 (file)
@@ -71,8 +71,7 @@
   <string name="filedetails_modified">Aldatuta:</string>
   <string name="filedetails_download">Deskargatu</string>
   <string name="filedetails_renamed_in_upload_msg">Fitxategiaren izena %1$sra aldatu da igotzean</string>
-  <string name="action_share_file">Elkarbanatu lotura</string>
-  <string name="action_unshare_file">Lotura partekatzeari utzi</string>
+  <string name="action_share">Partekatu</string>
   <string name="common_yes">Bai</string>
   <string name="common_no">Ez</string>
   <string name="common_ok">Ados</string>
@@ -174,7 +173,7 @@ Mesedez, baimendu berriz</string>
   <string name="favorite">Gogokoa</string>
   <string name="common_rename">Berrizendatu</string>
   <string name="common_remove">Ezabatu</string>
-  <string name="confirmation_remove_alert">Ziur zaude %1$s ezabatu nahi duzula?</string>
+  <string name="confirmation_remove_file_alert">Ziur zaude %1$s ezabatu nahi duzula?</string>
   <string name="confirmation_remove_folder_alert">Ziru zaude %1$s eta bere edukiak ezabatu nahi dituzula?</string>
   <string name="confirmation_remove_local">Bertakoa bakarrik</string>
   <string name="confirmation_remove_folder_local">Bertakoa bakarrik</string>
@@ -277,5 +276,8 @@ Mesedez, baimendu berriz</string>
   <string name="prefs_instant_video_upload_path_title">Bideo Igoera Bidea</string>
   <string name="auth_host_address">Zerbitzariaren helbidea</string>
   <string name="share_dialog_title">Partekatzea</string>
+  <string name="share_via_link_section_title">Elkarbanatu lotura</string>
+  <string name="share_via_link_expiration_date_label">Ezarri muga data</string>
+  <string name="share_via_link_password_label">Babestu pasahitzarekin</string>
   <string name="share_search">Bilatu</string>
 </resources>
index 35696da..8dab96b 100644 (file)
@@ -71,8 +71,7 @@
   <string name="filedetails_modified">تغییر یافته توسط:</string>
   <string name="filedetails_download">بارگیری</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="action_share">اشتراک‌گذاری</string>
   <string name="common_yes">بله</string>
   <string name="common_no">نه</string>
   <string name="common_ok">باشه</string>
   <string name="file_list__footer__files_and_folder">%1$d فایل، 1 پوشه</string>
   <string name="file_list__footer__files_and_folders">%1$d فایل, %2$d پوشه</string>
   <string name="share_dialog_title">اشتراک گذاری</string>
+  <string name="share_via_link_section_title">اشتراک گذاشتن لینک</string>
+  <string name="share_via_link_expiration_date_label">تنظیم تاریخ انقضا</string>
+  <string name="share_via_link_password_label">نگهداری کردن رمز عبور</string>
   <string name="share_search">جست‌و‌جو</string>
 </resources>
index ef76270..b0852a2 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Synkronoi</string>
   <string name="filedetails_renamed_in_upload_msg">Tiedoston nimeksi muutettiin %1$s siirron yhteydessä</string>
   <string name="list_layout">Luettelon asettelu</string>
-  <string name="action_share_file">Jaa linkki</string>
-  <string name="action_unshare_file">Poista linkin jako</string>
-  <string name="action_share_with_users">Jaa käyttäjien kanssa</string>
+  <string name="action_share">Jaa</string>
   <string name="common_yes">Kyllä</string>
   <string name="common_no">Ei</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Poista suosikeista</string>
   <string name="common_rename">Nimeä uudelleen</string>
   <string name="common_remove">Poista</string>
-  <string name="confirmation_remove_alert">Haluatko varmasti poistaa kohteen %1$s?</string>
+  <string name="confirmation_remove_file_alert">Haluatko varmasti poistaa kohteen %1$s?</string>
   <string name="confirmation_remove_folder_alert">Haluatko varmasti poistaa kohteen %1$s ja sen sisällön?</string>
   <string name="confirmation_remove_local">Vain paikallinen</string>
   <string name="confirmation_remove_folder_local">Vain paikallinen</string>
-  <string name="confirmation_remove_remote">Palvelimelta</string>
+  <string name="confirmation_remove_file_remote">Palvelimelta</string>
   <string name="confirmation_remove_remote_and_local">Etä ja paikallinen</string>
   <string name="remove_success_msg">Poistettu onnistuneesti</string>
   <string name="remove_fail_msg">Poistamista ei voitu suorittaa loppuun asti</string>
   <string name="file_list__footer__files_and_folder">%1$d tiedostoa, 1 kansio</string>
   <string name="file_list__footer__files_and_folders">%1$d tiedostoa, %2$d kansiota</string>
   <string name="share_dialog_title">Jakaminen</string>
-  <string name="share_with_user_section_title">Jaa käyttäjien tai ryhmien kanssa</string>
+  <string name="share_with_user_section_title">Jaa käyttäjien ja ryhmien kanssa</string>
   <string name="share_add_user_or_group">Lisää käyttäjä tai ryhmä</string>
+  <string name="share_via_link_section_title">Jaa linkki</string>
+  <string name="share_via_link_expiration_date_label">Aseta päättymispäivä</string>
+  <string name="share_via_link_password_label">Suojaa salasanalla</string>
   <string name="share_search">Etsi</string>
   <string name="search_users_and_groups_hint">Etsi käyttäjiä ja ryhmiä</string>
   <string name="share_group_clarification">%1$s (ryhmä)</string>
index 8dde313..1a5bc5c 100644 (file)
@@ -83,9 +83,7 @@ Téléchargez-le ici : %2$s</string>
   <string name="filedetails_sync_file">Synchroniser</string>
   <string name="filedetails_renamed_in_upload_msg">Le fichier a été renommé en %s pendant le téléversement</string>
   <string name="list_layout">Affichage en liste</string>
-  <string name="action_share_file">Partager le lien</string>
-  <string name="action_unshare_file">Ne plus partager ce lien</string>
-  <string name="action_share_with_users">Partager avec des utilisateurs</string>
+  <string name="action_share">Partage</string>
   <string name="common_yes">Oui</string>
   <string name="common_no">Non</string>
   <string name="common_ok">OK</string>
@@ -204,11 +202,11 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="unfavorite">Retirer des favoris</string>
   <string name="common_rename">Renommer</string>
   <string name="common_remove">Supprimer</string>
-  <string name="confirmation_remove_alert">Voulez-vous vraiment supprimer %1$s ?</string>
+  <string name="confirmation_remove_file_alert">Voulez-vous vraiment supprimer %1$s ?</string>
   <string name="confirmation_remove_folder_alert">Voulez-vous vraiment supprimer %1$s et son contenu ?</string>
   <string name="confirmation_remove_local">Local seulement</string>
   <string name="confirmation_remove_folder_local">Local seulement</string>
-  <string name="confirmation_remove_remote">Depuis le serveur</string>
+  <string name="confirmation_remove_file_remote">Depuis le serveur</string>
   <string name="confirmation_remove_remote_and_local">Distant &amp; local</string>
   <string name="remove_success_msg">Suppression effectuée avec succès</string>
   <string name="remove_fail_msg">Suppression impossible</string>
@@ -278,6 +276,8 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <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="update_link_file_no_exist">Actualisation impossible. Veuillez vérifier si ce fichier existe</string>
+  <string name="update_link_file_error">Une erreur est survenue lors de la tentative de rafraîchissement du lien partagé</string>
   <string name="share_link_password_title">Saisissez 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>
@@ -294,6 +294,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="forbidden_permissions_delete">d’effacer ce fichier</string>
   <string name="share_link_forbidden_permissions">afin de partager ce fichier</string>
   <string name="unshare_link_forbidden_permissions">afin de ne plus partager ce fichier</string>
+  <string name="update_link_forbidden_permissions">pour mettre à jour ce lien partagé</string>
   <string name="forbidden_permissions_create">de créer ce fichier</string>
   <string name="uploader_upload_forbidden_permissions">afin d’importer dans ce répertoire</string>
   <string name="downloader_download_file_not_found">Ce fichier n’est plus disponible sur le serveur</string>
@@ -341,9 +342,14 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
   <string name="file_list__footer__files_and_folder">%1$d fichiers, 1 dossier</string>
   <string name="file_list__footer__files_and_folders">%1$d fichiers, %2$d dossiers</string>
   <string name="share_dialog_title">Partage</string>
-  <string name="share_with_user_section_title">Partager avec des Utilisateurs et des Groupes</string>
+  <string name="share_with_user_section_title">Partager avec des utilisateurs et des groupes</string>
   <string name="share_no_users">Aucune donnée partagée avec des utilisateurs pour le moment</string>
   <string name="share_add_user_or_group">Ajouter un Utilisateur ou un Groupe</string>
+  <string name="share_via_link_section_title">Partager par lien public</string>
+  <string name="share_via_link_expiration_date_label">Spécifier une date d\'expiration</string>
+  <string name="share_via_link_password_label">Protéger par un mot de passe</string>
+  <string name="share_via_link_password_title">Sécurisé</string>
+  <string name="share_get_public_link_button">Obtenir le lien</string>
   <string name="share_search">Rechercher</string>
   <string name="search_users_and_groups_hint">Chercher parmi les utilisateurs et groupes</string>
   <string name="share_group_clarification">%1$s (groupe)</string>
index 5a02fbb..b649f94 100644 (file)
@@ -83,9 +83,7 @@ Descárgueo de aquí: %2$s</string>
   <string name="filedetails_sync_file">Sincronizar</string>
   <string name="filedetails_renamed_in_upload_msg">O ficheiro foi renomeado a %1$s durante o envío</string>
   <string name="list_layout">Deseño da lista</string>
-  <string name="action_share_file">Ligazón para compartir</string>
-  <string name="action_unshare_file">Deixar de compartir a ligazón</string>
-  <string name="action_share_with_users">Compartir con usuarios</string>
+  <string name="action_share">Compartir</string>
   <string name="common_yes">Si</string>
   <string name="common_no">Non</string>
   <string name="common_ok">Aceptar</string>
@@ -200,7 +198,7 @@ Descárgueo de aquí: %2$s</string>
   <string name="unfavorite">Retirar de favoritos</string>
   <string name="common_rename">Renomear</string>
   <string name="common_remove">Retirar</string>
-  <string name="confirmation_remove_alert">Confirma que quere retirar %1$s?</string>
+  <string name="confirmation_remove_file_alert">Confirma que quere retirar %1$s?</string>
   <string name="confirmation_remove_folder_alert">Confirma que quere retirar %1$s e o seu contido?</string>
   <string name="confirmation_remove_local">Só local</string>
   <string name="confirmation_remove_folder_local">Só local</string>
@@ -335,9 +333,11 @@ Descárgueo de aquí: %2$s</string>
   <string name="file_list__footer__files_and_folder">%1$d ficheiros, 1 cartafol</string>
   <string name="file_list__footer__files_and_folders">%1$d ficheiros, %2$d cartafoles</string>
   <string name="share_dialog_title">Compartindo</string>
-  <string name="share_with_user_section_title">Compartir con Usuarios e Grupos</string>
   <string name="share_no_users">Aínda non hai datos compartidos con usuarios</string>
   <string name="share_add_user_or_group">Engadir Usuario ou Grupo</string>
+  <string name="share_via_link_section_title">Ligazón para compartir</string>
+  <string name="share_via_link_expiration_date_label">Definir a data de caducidade</string>
+  <string name="share_via_link_password_label">Protexido con contrasinal</string>
   <string name="share_search">Buscar</string>
   <string name="search_users_and_groups_hint">Buscar usuarios e grupos</string>
   <string name="share_group_clarification">%1$s (grupo)</string>
index 92c2ac1..693c69e 100644 (file)
@@ -64,8 +64,7 @@
   <string name="filedetails_modified">מועד השינוי:</string>
   <string name="filedetails_download">הורדה</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="action_share">שיתוף</string>
   <string name="common_yes">כן</string>
   <string name="common_no">לא</string>
   <string name="common_ok">אישור</string>
   <string name="favorite">מועדף</string>
   <string name="common_rename">שינוי שם</string>
   <string name="common_remove">הסרה</string>
-  <string name="confirmation_remove_alert">האם באמת להסיר %1$s?</string>
+  <string name="confirmation_remove_file_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="prefs_category_security">אבטחה</string>
   <string name="auth_host_address">כתובת שרת</string>
   <string name="share_dialog_title">שיתוף</string>
+  <string name="share_via_link_section_title">קישור לשיתוף</string>
+  <string name="share_via_link_expiration_date_label">הגדרת תאריך תפוגה</string>
+  <string name="share_via_link_password_label">הגנה בססמה</string>
   <string name="share_search">חיפוש</string>
 </resources>
index feb62ce..ae1a5d7 100644 (file)
@@ -28,6 +28,7 @@
   <string name="setup_btn_connect">जुड़ें </string>
   <string name="uploader_btn_upload_text">अपलोड </string>
   <string name="uploader_btn_new_folder_text">नया फ़ोल्डर</string>
+  <string name="action_share">साझा करें</string>
   <string name="common_cancel">रद्द करें </string>
   <string name="common_error">त्रुटि</string>
   <string name="ssl_validator_btn_details_see">विवरण </string>
index 6fba8ee..7e42269 100644 (file)
@@ -43,7 +43,7 @@
   <string name="file_list_seconds_ago">prije par sekundi</string>
   <string name="file_list_empty">Nema ničega u ovoj mapi. Pošalji nešto!</string>
   <string name="filedetails_download">Preuzimanje</string>
-  <string name="action_share_file">Podijelite vezu</string>
+  <string name="action_share">Dijeljenje</string>
   <string name="common_yes">Da</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">U redu</string>
@@ -66,5 +66,8 @@
   <string name="prefs_category_security">Sigurnost</string>
   <string name="auth_host_address">Adresa poslužitelja</string>
   <string name="share_dialog_title">Dijeljenje zajedničkih resursa</string>
+  <string name="share_via_link_section_title">Podijelite vezu</string>
+  <string name="share_via_link_expiration_date_label">Odredite datum isteka</string>
+  <string name="share_via_link_password_label">Zaštititi lozinkom</string>
   <string name="share_search">pretraži</string>
 </resources>
index 178d595..3fb3b79 100644 (file)
@@ -78,8 +78,7 @@
   <string name="filedetails_sync_file">Szinkronizálás</string>
   <string name="filedetails_renamed_in_upload_msg">A feltöltés során az állmányt erre neveztük át: %1$s</string>
   <string name="list_layout">Lista Elrendezés</string>
-  <string name="action_share_file">Megosztás hivatkozással</string>
-  <string name="action_unshare_file">Megosztás visszavonása</string>
+  <string name="action_share">Megosztás</string>
   <string name="common_yes">Igen</string>
   <string name="common_no">Nem</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Nem kedvenc</string>
   <string name="common_rename">Átnevezés</string>
   <string name="common_remove">Eltávolítás</string>
-  <string name="confirmation_remove_alert">Tényleg el akarod távolítani %1$s?</string>
+  <string name="confirmation_remove_file_alert">Tényleg el akarod távolítani %1$s?</string>
   <string name="confirmation_remove_folder_alert">Tényleg el akarod távolítani a %1$s és tartalmát?</string>
   <string name="confirmation_remove_local">Csak a helyi példány</string>
   <string name="confirmation_remove_folder_local">Csak a helyi példány</string>
   <string name="file_list__footer__files_and_folder">%1$d fájl, 1 könyvtár</string>
   <string name="file_list__footer__files_and_folders">%1$d fájl, %2$d könyvtár</string>
   <string name="share_dialog_title">Megosztás</string>
+  <string name="share_via_link_section_title">Megosztás hivatkozással</string>
+  <string name="share_via_link_expiration_date_label">Legyen lejárati idő</string>
+  <string name="share_via_link_password_label">Jelszóval is védem</string>
   <string name="share_search">Keresés</string>
 </resources>
index ef78c1f..1debd95 100644 (file)
@@ -20,7 +20,7 @@
   <string name="file_list_seconds_ago">վրկ. առաջ</string>
   <string name="filedetails_size">Չափս.</string>
   <string name="filedetails_download">Բեռնել</string>
-  <string name="action_share_file">Կիսվել հղմամբ</string>
+  <string name="action_share">Կիսվել</string>
   <string name="common_yes">Այո</string>
   <string name="common_no">Ոչ</string>
   <string name="common_cancel">Չեղարկել</string>
@@ -42,4 +42,5 @@
   <string name="file_list__footer__files">%1$d ֆայլ</string>
   <string name="file_list__footer__files_and_folder">%1$d ֆայլ, 1 պանակ</string>
   <string name="file_list__footer__files_and_folders">%1$d ֆայլ, %2$d պանակ</string>
+  <string name="share_via_link_section_title">Կիսվել հղմամբ</string>
 </resources>
index 666c923..402b64a 100644 (file)
@@ -29,7 +29,7 @@
   <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="action_share">Compartir</string>
   <string name="common_yes">Si</string>
   <string name="common_no">No</string>
   <string name="common_ok">Ok</string>
@@ -45,5 +45,8 @@
   <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>
+  <string name="share_via_link_section_title">Compartir ligamine</string>
+  <string name="share_via_link_expiration_date_label">Fixa data de expiration</string>
+  <string name="share_via_link_password_label">Protegite per contrasigno</string>
   <string name="share_search">Cercar</string>
 </resources>
index 3fbb3b7..295a8ed 100644 (file)
@@ -81,8 +81,7 @@
   <string name="filedetails_download">Unduh</string>
   <string name="filedetails_renamed_in_upload_msg">Berkas diubah namanya menjadi %1$s saat pengunggahan</string>
   <string name="list_layout">Daftar Tata Letak</string>
-  <string name="action_share_file">Bagikan tautan</string>
-  <string name="action_unshare_file">Batal bagikan tautan</string>
+  <string name="action_share">Bagikan</string>
   <string name="common_yes">Ya</string>
   <string name="common_no">Tidak</string>
   <string name="common_ok">Oke</string>
   <string name="unfavorite">Hapus favorit</string>
   <string name="common_rename">Ubah nama</string>
   <string name="common_remove">Hapus</string>
-  <string name="confirmation_remove_alert">Apakah Anda yakin ingin menghapus %1$s?</string>
+  <string name="confirmation_remove_file_alert">Apakah Anda yakin ingin menghapus %1$s?</string>
   <string name="confirmation_remove_folder_alert">Apakah Anda yakin ingin menghapus %1$s dan isinya?</string>
   <string name="confirmation_remove_local">Lokal saja</string>
   <string name="confirmation_remove_folder_local">Lokal saja</string>
-  <string name="confirmation_remove_remote">Dari server</string>
+  <string name="confirmation_remove_file_remote">Dari server</string>
   <string name="confirmation_remove_remote_and_local">Remot &amp; lokal</string>
   <string name="remove_success_msg">Penghapusan berhasil</string>
   <string name="remove_fail_msg">Penghapusan gagal</string>
   <string name="file_list__footer__files_and_folder">%1$d berkas, 1 folder</string>
   <string name="file_list__footer__files_and_folders">%1$d berkas, %2$d folder</string>
   <string name="share_dialog_title">Berbagi</string>
-  <string name="share_with_user_section_title">Bagikan dengan Pengguna dan Grup</string>
   <string name="share_no_users">Tidak ada data yang dibagikan dengan pengguna</string>
   <string name="share_add_user_or_group">Tambah Pengguna atau Grup</string>
+  <string name="share_via_link_section_title">Bagikan tautan</string>
+  <string name="share_via_link_expiration_date_label">Atur tanggal kedaluwarsa</string>
+  <string name="share_via_link_password_label">Lindungi dengan sandi</string>
   <string name="share_search">Cari</string>
 </resources>
index 046a796..3e89b52 100644 (file)
@@ -20,7 +20,7 @@
   <string name="file_list_seconds_ago">sek.</string>
   <string name="file_list_empty">Ekkert hér. Settu eitthvað inn!</string>
   <string name="filedetails_download">Niðurhal</string>
-  <string name="action_share_file">Deila hlekk</string>
+  <string name="action_share">Deila</string>
   <string name="common_yes">Já</string>
   <string name="common_no">Nei</string>
   <string name="common_ok">Í lagi</string>
@@ -35,5 +35,8 @@
   <string name="actionbar_move">Færa</string>
   <string name="folder_picker_choose_button_text">Veldu</string>
   <string name="auth_host_address">Host nafn netþjóns</string>
+  <string name="share_via_link_section_title">Deila hlekk</string>
+  <string name="share_via_link_expiration_date_label">Setja gildistíma</string>
+  <string name="share_via_link_password_label">Verja með lykilorði</string>
   <string name="share_search">Leita</string>
 </resources>
index 98e444c..49b5ce2 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Sincronizza</string>
   <string name="filedetails_renamed_in_upload_msg">Il file è stato rinominato in %1$s durante il caricamento</string>
   <string name="list_layout">Struttura elenco</string>
-  <string name="action_share_file">Condividi collegamento</string>
-  <string name="action_unshare_file">Rimuovi condivisione collegamento</string>
-  <string name="action_share_with_users">Condividi con utenti</string>
+  <string name="action_share">Condividi</string>
   <string name="common_yes">Sì</string>
   <string name="common_no">No</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Rimuovi dai preferiti</string>
   <string name="common_rename">Rinomina</string>
   <string name="common_remove">Rimuovi</string>
-  <string name="confirmation_remove_alert">Vuoi davvero rimuovere %1$s?</string>
+  <string name="confirmation_remove_file_alert">Vuoi davvero rimuovere %1$s?</string>
   <string name="confirmation_remove_folder_alert">Vuoi davvero rimuovere %1$s e il suo contenuto?</string>
   <string name="confirmation_remove_local">Solo localmente</string>
   <string name="confirmation_remove_folder_local">Solo locale</string>
-  <string name="confirmation_remove_remote">Dal server</string>
+  <string name="confirmation_remove_file_remote">Dal server</string>
   <string name="confirmation_remove_remote_and_local">Remota e locale</string>
   <string name="remove_success_msg">Rimozione effettuata con successo</string>
   <string name="remove_fail_msg">La rimozione non può essere completata</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="update_link_file_no_exist">Impossibile aggiornare. Assicurati che il file esista</string>
+  <string name="update_link_file_error">Si è verificato un errore durante il tentativo di aggiornare il collegamento condiviso</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="forbidden_permissions_delete">per eliminare questo file</string>
   <string name="share_link_forbidden_permissions">per condividere questo file</string>
   <string name="unshare_link_forbidden_permissions">per rimuovere la condivisione di questo file</string>
+  <string name="update_link_forbidden_permissions">per aggiornare questo collegamento condiviso</string>
   <string name="forbidden_permissions_create">per creare il file</string>
   <string name="uploader_upload_forbidden_permissions">per caricare in questa cartella</string>
   <string name="downloader_download_file_not_found">Il file non è più disponibile sul server</string>
   <string name="share_with_user_section_title">Condividi con utenti e gruppi</string>
   <string name="share_no_users">Ancora nessun dato condiviso con gli utenti </string>
   <string name="share_add_user_or_group">Aggiungi utente o gruppo</string>
+  <string name="share_via_link_section_title">Condividi collegamento</string>
+  <string name="share_via_link_expiration_date_label">Imposta data di scadenza</string>
+  <string name="share_via_link_password_label">Proteggi con password</string>
+  <string name="share_via_link_password_title">Protetto</string>
+  <string name="share_get_public_link_button">Ottieni collegamento</string>
   <string name="share_search">Cerca</string>
   <string name="search_users_and_groups_hint">Cerca utenti e gruppi</string>
   <string name="share_group_clarification">%1$s (gruppo)</string>
index 0740784..eb66912 100644 (file)
@@ -83,9 +83,7 @@
   <string name="filedetails_sync_file">ファイルを同期</string>
   <string name="filedetails_renamed_in_upload_msg">アップロード中にファイル名を %1$s に変更しました</string>
   <string name="list_layout">リストレイアウト</string>
-  <string name="action_share_file">URLで共有</string>
-  <string name="action_unshare_file">未共有のリンク</string>
-  <string name="action_share_with_users">ユーザーと共有</string>
+  <string name="action_share">共有</string>
   <string name="common_yes">はい</string>
   <string name="common_no">いいえ</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">お気に入りを解除</string>
   <string name="common_rename">名前を変更</string>
   <string name="common_remove">削除</string>
-  <string name="confirmation_remove_alert">本当に %1$s を削除しますか?</string>
+  <string name="confirmation_remove_file_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="share_link_file_error">このファイルまたはフォルダーを共有する際にエラーが発生しました</string>
   <string name="unshare_link_file_no_exist">共有を解除できません。ファイルがあるか確認してください。</string>
   <string name="unshare_link_file_error">このファイルまたはフォルダーの共有を解除する際にエラーが発生しました</string>
+  <string name="update_link_file_no_exist">更新できません。ファイルがあるか確認してください。</string>
+  <string name="update_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="file_list__footer__files_and_folder">%1$d ファイル、1 フォルダー</string>
   <string name="file_list__footer__files_and_folders">%1$d ファイル、%2$d フォルダー</string>
   <string name="share_dialog_title">共有</string>
-  <string name="share_with_user_section_title">ã\83¦ã\83¼ã\82¶ã\83¼ã\81¾ã\81\9fã\81¯ã\82°ã\83«ã\83¼ã\83\97ã\81«共有</string>
+  <string name="share_with_user_section_title">ã\83¦ã\83¼ã\82¶ã\83¼ã\81¨ã\82°ã\83«ã\83¼ã\83\97ã\81§共有</string>
   <string name="share_no_users">ユーザーと共有されているデータはありません</string>
   <string name="share_add_user_or_group">ユーザーまたはグループを追加</string>
+  <string name="share_via_link_section_title">URLで共有</string>
+  <string name="share_via_link_expiration_date_label">有効期限を設定</string>
+  <string name="share_via_link_password_label">パスワード保護を有効化</string>
+  <string name="share_via_link_password_title">セキュア</string>
+  <string name="share_get_public_link_button">リンクを取得</string>
   <string name="share_search">検索</string>
   <string name="search_users_and_groups_hint">ユーザーとグループを検索</string>
   <string name="share_group_clarification">%1$s (グループ)</string>
index 06bf89b..acdeb62 100644 (file)
@@ -43,6 +43,7 @@
   <string name="filedetails_modified">მოდიფიცირებულია:</string>
   <string name="filedetails_download">ჩამოტვირთვა</string>
   <string name="filedetails_renamed_in_upload_msg">ფაილ %1$s–ზე გადარქმეულ იქნა სახელი ატვირთვის დროს</string>
+  <string name="action_share">გაზიარება</string>
   <string name="common_yes">კი</string>
   <string name="common_no">არა</string>
   <string name="common_ok">დიახ</string>
   <string name="prefs_category_security">უსაფრთხოება</string>
   <string name="auth_host_address">სერვერის მისამართი</string>
   <string name="share_dialog_title">გაზიარება</string>
+  <string name="share_via_link_expiration_date_label">მიუთითე ვადის გასვლის დრო</string>
+  <string name="share_via_link_password_label">პაროლით დაცვა</string>
   <string name="share_search">ძებნა</string>
 </resources>
index 1c9ef99..ece7d32 100644 (file)
@@ -55,6 +55,7 @@
   <string name="filedetails_created">បាន​បង្កើត៖</string>
   <string name="filedetails_modified">បាន​កែ​សម្រួល៖</string>
   <string name="filedetails_download">ទាញយក</string>
+  <string name="action_share">ចែក​រំលែក</string>
   <string name="common_yes">ព្រម</string>
   <string name="common_no">ទេ</string>
   <string name="common_ok">OK</string>
   <string name="prefs_category_security">សុវត្ថិភាព</string>
   <string name="auth_host_address">អាសយដ្ឋាន​ម៉ាស៊ីន​បម្រើ</string>
   <string name="share_dialog_title">ការ​ចែក​រំលែក</string>
+  <string name="share_via_link_expiration_date_label">កំណត់​ពេល​ផុត​កំណត់</string>
+  <string name="share_via_link_password_label">ការ​ពារ​ដោយ​ពាក្យ​សម្ងាត់</string>
   <string name="share_search">ស្វែង​រក</string>
 </resources>
index 4ca45b1..52476d5 100644 (file)
@@ -21,7 +21,7 @@
   <string name="uploader_btn_upload_text">ಪೇರಿಸು</string>
   <string name="uploader_btn_new_folder_text">ಹೊಸ ಕಡತಕೋಶ</string>
   <string name="filedetails_download">ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ</string>
-  <string name="action_share_file">ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು  ಹಂಚಿಕೊಳ್ಳಬಹುದು</string>
+  <string name="action_share">ಹಂಚಿಕೊಳ್ಳಿ</string>
   <string name="common_yes">ಹೌದು</string>
   <string name="common_no">ಇಲ್ಲ</string>
   <string name="common_ok">ಸರಿ</string>
@@ -40,5 +40,8 @@
   <string name="prefs_category_security">ಭದ್ರತೆ</string>
   <string name="auth_host_address">ಪರಿಚಾರಕ ಗಣಕಯಂತ್ರದ ವಿಳಾಸ</string>
   <string name="share_dialog_title">ಹಂಚಿಕೆ</string>
+  <string name="share_via_link_section_title">ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು  ಹಂಚಿಕೊಳ್ಳಬಹುದು</string>
+  <string name="share_via_link_expiration_date_label">ಮುಕ್ತಾಯ ದಿನಾಂಕವನ್ನು ನಿರ್ದರಿಸಿ</string>
+  <string name="share_via_link_password_label">ಗುಪ್ತಪದ ರಕ್ಷಿಸಿಕೂಳ್ಲಿ</string>
   <string name="share_search">ಹುಡುಕು</string>
 </resources>
index 2734d4a..2d1574c 100644 (file)
@@ -81,8 +81,7 @@
   <string name="filedetails_download">다운로드</string>
   <string name="filedetails_renamed_in_upload_msg">업로드 중 파일 이름을 %1$s(으)로 변경하였습니다</string>
   <string name="list_layout">목록 레이아웃</string>
-  <string name="action_share_file">링크 공유</string>
-  <string name="action_unshare_file">링크 공유 해제</string>
+  <string name="action_share">공유</string>
   <string name="common_yes">예</string>
   <string name="common_no">아니요</string>
   <string name="common_ok">확인</string>
   <string name="unfavorite">책갈피 해제</string>
   <string name="common_rename">이름 바꾸기</string>
   <string name="common_remove">삭제</string>
-  <string name="confirmation_remove_alert">%1$s을(를) 삭제하시겠습니까?</string>
+  <string name="confirmation_remove_file_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="file_list__footer__files_and_folder">파일 %1$d개, 폴더 1개</string>
   <string name="file_list__footer__files_and_folders">파일 %1$d개, 폴더 %2$d개</string>
   <string name="share_dialog_title">공유</string>
-  <string name="share_with_user_section_title">Share with Users and Groups</string>
   <string name="share_no_users">No data shared with users yet</string>
   <string name="share_add_user_or_group">Add User or Group</string>
+  <string name="share_via_link_section_title">링크 공유</string>
+  <string name="share_via_link_expiration_date_label">만료 날짜 설정</string>
+  <string name="share_via_link_password_label">암호 보호</string>
   <string name="share_search">검색</string>
 </resources>
index e03d080..c40728b 100644 (file)
@@ -27,6 +27,7 @@
   <string name="filedetails_created">درووستبووە:</string>
   <string name="filedetails_modified">گۆردراو:</string>
   <string name="filedetails_download">داگرتن</string>
+  <string name="action_share">هاوبەشی کردن</string>
   <string name="common_yes">بەڵێ</string>
   <string name="common_no">نەخێر</string>
   <string name="common_ok">باشە</string>
index 5595d5c..55bae32 100644 (file)
@@ -62,7 +62,7 @@
   <string name="filedetails_created">Erstallt:</string>
   <string name="filedetails_modified">Geännert:</string>
   <string name="filedetails_download">Eroflueden</string>
-  <string name="action_share_file">Link deelen</string>
+  <string name="action_share">Deelen</string>
   <string name="common_yes">Jo</string>
   <string name="common_no">Nee</string>
   <string name="common_ok">OK</string>
   <string name="auth_unsupported_auth_method">De Server ënnerstëtzt dës Authentifizéierungsmethod net</string>
   <string name="common_rename">Ëmbenennen</string>
   <string name="common_remove">Läschen</string>
-  <string name="confirmation_remove_alert">Wëlls du %1$s wierklech läschen?</string>
+  <string name="confirmation_remove_file_alert">Wëlls du %1$s wierklech läschen?</string>
   <string name="confirmation_remove_folder_alert">Wëlls du %1$s an de ganzen Inhalt wierklech läschen?</string>
   <string name="confirmation_remove_local">Nemme lokal</string>
   <string name="confirmation_remove_folder_local">Nemme lokal</string>
   <string name="subject_user_shared_with_you">%1$s huet \"%2$s\" mat dir gedeelt</string>
   <string name="auth_refresh_button">Connectioun opfrëschen</string>
   <string name="auth_host_address">Server-Adress</string>
+  <string name="share_via_link_section_title">Link deelen</string>
+  <string name="share_via_link_expiration_date_label">Verfallsdatum setzen</string>
+  <string name="share_via_link_password_label">Passwuertgeschützt</string>
   <string name="share_search">Sichen</string>
 </resources>
index fe371c0..201a001 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Sinchronizuojama</string>
   <string name="filedetails_renamed_in_upload_msg">Įkėlimo metu failas buvo pervadintas į %1$s</string>
   <string name="list_layout">Sąrašo išdėstymas</string>
-  <string name="action_share_file">Dalintis nuoroda</string>
-  <string name="action_unshare_file">Nebesidalinti nuoroda</string>
-  <string name="action_share_with_users">Dalintis su vartotojais</string>
+  <string name="action_share">Dalintis</string>
   <string name="common_yes">Taip</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">Gerai</string>
   <string name="uploader_info_dirname">Katalogo pavadinimas</string>
   <string name="uploader_upload_in_progress_ticker">Įkeliama ...</string>
   <string name="uploader_upload_in_progress_content">%1$d%% Siunčiama %2$s</string>
-  <string name="uploader_upload_succeeded_ticker">Nusiuntimas pavyko</string>
+  <string name="uploader_upload_succeeded_ticker">Įkėlimas pavyko</string>
   <string name="uploader_upload_succeeded_content_single">%1$s buvo sėkmingai nusiųstas</string>
   <string name="uploader_upload_failed_ticker">Nusiuntimas nepavyko</string>
   <string name="uploader_upload_failed_content_single">Nepavyko baigti %1$s nusiuntimo</string>
   <string name="unfavorite">Nebemėgti</string>
   <string name="common_rename">Pervadinti</string>
   <string name="common_remove">Pašalinti</string>
-  <string name="confirmation_remove_alert">Ar tikrai norite pašalinti %1$s?</string>
+  <string name="confirmation_remove_file_alert">Ar tikrai norite pašalinti %1$s?</string>
   <string name="confirmation_remove_folder_alert">Ar tikrai norite pašalinti %1$s ir ten esantį turinį?</string>
   <string name="confirmation_remove_local">Tik vietiniai</string>
   <string name="confirmation_remove_folder_local">Tik vietiniai</string>
   <string name="file_list__footer__files_and_folder">%1$d failai, 1 aplankas</string>
   <string name="file_list__footer__files_and_folders">%1$d failai, %2$d aplankai</string>
   <string name="share_dialog_title">Dalijimasis</string>
-  <string name="share_with_user_section_title">Dalintis su vartotojais ir grupėmis</string>
   <string name="share_no_users">Su vartotojais niekuo nesidalinama</string>
   <string name="share_add_user_or_group">Pridėti vartotoją ar grupę</string>
+  <string name="share_via_link_section_title">Dalintis nuoroda</string>
+  <string name="share_via_link_expiration_date_label">Nustatykite galiojimo laiką</string>
+  <string name="share_via_link_password_label">Apsaugotas slaptažodžiu</string>
   <string name="share_search">Ieškoti</string>
   <string name="search_users_and_groups_hint">Surasti vartotoją ar grupę</string>
   <string name="share_group_clarification">%1$s (grupė)</string>
index 42cb5bb..0b2930d 100644 (file)
@@ -70,8 +70,7 @@
   <string name="filedetails_modified">Modificēta:</string>
   <string name="filedetails_download">Lejupielādēt</string>
   <string name="filedetails_renamed_in_upload_msg">Datne tika pārsaukta uz %1$s augšupielādes laikā</string>
-  <string name="action_share_file">Dalīt saiti</string>
-  <string name="action_unshare_file">Pārtraukt dalīt saiti</string>
+  <string name="action_share">Dalīties</string>
   <string name="common_yes">Jā</string>
   <string name="common_no">Nē</string>
   <string name="common_ok">Labi</string>
   <string name="file_list__footer__folder">1 mape</string>
   <string name="file_list__footer__file">1 datne</string>
   <string name="share_dialog_title">Dalīšanās</string>
+  <string name="share_via_link_section_title">Dalīt saiti</string>
+  <string name="share_via_link_expiration_date_label">Iestaties termiņa datumu</string>
+  <string name="share_via_link_password_label">Aizsargāt ar paroli</string>
   <string name="share_search">Meklēt</string>
 </resources>
index 204e3f1..0773d69 100644 (file)
@@ -74,8 +74,7 @@
   <string name="filedetails_modified">Изменето:</string>
   <string name="filedetails_download">Преземање</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="action_share">Сподели</string>
   <string name="common_yes">Да</string>
   <string name="common_no">Не</string>
   <string name="common_ok">Во ред</string>
   <string name="auth_account_does_not_exist">Сметката сеуште не постои на овој уред</string>
   <string name="common_rename">Преименувај</string>
   <string name="common_remove">Отстрани</string>
-  <string name="confirmation_remove_alert">Дали навистина сакаш да ја отстраниш %1$s?</string>
+  <string name="confirmation_remove_file_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="auth_refresh_button">Освежи ја конекцијата</string>
   <string name="auth_host_address">Адреса на сервер</string>
   <string name="share_dialog_title">Споделување</string>
+  <string name="share_via_link_section_title">Сподели ја врската</string>
+  <string name="share_via_link_expiration_date_label">Постави рок на траење</string>
+  <string name="share_via_link_password_label">Заштити со лозинка</string>
   <string name="share_search">Барај</string>
 </resources>
index 50f7a44..9d18045 100644 (file)
@@ -14,6 +14,7 @@
   <string name="auth_password">Нууц үг</string>
   <string name="sync_string_files">Файлууд</string>
   <string name="uploader_btn_upload_text">Байршуулах</string>
+  <string name="action_share">Түгээх</string>
   <string name="create_account">Аккаунт үүсгэх</string>
   <string name="common_remove">Устгах</string>
   <string name="empty"></string>
index 910ed90..66752db 100644 (file)
@@ -38,6 +38,7 @@
   <string name="filedetails_created">Telah dibina:</string>
   <string name="filedetails_modified">Telah diubah:</string>
   <string name="filedetails_download">Muatturun</string>
+  <string name="action_share">Kongsi</string>
   <string name="common_yes">Ya</string>
   <string name="common_no">Tidak</string>
   <string name="common_ok">OK</string>
index 48cf4e1..943676d 100644 (file)
@@ -19,4 +19,5 @@
   <string name="common_cancel">ပယ်ဖျက်မည်</string>
   <string name="empty"></string>
   <string name="folder_picker_choose_button_text">ရွေးချယ်</string>
+  <string name="share_via_link_expiration_date_label">သက်တမ်းကုန်ဆုံးမည့်ရက်သတ်မှတ်မည်</string>
 </resources>
index ea48e25..8cc58e7 100644 (file)
@@ -81,8 +81,7 @@
   <string name="filedetails_download">Last ned</string>
   <string name="filedetails_renamed_in_upload_msg">Filnavnet ble endret til  %1$s under opplasting</string>
   <string name="list_layout">Listeoppsett</string>
-  <string name="action_share_file">Del lenke</string>
-  <string name="action_unshare_file">Avslutt deling av lenke</string>
+  <string name="action_share">Delt ressurs</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nei</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Fjern favoritt</string>
   <string name="common_rename">Endre navn</string>
   <string name="common_remove">Fjern</string>
-  <string name="confirmation_remove_alert">Vil du virkelig fjerne %1$s?</string>
+  <string name="confirmation_remove_file_alert">Vil du virkelig fjerne %1$s?</string>
   <string name="confirmation_remove_folder_alert">Vil du virkelig fjerne %1$s inkludert innholdet?</string>
   <string name="confirmation_remove_local">Kun lokalt</string>
   <string name="confirmation_remove_folder_local">Kun lokalt</string>
-  <string name="confirmation_remove_remote">Fra server</string>
+  <string name="confirmation_remove_file_remote">Fra server</string>
   <string name="confirmation_remove_remote_and_local">Ekstern &amp; lokal</string>
   <string name="remove_success_msg">Fjerning var vellykket</string>
   <string name="remove_fail_msg">Fjerning mislyktes</string>
   <string name="file_list__footer__files_and_folder">%1$d filer, 1 mappe</string>
   <string name="file_list__footer__files_and_folders">%1$d filer, %2$d mapper</string>
   <string name="share_dialog_title">Deling</string>
-  <string name="share_with_user_section_title">Del med brukere og grupper</string>
   <string name="share_no_users">Ingen data delt med brukere ennå</string>
   <string name="share_add_user_or_group">Legg til bruker eller gruppe</string>
+  <string name="share_via_link_section_title">Del lenke</string>
+  <string name="share_via_link_expiration_date_label">Sett utløpsdato</string>
+  <string name="share_via_link_password_label">Passordbeskyttet</string>
   <string name="share_search">Søk</string>
 </resources>
index 3cf1764..50ab415 100644 (file)
@@ -83,9 +83,7 @@ Download hier: %2$s</string>
   <string name="filedetails_sync_file">Synchroniseren</string>
   <string name="filedetails_renamed_in_upload_msg">Bestand is tijdens het uploaden hernoemd naar %1$s</string>
   <string name="list_layout">Lijst layout</string>
-  <string name="action_share_file">Deel link</string>
-  <string name="action_unshare_file">Link niet meer delen</string>
-  <string name="action_share_with_users">Delen met gebruiker</string>
+  <string name="action_share">Deel</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nee</string>
   <string name="common_ok">OK</string>
@@ -202,11 +200,11 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="unfavorite">Niet meer favoriet</string>
   <string name="common_rename">Hernoemen</string>
   <string name="common_remove">Verwijderen</string>
-  <string name="confirmation_remove_alert">Wilt u %1$s werkelijk verwijderen?</string>
+  <string name="confirmation_remove_file_alert">Wilt u %1$s werkelijk verwijderen?</string>
   <string name="confirmation_remove_folder_alert">Wilt u %1$s en de inhoud ervan werkelijk verwijderen?</string>
   <string name="confirmation_remove_local">Alleen lokaal</string>
   <string name="confirmation_remove_folder_local">Alleen lokaal</string>
-  <string name="confirmation_remove_remote">Van server</string>
+  <string name="confirmation_remove_file_remote">Van server</string>
   <string name="confirmation_remove_remote_and_local">Extern &amp; lokaal</string>
   <string name="remove_success_msg">Succesvol verwijderd</string>
   <string name="remove_fail_msg">Verwijdering kon niet voltooid worden</string>
@@ -340,9 +338,11 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
   <string name="file_list__footer__files_and_folder">%1$d bestanden, 1 map</string>
   <string name="file_list__footer__files_and_folders">%1$d bestanden, %2$d mappen</string>
   <string name="share_dialog_title">Delen</string>
-  <string name="share_with_user_section_title">Delen met gebruikers en groepen</string>
   <string name="share_no_users">Nog geen gegevens met gebruikers gedeeld</string>
   <string name="share_add_user_or_group">Toevoegen gebruiker of groep</string>
+  <string name="share_via_link_section_title">Deel link</string>
+  <string name="share_via_link_expiration_date_label">Stel vervaldatum in</string>
+  <string name="share_via_link_password_label">Wachtwoord beveiligd</string>
   <string name="share_search">Zoeken</string>
   <string name="search_users_and_groups_hint">Zoeken naar gebruikers en groepen</string>
   <string name="share_group_clarification">%1$s (groep)</string>
index aa846e3..6392a96 100644 (file)
@@ -58,7 +58,7 @@
   <string name="filedetails_created">Oppretta:</string>
   <string name="filedetails_modified">Endra:</string>
   <string name="filedetails_download">Last ned</string>
-  <string name="action_share_file">Del lenkje</string>
+  <string name="action_share">Del</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nei</string>
   <string name="common_ok">Greitt</string>
   <string name="prefs_category_security">Tryggleik</string>
   <string name="auth_host_address">Tenaradresse</string>
   <string name="share_dialog_title">Deling</string>
+  <string name="share_via_link_section_title">Del lenkje</string>
+  <string name="share_via_link_expiration_date_label">Set utløpsdato</string>
+  <string name="share_via_link_password_label">Passordvern</string>
   <string name="share_search">Søk</string>
 </resources>
index ce487e8..b06c6fe 100644 (file)
@@ -83,9 +83,7 @@ Telecargatz-lo aicí : %2$s</string>
   <string name="filedetails_sync_file">Sincronizar</string>
   <string name="filedetails_renamed_in_upload_msg">Lo fichièr es estat renomenat en %s pendent lo mandadís</string>
   <string name="list_layout">Afichatge en lista</string>
-  <string name="action_share_file">Partejar lo ligam</string>
-  <string name="action_unshare_file">Partejar pas mai aqueste ligam</string>
-  <string name="action_share_with_users">Partejar amb d\'Utilizaires</string>
+  <string name="action_share">Partejar</string>
   <string name="common_yes">Òc</string>
   <string name="common_no">Non</string>
   <string name="common_ok">D\'acòrdi</string>
@@ -204,11 +202,11 @@ En rason d\'aquesta modificacion, totes los fichièrs mandats amb de versions an
   <string name="unfavorite">Suprimir dels favorits</string>
   <string name="common_rename">Renomenar</string>
   <string name="common_remove">Suprimir</string>
-  <string name="confirmation_remove_alert">Sètz segur que volètz suprimir %1$s ?</string>
+  <string name="confirmation_remove_file_alert">Sètz segur que volètz suprimir %1$s ?</string>
   <string name="confirmation_remove_folder_alert">Sètz segur que volètz suprimir %1$s e son contengut ?</string>
   <string name="confirmation_remove_local">Local solament</string>
   <string name="confirmation_remove_folder_local">Local solament</string>
-  <string name="confirmation_remove_remote">Dempuèi lo servidor</string>
+  <string name="confirmation_remove_file_remote">Dempuèi lo servidor</string>
   <string name="confirmation_remove_remote_and_local">Distant &amp; local</string>
   <string name="remove_success_msg">Supression efectuada amb succès</string>
   <string name="remove_fail_msg">Supression impossibla</string>
@@ -338,9 +336,11 @@ En rason d\'aquesta modificacion, totes los fichièrs mandats amb de versions an
   <string name="file_list__footer__files_and_folder">%1$d fichièrs, 1 dorsièr</string>
   <string name="file_list__footer__files_and_folders">%1$d fichièrs, %2$d dorsièrs</string>
   <string name="share_dialog_title">Partiment</string>
-  <string name="share_with_user_section_title">Partejar amb d\'utilizaires e de gropes</string>
   <string name="share_no_users">Cap de donada es pas partejada amb d\'utilizaires pel moment</string>
   <string name="share_add_user_or_group">Apondre un utilizaire o un grop</string>
+  <string name="share_via_link_section_title">Partejar lo ligam</string>
+  <string name="share_via_link_expiration_date_label">Especificar una data d\'expiracion</string>
+  <string name="share_via_link_password_label">Protegir per un senhal</string>
   <string name="share_search">Recercar</string>
   <string name="search_users_and_groups_hint">Recercar d\'utilizaires e de gropes</string>
 </resources>
index 35a3769..bee8058 100644 (file)
@@ -40,6 +40,7 @@
   <string name="filedetails_created">ਬਣਾਈ:</string>
   <string name="filedetails_modified">ਸੋਧ ਕੀਤੀ:</string>
   <string name="filedetails_download">ਡਾਊਨਲੋਡ</string>
+  <string name="action_share">ਸਾਂਝਾ ਕਰੋ</string>
   <string name="common_yes">ਹਾਂ</string>
   <string name="common_no">ਨਹੀਂ</string>
   <string name="common_ok">ਠੀਕ ਹੈ</string>
index dbe2bd4..9d77e88 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Pobierz</string>
   <string name="filedetails_renamed_in_upload_msg">Podczas wysyłania nazwa pliku została zmieniona na %1$s</string>
   <string name="list_layout">Lista szablonów wyglądu</string>
-  <string name="action_share_file">Udostępnij link</string>
-  <string name="action_unshare_file">Anuluj udostępnianie</string>
+  <string name="action_share">Udostępnij</string>
   <string name="common_yes">Tak</string>
   <string name="common_no">Nie</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Usuń z ulubionych</string>
   <string name="common_rename">Zmień nazwę</string>
   <string name="common_remove">Usuń</string>
-  <string name="confirmation_remove_alert">Czy naprawdę chcesz usunąć %1$s?</string>
+  <string name="confirmation_remove_file_alert">Czy naprawdę chcesz usunąć %1$s?</string>
   <string name="confirmation_remove_folder_alert">Czy naprawdę chcesz usunąć %1$s i jego zawartość?</string>
   <string name="confirmation_remove_local">Tylko lokalnie</string>
   <string name="confirmation_remove_folder_local">Tylko lokalnie</string>
-  <string name="confirmation_remove_remote">Z serwera</string>
+  <string name="confirmation_remove_file_remote">Z serwera</string>
   <string name="remove_success_msg">Usunięto</string>
   <string name="remove_fail_msg">Nie można usunąć</string>
   <string name="rename_dialog_title">Wprowadź nową nazwę</string>
   <string name="file_list__footer__file">1 plik</string>
   <string name="file_list__footer__file_and_folder">1 plik , 1 folder</string>
   <string name="share_dialog_title">Udostępnianie</string>
+  <string name="share_via_link_section_title">Udostępnij link</string>
+  <string name="share_via_link_expiration_date_label">Ustaw datę wygaśnięcia</string>
+  <string name="share_via_link_password_label">Zabezpiecz hasłem</string>
   <string name="share_search">Wyszukaj</string>
 </resources>
index 573a57c..075acaf 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Sincronizar</string>
   <string name="filedetails_renamed_in_upload_msg">Arquivo foi renomeado para %1$s durante o envio</string>
   <string name="list_layout">Lista de Layout</string>
-  <string name="action_share_file">Compartilhar link</string>
-  <string name="action_unshare_file">Descompartilhar o link</string>
-  <string name="action_share_with_users">Compartilhado com usuários</string>
+  <string name="action_share">Compartilhar</string>
   <string name="common_yes">Sim</string>
   <string name="common_no">Não</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Nãofavorito</string>
   <string name="common_rename">Renomear</string>
   <string name="common_remove">Remover</string>
-  <string name="confirmation_remove_alert">Você realmente deseja remover %1$s?</string>
+  <string name="confirmation_remove_file_alert">Você realmente deseja remover %1$s?</string>
   <string name="confirmation_remove_folder_alert">Você realmente deseja remover %1$s e seus conteúdos?</string>
   <string name="confirmation_remove_local">Somente local</string>
   <string name="confirmation_remove_folder_local">Somente local</string>
-  <string name="confirmation_remove_remote">Do servidor</string>
+  <string name="confirmation_remove_file_remote">Do servidor</string>
   <string name="confirmation_remove_remote_and_local">Remoto &amp; local</string>
   <string name="remove_success_msg">Removido com sucesso</string>
   <string name="remove_fail_msg">Erro ao remover</string>
   <string name="file_list__footer__files_and_folder">%1$d arquivos, 1 pasta</string>
   <string name="file_list__footer__files_and_folders">%1$d arquivos, %2$d pastas</string>
   <string name="share_dialog_title">Compartilhamento</string>
-  <string name="share_with_user_section_title">Compartilhar com Usuários e Grupos</string>
   <string name="share_no_users">Ainda não existe nenhum dado compartilhado com usuários</string>
   <string name="share_add_user_or_group">Adicionar Usuário ou Grupo</string>
+  <string name="share_via_link_section_title">Compartilhar link</string>
+  <string name="share_via_link_expiration_date_label">Definir data de expiração</string>
+  <string name="share_via_link_password_label">Proteger com senha</string>
   <string name="share_search">Perquisar</string>
   <string name="search_users_and_groups_hint">Pesquisar usuários e grupos</string>
   <string name="share_group_clarification">%1$s (grupo)</string>
index 152a02c..7036724 100644 (file)
@@ -82,8 +82,7 @@
   <string name="filedetails_sync_file">Sincronizar</string>
   <string name="filedetails_renamed_in_upload_msg">O ficheiro foi renomeado para %1$s durante o envio.</string>
   <string name="list_layout">Apresentação da Lista</string>
-  <string name="action_share_file">Partilhar a hiperligação</string>
-  <string name="action_unshare_file">Cancelar partilha da hiperligação</string>
+  <string name="action_share">Compartilhar</string>
   <string name="common_yes">Sim</string>
   <string name="common_no">Não</string>
   <string name="common_ok">ACEITAR</string>
   <string name="unfavorite">Retirar Favorito</string>
   <string name="common_rename">Renomear</string>
   <string name="common_remove">Remover</string>
-  <string name="confirmation_remove_alert">Tem a certeza que deseja remover %1$s ?</string>
+  <string name="confirmation_remove_file_alert">Tem a certeza que deseja remover %1$s ?</string>
   <string name="confirmation_remove_folder_alert">Deseja realmente remover %1$s e o seu conteúdo?</string>
   <string name="confirmation_remove_local">Apenas localmente</string>
   <string name="confirmation_remove_folder_local">Apenas localmente</string>
-  <string name="confirmation_remove_remote">Do servidor</string>
+  <string name="confirmation_remove_file_remote">Do servidor</string>
   <string name="confirmation_remove_remote_and_local">Remoto &amp; local</string>
   <string name="remove_success_msg">Removido com sucesso</string>
   <string name="remove_fail_msg">Não foi possível remover</string>
   <string name="file_list__footer__files_and_folder">%1$d ficheiros, 1 pasta</string>
   <string name="file_list__footer__files_and_folders">%1$d ficheiros, %2$d pastas</string>
   <string name="share_dialog_title">Partilha</string>
-  <string name="share_with_user_section_title">Partilhar com Utilizadores e Grupos</string>
   <string name="share_no_users">Ainda não foram partilhados os dados com os utilizadores</string>
   <string name="share_add_user_or_group">Adicionar Utilziador ou Grupo</string>
+  <string name="share_via_link_section_title">Compartilhar hiperligação</string>
+  <string name="share_via_link_expiration_date_label">Definir a data de expiração</string>
+  <string name="share_via_link_password_label">Proteger com Palavra-passe</string>
   <string name="share_search">Procurar</string>
 </resources>
index a316005..040e114 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Descarcă</string>
   <string name="filedetails_renamed_in_upload_msg">Fișierul a fost redenumit %1$s în timpul încărcării</string>
   <string name="list_layout">Aspect listă</string>
-  <string name="action_share_file">Partajază legătură</string>
-  <string name="action_unshare_file">Departajează legătura</string>
+  <string name="action_share">Partajează</string>
   <string name="common_yes">Da</string>
   <string name="common_no">Nu</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Defavoritați</string>
   <string name="common_rename">Redenumește</string>
   <string name="common_remove">Elimină</string>
-  <string name="confirmation_remove_alert">Doriti sigur sa stergeti %1$s?</string>
+  <string name="confirmation_remove_file_alert">Doriti sigur sa stergeti %1$s?</string>
   <string name="confirmation_remove_folder_alert">Sigur vrei să elimini %1$s și conținutul său?</string>
   <string name="confirmation_remove_local">Doar local</string>
   <string name="confirmation_remove_folder_local">Doar local</string>
-  <string name="confirmation_remove_remote">De pe server</string>
+  <string name="confirmation_remove_file_remote">De pe server</string>
   <string name="confirmation_remove_remote_and_local">Ambele</string>
   <string name="remove_success_msg">Eliminat cu succes</string>
   <string name="remove_fail_msg">Eliminarea nu a reușit</string>
   <string name="file_list__footer__files_and_folder">%1$d fișiere, 1 folder</string>
   <string name="file_list__footer__files_and_folders">%1$d fișiere, %2$d foldere</string>
   <string name="share_dialog_title">Partajare</string>
+  <string name="share_via_link_section_title">Partajază legătură</string>
+  <string name="share_via_link_expiration_date_label">Specifică data expirării</string>
+  <string name="share_via_link_password_label">Protejare cu parolă</string>
   <string name="share_search">Căutare</string>
 </resources>
index 6675918..cfbee73 100644 (file)
   <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_file_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_file_remote">Удалить с сервера</string>
   <string name="confirmation_remove_remote_and_local">Оба, удаленный и локальный</string>
   <string name="remove_success_msg">Успешное удаление</string>
   <string name="remove_fail_msg">Удаление не может быть завершено</string>
index ce2f0b4..0b41683 100644 (file)
@@ -82,8 +82,7 @@
   <string name="filedetails_download">Скачать</string>
   <string name="filedetails_renamed_in_upload_msg">Файл был переименован в %1$s во время загрузки</string>
   <string name="list_layout">Макет списка</string>
-  <string name="action_share_file">Поделиться ссылкой</string>
-  <string name="action_unshare_file">Убрать ссылку</string>
+  <string name="action_share">Общий доступ</string>
   <string name="common_yes">Да</string>
   <string name="common_no">Нет</string>
   <string name="common_ok">ОК</string>
   <string name="unfavorite">Убрать из избранного</string>
   <string name="common_rename">Переименовать</string>
   <string name="common_remove">Удалить</string>
-  <string name="confirmation_remove_alert">Вы действительно хотите удалить %1$s?</string>
+  <string name="confirmation_remove_file_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="file_list__footer__files_and_folder">%1$d файлов, 1 каталог</string>
   <string name="file_list__footer__files_and_folders">%1$d файлов, %2$d каталогов</string>
   <string name="share_dialog_title">Общий доступ</string>
-  <string name="share_with_user_section_title">Поделиться с пользователями или группами</string>
   <string name="share_no_users">Нет данных используемых совместно с другими пользователями</string>
   <string name="share_add_user_or_group">Добавить пользователя или группу</string>
+  <string name="share_via_link_section_title">Поделиться ссылкой</string>
+  <string name="share_via_link_expiration_date_label">Установить срок действия</string>
+  <string name="share_via_link_password_label">Защитить паролем</string>
   <string name="share_search">Найти</string>
 </resources>
index 7ecb8cc..2531d9b 100644 (file)
@@ -33,6 +33,7 @@
   <string name="filedetails_created">සෑදු දිනය:</string>
   <string name="filedetails_modified">වෙනස් කළ දිනය:</string>
   <string name="filedetails_download">භාගත කරන්න</string>
+  <string name="action_share">බෙදා හදා ගන්න</string>
   <string name="common_yes">ඔව්</string>
   <string name="common_no">එපා</string>
   <string name="common_ok">හරි</string>
@@ -79,5 +80,7 @@
   <string name="folder_picker_choose_button_text">තෝරන්න</string>
   <string name="auth_host_address">සේවාදායකයේ ලිපිනය</string>
   <string name="share_dialog_title">හුවමාරු කිරීම</string>
+  <string name="share_via_link_expiration_date_label">කල් ඉකුත් විමේ දිනය දමන්න</string>
+  <string name="share_via_link_password_label">මුර පදයකින් ආරක්ශාකරන්න</string>
   <string name="share_search">සොයන්න</string>
 </resources>
index 538d272..5d9f412 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Synchronizovať</string>
   <string name="filedetails_renamed_in_upload_msg">Súbor bol premenovaný na %1$s počas nahrávania</string>
   <string name="list_layout">Rozvrhnutie zoznamu</string>
-  <string name="action_share_file">Zdieľať linku</string>
-  <string name="action_unshare_file">Zrušiť zdieľanie odkazu</string>
-  <string name="action_share_with_users">Zdieľať s používateľmi</string>
+  <string name="action_share">Zdieľať</string>
   <string name="common_yes">Áno</string>
   <string name="common_no">Nie</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Odobrať z obľúbených</string>
   <string name="common_rename">Premenuj</string>
   <string name="common_remove">Odober</string>
-  <string name="confirmation_remove_alert">Naozaj chcete odstrániť %1$s?</string>
+  <string name="confirmation_remove_file_alert">Naozaj chcete odstrániť %1$s?</string>
   <string name="confirmation_remove_folder_alert">Naozaj chcete odstrániť %1$s a jeho obsah?</string>
   <string name="confirmation_remove_local">Iba lokálne</string>
   <string name="confirmation_remove_folder_local">Iba lokálne</string>
-  <string name="confirmation_remove_remote">Zo servera</string>
+  <string name="confirmation_remove_file_remote">Zo servera</string>
   <string name="confirmation_remove_remote_and_local">Vzdialene aj lokálne</string>
   <string name="remove_success_msg">Úspešne odstránené</string>
   <string name="remove_fail_msg">Odstránenie zlyhalo</string>
   <string name="file_list__footer__files_and_folder">%1$d súb., 1 priečinok</string>
   <string name="file_list__footer__files_and_folders">%1$d súb., %2$d prieč.</string>
   <string name="share_dialog_title">Zdieľanie</string>
-  <string name="share_with_user_section_title">Zdieľať s používateľmi alebo skupinami</string>
   <string name="share_no_users">Zatiaľ s používateľmi nezdieľate žiadne dáta.</string>
   <string name="share_add_user_or_group">Pridať používateľa alebo skupinu</string>
+  <string name="share_via_link_section_title">Zdieľať linku</string>
+  <string name="share_via_link_expiration_date_label">Nastaviť dátum expirácie</string>
+  <string name="share_via_link_password_label">Chrániť heslom</string>
   <string name="share_search">Hľadať</string>
   <string name="search_users_and_groups_hint">Vyhľadať používateľov alebo skupiny</string>
   <string name="share_group_clarification">%1$s (skupina)</string>
index 54c8ef1..ca340d2 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Prejmi</string>
   <string name="filedetails_renamed_in_upload_msg">Datoteka je bila med nalaganjem preimenovana v %1$s</string>
   <string name="list_layout">Postavitev seznama</string>
-  <string name="action_share_file">Povezava za souporabo</string>
-  <string name="action_unshare_file">Odstrani možnost souporabe</string>
+  <string name="action_share">Souporaba</string>
   <string name="common_yes">Da</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">V redu</string>
   <string name="unfavorite">Odstrani priljubljeno</string>
   <string name="common_rename">Preimenuj</string>
   <string name="common_remove">Odstrani</string>
-  <string name="confirmation_remove_alert">Ali res želite odstraniti %1$s?</string>
+  <string name="confirmation_remove_file_alert">Ali res želite odstraniti %1$s?</string>
   <string name="confirmation_remove_folder_alert">Ali res želite odstraniti %1$s skupaj s celotno vsebino?</string>
   <string name="confirmation_remove_local">Le krajevno</string>
   <string name="confirmation_remove_folder_local">Le krajevno</string>
-  <string name="confirmation_remove_remote">S strežnika</string>
+  <string name="confirmation_remove_file_remote">S strežnika</string>
   <string name="confirmation_remove_remote_and_local">Oddaljeno &amp; krajevno</string>
   <string name="remove_success_msg">Odstranitev je uspešno končana</string>
   <string name="remove_fail_msg">Odstranjevanje je spodletelo</string>
   <string name="file_list__footer__files_and_folder">%1$d datotek, 1 mapa</string>
   <string name="file_list__footer__files_and_folders">%1$d datotek, %2$d map</string>
   <string name="share_dialog_title">Souporaba</string>
+  <string name="share_via_link_section_title">Povezava za souporabo</string>
+  <string name="share_via_link_expiration_date_label">Nastavi datum preteka</string>
+  <string name="share_via_link_password_label">Zaščiti z geslom</string>
   <string name="share_search">Poišči</string>
 </resources>
index c4a9dec..3bb0088 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">Njëkohëso</string>
   <string name="filedetails_renamed_in_upload_msg">Kartela u riemërtua si %1$s gjatë ngarkimit</string>
   <string name="list_layout">Skemë Liste</string>
-  <string name="action_share_file">Ndajeni lidhjen me të tjerët</string>
-  <string name="action_unshare_file">Zhbëjeni ndarjen e lidhjes me të tjerët</string>
-  <string name="action_share_with_users">Ndajeni me përdoruesit</string>
+  <string name="action_share">Ndaje</string>
   <string name="common_yes">Po</string>
   <string name="common_no">Jo</string>
   <string name="common_ok">OK</string>
   <string name="share_link_file_error">Ndodhi një gabim teksa përpiqej të ndahej me të tjerët kjo kartelë apo dosje</string>
   <string name="unshare_link_file_no_exist">S\’arrin të zhbëjë ndarjen me të tjerët. Ju lutemi, kontrolloni nëse kartela ekziston</string>
   <string name="unshare_link_file_error">Ndodhi një gabim teksa përpiqej të zhbëhej ndarja me të tjerët e kësaj kartele apo dosjeje</string>
+  <string name="update_link_file_no_exist">S’u arrit të përditësohej gjë. Ju lutemi, kontrolloni nëse ekziston apo jo kartela.</string>
+  <string name="update_link_file_error">Ndodhi një gabim teksa provohej të përditësohej lidhja e ndarë me të tjerët</string>
   <string name="share_link_password_title">Jepni një fjalëkalim</string>
   <string name="share_link_empty_password">Duhet të jepni një fjalëkalim</string>
   <string name="activity_chooser_send_file_title">Dërgoje</string>
   <string name="forbidden_permissions_delete">për fshirje të kësaj kartele</string>
   <string name="share_link_forbidden_permissions">për ndarje me të tjerët të kësaj kartele</string>
   <string name="unshare_link_forbidden_permissions">për zhbërje të ndarjes me të tjerët të kësaj kartele</string>
+  <string name="update_link_forbidden_permissions">që të përditësohet kjo lidhje e ndarë me të tjerët</string>
   <string name="forbidden_permissions_create">për krijim kartele</string>
   <string name="uploader_upload_forbidden_permissions">për ngarkim në këtë dosje</string>
   <string name="downloader_download_file_not_found">Kartela s\’gjendet më te shërbyesi</string>
   <string name="file_list__footer__files_and_folder">%1$d kartela, 1 dosje</string>
   <string name="file_list__footer__files_and_folders">%1$d kartela, %2$d dosje</string>
   <string name="share_dialog_title">Ndarje me të tjerët</string>
-  <string name="share_with_user_section_title">Ndani me Përdorues dhe Grupe</string>
+  <string name="share_with_user_section_title">Ndajeni me përdorues dhe grupe</string>
   <string name="share_no_users">Ende pa të dhëna të ndara me përdorues</string>
   <string name="share_add_user_or_group">Shtoni Përdorues ose Grup</string>
+  <string name="share_via_link_section_title">Lidhje ndarjeje</string>
+  <string name="share_via_link_expiration_date_label">Caktoni datë skadimi</string>
+  <string name="share_via_link_password_label">Mbroje me fjalëkalim</string>
+  <string name="share_via_link_password_title">E siguruar</string>
+  <string name="share_get_public_link_button">Merreni lidhjen</string>
   <string name="share_search">Kërko</string>
   <string name="search_users_and_groups_hint">Kërkoni për grupe dhe përdorues</string>
   <string name="share_group_clarification">%1$s (grup)</string>
index cde6c3d..9b967f9 100644 (file)
@@ -30,7 +30,7 @@
   <string name="filedetails_size">Veličina:</string>
   <string name="filedetails_type">Tip:</string>
   <string name="filedetails_download">Preuzmi</string>
-  <string name="action_share_file">Podeli prečicu</string>
+  <string name="action_share">Deljenje</string>
   <string name="common_yes">Da</string>
   <string name="common_no">Ne</string>
   <string name="common_ok">Ok</string>
@@ -72,5 +72,8 @@
   <string name="empty"></string>
   <string name="prefs_category_accounts">Nalozi</string>
   <string name="folder_picker_choose_button_text">Izaberi</string>
+  <string name="share_via_link_section_title">Veza deljenja</string>
+  <string name="share_via_link_expiration_date_label">Datum isteka</string>
+  <string name="share_via_link_password_label">Zaštita lozinkom</string>
   <string name="share_search">Traži</string>
 </resources>
index 74f0bf0..c20addc 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">Преузми</string>
   <string name="filedetails_renamed_in_upload_msg">Фајл је преименован у %1$s током отпремања</string>
   <string name="list_layout">Распоред листе</string>
-  <string name="action_share_file">Веза дељења</string>
-  <string name="action_unshare_file">Не дели везом</string>
+  <string name="action_share">Дељење</string>
   <string name="common_yes">Да</string>
   <string name="common_no">Не</string>
   <string name="common_ok">У реду</string>
   <string name="unfavorite">Неомиљени</string>
   <string name="common_rename">Преименуј</string>
   <string name="common_remove">Уклони</string>
-  <string name="confirmation_remove_alert">Желите да уклоните %1$s?</string>
+  <string name="confirmation_remove_file_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="file_list__footer__files_and_folder">%1$d фајлова, 1 фасцикла</string>
   <string name="file_list__footer__files_and_folders">%1$d фајлова, %2$d фасцикли</string>
   <string name="share_dialog_title">Дељење</string>
+  <string name="share_via_link_section_title">Веза дељења</string>
+  <string name="share_via_link_expiration_date_label">Постави датум истека</string>
+  <string name="share_via_link_password_label">Заштићено лозинком</string>
   <string name="share_search">Тражи</string>
 </resources>
index 1a00e96..29bf4a2 100644 (file)
@@ -73,8 +73,7 @@
   <string name="filedetails_modified">Ändrad:</string>
   <string name="filedetails_download">Ladda ner</string>
   <string name="filedetails_renamed_in_upload_msg">Filen bytte namn till %1$s under uppladdningen</string>
-  <string name="action_share_file">Dela länk</string>
-  <string name="action_unshare_file">Sluta dela länk</string>
+  <string name="action_share">Dela</string>
   <string name="common_yes">Ja</string>
   <string name="common_no">Nej</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Avfavoritisera</string>
   <string name="common_rename">Byt namn</string>
   <string name="common_remove">Radera</string>
-  <string name="confirmation_remove_alert">Vill du verkligen ta bort %1$s?</string>
+  <string name="confirmation_remove_file_alert">Vill du verkligen ta bort %1$s?</string>
   <string name="confirmation_remove_folder_alert">Vill du verkligen ta bort %1$s och dess innehåll?</string>
   <string name="confirmation_remove_local">Endast lokalt</string>
   <string name="confirmation_remove_folder_local">Endast lokalt</string>
   <string name="subject_user_shared_with_you">%1$s delade \"%2$s\" med dig</string>
   <string name="auth_host_address">Serveradress</string>
   <string name="share_dialog_title">Dela</string>
+  <string name="share_via_link_section_title">Dela länk</string>
+  <string name="share_via_link_expiration_date_label">Sätt utgångsdatum</string>
+  <string name="share_via_link_password_label">Lösenordsskydda</string>
   <string name="share_search">Sök</string>
 </resources>
index 1937439..43b6e82 100644 (file)
@@ -39,6 +39,7 @@
   <string name="filedetails_modified">மாற்றப்பட்டது:</string>
   <string name="filedetails_download">பதிவிறக்குக</string>
   <string name="filedetails_renamed_in_upload_msg">பதிவேற்றும்போது கோப்பின் பெயரானது %1$s ஆக பெயர்மாற்றப்பட்டது</string>
+  <string name="action_share">பகிர்வு</string>
   <string name="common_yes">ஆம்</string>
   <string name="common_no">இல்லை</string>
   <string name="common_ok">சரி </string>
   <string name="prefs_category_accounts">கணக்குகள்</string>
   <string name="folder_picker_choose_button_text">தெரிவுசெய்க </string>
   <string name="auth_host_address">சேவையக முகவரி</string>
+  <string name="share_via_link_expiration_date_label">காலாவதி தேதியை குறிப்பிடுக</string>
+  <string name="share_via_link_password_label">கடவுச்சொல்லை பாதுகாத்தல்</string>
   <string name="share_search">தேடுதல்</string>
 </resources>
index aab35a2..c54b083 100644 (file)
@@ -82,9 +82,7 @@
   <string name="filedetails_sync_file">ประสานข้อมูล</string>
   <string name="filedetails_renamed_in_upload_msg">ไฟล์ได้ถูกเปลี่ยนชื่อเป็น %1$s ในระหว่างการอัพโหลด</string>
   <string name="list_layout">เค้าโครงรายการ</string>
-  <string name="action_share_file">แชร์ลิงค์</string>
-  <string name="action_unshare_file">ยกเลิกการแชร์ลิงค์</string>
-  <string name="action_share_with_users">แชร์กับผู้ใช้</string>
+  <string name="action_share">แชร์</string>
   <string name="common_yes">ตกลง</string>
   <string name="common_no">ไม่ตกลง</string>
   <string name="common_ok">ตกลง</string>
   <string name="unfavorite">ออกจากรายการโปรด</string>
   <string name="common_rename">เปลี่ยนชื่อ</string>
   <string name="common_remove">ลบออก</string>
-  <string name="confirmation_remove_alert">คุณต้องการที่จะลบ %1$s?</string>
+  <string name="confirmation_remove_file_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="forbidden_permissions_delete">เพื่อลบไฟล์นี้</string>
   <string name="share_link_forbidden_permissions">เพื่อแชร์ไฟล์นี้</string>
   <string name="unshare_link_forbidden_permissions">เพื่อเลิกแชร์ไฟล์นี้</string>
+  <string name="update_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="file_list__footer__files_and_folder">%1$d ไฟล์, 1 โฟลเดอร์</string>
   <string name="file_list__footer__files_and_folders">%1$d ไฟล์, %2$d โฟลเดอร์</string>
   <string name="share_dialog_title">การแชร์ข้อมูล</string>
-  <string name="share_with_user_section_title">à¹\81à¸\8aรà¹\8cà¹\84à¸\9bยัà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89หรือกลุ่ม</string>
+  <string name="share_with_user_section_title">à¹\81à¸\8aรà¹\8cà¸\81ัà¸\9aà¸\9cูà¹\89à¹\83à¸\8aà¹\89à¹\81ละกลุ่ม</string>
   <string name="share_no_users">ยังไม่มีข้อมูลที่แชร์กับผู้ใช้ในตอนนี้</string>
   <string name="share_add_user_or_group">เพิ่มผู้ใช่หรือกลุ่ม</string>
+  <string name="share_via_link_section_title">แชร์ลิงค์</string>
+  <string name="share_via_link_expiration_date_label">กำหนดวันที่หมดอายุ</string>
+  <string name="share_via_link_password_label">รหัสผ่านป้องกัน</string>
+  <string name="share_via_link_password_title">ความปลอดภัย</string>
+  <string name="share_get_public_link_button">รับลิงค์</string>
   <string name="share_search">ค้นหา</string>
   <string name="search_users_and_groups_hint">ค้นหาผู้ใช้และกลุ่ม</string>
   <string name="share_group_clarification">%1$s (กลุ่ม)</string>
index 0eaaba1..bad3ccc 100644 (file)
@@ -71,6 +71,7 @@
   <string name="file_list_seconds_ago">saniyeler önce</string>
   <string name="file_list_empty">Burada hiçbir şey yok. Bir şeyler yükleyin!</string>
   <string name="file_list_loading">Yükleniyor...</string>
+  <string name="file_list_no_app_for_file_type">Dosya tipi için uygulama bulunamadı!</string>
   <string name="local_file_list_empty">Bu klasörde dosya yok.</string>
   <string name="filedetails_select_file">Ek bilgileri görmek için dosyaya dokunun.</string>
   <string name="filedetails_size">Boyut:</string>
   <string name="filedetails_created">Oluşturulma:</string>
   <string name="filedetails_modified">Değiştirilme:</string>
   <string name="filedetails_download">İndir</string>
+  <string name="filedetails_sync_file">Eşitleme</string>
   <string name="filedetails_renamed_in_upload_msg">Dosya adı, yükleme sırasında %1$s olarak değiştirildi</string>
   <string name="list_layout">Liste Yerleşimi</string>
-  <string name="action_share_file">Paylaşma bağlantısı</string>
-  <string name="action_unshare_file">Bağlantı paylaşımını kaldır</string>
+  <string name="action_share">Paylaş</string>
   <string name="common_yes">Evet</string>
   <string name="common_no">Hayır</string>
   <string name="common_ok">Tamam</string>
+  <string name="common_cancel_sync">Eşitlemeyi iptal et</string>
   <string name="common_cancel">İptal</string>
   <string name="common_save_exit">Kaydet ve Çık</string>
   <string name="common_error">Hata</string>
   <string name="unfavorite">Favoriden kaldır</string>
   <string name="common_rename">Yeniden adlandır</string>
   <string name="common_remove">Kaldır</string>
-  <string name="confirmation_remove_alert">Gerçekten %1$s dosyasını kaldırmak istiyor musunuz?</string>
+  <string name="confirmation_remove_file_alert">Gerçekten %1$s dosyasını kaldırmak istiyor musunuz?</string>
   <string name="confirmation_remove_folder_alert">Gerçekten %1$s ve içeriğini kaldırmak istediğinizden emin misiniz?</string>
   <string name="confirmation_remove_local">Sadece yerel</string>
   <string name="confirmation_remove_folder_local">Sadece yerel</string>
-  <string name="confirmation_remove_remote">Sunucudan</string>
+  <string name="confirmation_remove_file_remote">Sunucudan</string>
   <string name="confirmation_remove_remote_and_local">Uzak ve yerel</string>
   <string name="remove_success_msg">Kaldırma başarılı</string>
   <string name="remove_fail_msg">Kaldırma başarısız</string>
   <string name="ssl_validator_label_validity_to">Bitiş:</string>
   <string name="ssl_validator_label_signature">İmza:</string>
   <string name="ssl_validator_label_signature_algorithm">Algoritma:</string>
+  <string name="digest_algorithm_not_available">Özümlenen algoritma telefonunuz için mevcut değil</string>
+  <string name="ssl_validator_label_certificate_fingerprint">Parmak izi:</string>
+  <string name="certificate_load_problem">Sertifika yüklemesinde problem var.</string>
   <string name="ssl_validator_null_cert">Sertifika gösterilemedi.</string>
   <string name="ssl_validator_no_info_about_error">- Hata hakkında bilgi yok</string>
   <string name="placeholder_sentence">Bu bir yer tutucudur</string>
   <string name="prefs_category_instant_uploading">Anında Yüklemeler</string>
   <string name="prefs_category_security">Güvenlik</string>
   <string name="prefs_instant_video_upload_path_title">Video Yükleme Yolu</string>
+  <string name="sync_folder_failed_content">%1$s klasörünün eşitlemesi tamamlanamadı</string>
   <string name="shared_subject_header">sizinle</string>
   <string name="with_you_subject_header">paylaştı</string>
   <string name="subject_user_shared_with_you">%1$s, sizinle \"%2$s\" paylaşımını yaptı</string>
   <string name="file_list__footer__files_and_folder">%1$d dosya, 1 klasör</string>
   <string name="file_list__footer__files_and_folders">%1$d dosya, %2$d klasör</string>
   <string name="share_dialog_title">Paylaşım</string>
+  <string name="share_no_users">Henüz kullanıcılara paylaşılan veri yok</string>
+  <string name="share_add_user_or_group">Kullanıcı veya Grup ekle</string>
+  <string name="share_via_link_section_title">Paylaşma bağlantısı</string>
+  <string name="share_via_link_expiration_date_label">Son kullanma tarihini ayarla</string>
+  <string name="share_via_link_password_label">Parola koruması</string>
   <string name="share_search">Ara</string>
+  <string name="search_users_and_groups_hint">Kullanıcı ve Grupları Ara</string>
+  <string name="share_group_clarification">%1$s (grup)</string>
+  <string name="share_sharee_unavailable">Üzgünüz sunucu versiyonunuz istemcilerdeki kullanıcılara paylaşıma izin vermiyor.
+\nLütfen yöneticinize başvurun</string>
 </resources>
diff --git a/res/values-tzl/strings.xml b/res/values-tzl/strings.xml
deleted file mode 100644 (file)
index 37e6152..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<resources>
-  <!--TODO re-enable when server-side folder size calculation is available   
-       <item>Biggest - Smallest</item>-->
-  <!--TODO re-enable when "Accounts" is available in Navigation Drawer-->
-  <!--<string name="drawer_item_accounts">Accounts</string>-->
-  <!--TODO re-enable when "On Device" is available
-    <string name="drawer_item_on_device">On device</string>-->
-  <string name="empty"></string>
-</resources>
index 7d64b16..bd4ba67 100644 (file)
@@ -33,6 +33,7 @@
   <string name="filedetails_created">قۇرۇلغان ۋاقتى:</string>
   <string name="filedetails_modified">ئۆزگەرتكەن ۋاقىت:</string>
   <string name="filedetails_download">چۈشۈر</string>
+  <string name="action_share">ھەمبەھىر</string>
   <string name="common_yes">ھەئە</string>
   <string name="common_no">ياق</string>
   <string name="common_ok">جەزملە</string>
index eecba28..37b26e0 100644 (file)
@@ -81,8 +81,7 @@
   <string name="filedetails_download">Завантажити</string>
   <string name="filedetails_renamed_in_upload_msg">Файл був переіменований в %1$s протягом вивантаження</string>
   <string name="list_layout">Вигляд списку</string>
-  <string name="action_share_file">Опублікувати посилання</string>
-  <string name="action_unshare_file">Видалити посилання</string>
+  <string name="action_share">Поділитися</string>
   <string name="common_yes">Так</string>
   <string name="common_no">Ні</string>
   <string name="common_ok">OK</string>
   <string name="unfavorite">Прибрати з вибраного</string>
   <string name="common_rename">Перейменувати</string>
   <string name="common_remove">Видалити</string>
-  <string name="confirmation_remove_alert">Ви дійсно бажаєте видалити %1$s?</string>
+  <string name="confirmation_remove_file_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="file_list__footer__files_and_folder">%1$d файлів, 1 тека</string>
   <string name="file_list__footer__files_and_folders">%1$d файлів, %2$d тек</string>
   <string name="share_dialog_title">Спільний доступ</string>
+  <string name="share_via_link_section_title">Поділитись посиланням</string>
+  <string name="share_via_link_expiration_date_label">Встановити термін дії</string>
+  <string name="share_via_link_password_label">Захистити паролем</string>
   <string name="share_search">Пошук</string>
 </resources>
index 111a866..2e39141 100644 (file)
@@ -16,7 +16,7 @@
   <string name="setup_btn_connect">منسلک</string>
   <string name="file_list_seconds_ago">سیکنڈز پہلے</string>
   <string name="filedetails_download">ڈاؤن لوڈ،</string>
-  <string name="action_share_file">اشتراک لنک</string>
+  <string name="action_share">اشتراک</string>
   <string name="common_yes">ہاں</string>
   <string name="common_no">نہیں</string>
   <string name="common_ok">اوکے</string>
@@ -26,5 +26,8 @@
   <string name="activity_chooser_send_file_title">بھجیں</string>
   <string name="empty"></string>
   <string name="folder_picker_choose_button_text">منتخب کریں</string>
+  <string name="share_via_link_section_title">اشتراک لنک</string>
+  <string name="share_via_link_expiration_date_label">تاریخ معیاد سیٹ کریں</string>
+  <string name="share_via_link_password_label">محفوظ پاسورڈ</string>
   <string name="share_search">تلاش</string>
 </resources>
index 6ec7515..e6482b4 100644 (file)
@@ -58,8 +58,7 @@
   <string name="filedetails_modified">Đã chỉnh sửa:</string>
   <string name="filedetails_download">Tải về</string>
   <string name="filedetails_renamed_in_upload_msg">Tập tin đã bị đổi tên thành %1$s trong quá trình tải lên</string>
-  <string name="action_share_file">Chia sẻ liên kết</string>
-  <string name="action_unshare_file">Liên kết không chia sẻ</string>
+  <string name="action_share">Chia sẻ</string>
   <string name="common_yes">Yes</string>
   <string name="common_no">Không</string>
   <string name="common_ok">Chấp nhận</string>
   <string name="folder_picker_choose_button_text">Chọn</string>
   <string name="auth_host_address">Địa chỉ máy chủ</string>
   <string name="share_dialog_title">Chia sẻ</string>
+  <string name="share_via_link_section_title">Chia sẻ liên kết</string>
+  <string name="share_via_link_expiration_date_label">Đặt ngày kết thúc</string>
+  <string name="share_via_link_password_label">Mật khẩu bảo vệ</string>
   <string name="share_search">Tìm kiếm</string>
 </resources>
index 85a30ce..25ca1f9 100644 (file)
@@ -81,8 +81,7 @@
   <string name="filedetails_download">下载</string>
   <string name="filedetails_renamed_in_upload_msg">上传过程中文件被更名为了 %1$s</string>
   <string name="list_layout">列表布局</string>
-  <string name="action_share_file">分享链接</string>
-  <string name="action_unshare_file">取消分享链接</string>
+  <string name="action_share">共享</string>
   <string name="common_yes">是</string>
   <string name="common_no">否</string>
   <string name="common_ok">确定</string>
   <string name="unfavorite">取消收藏</string>
   <string name="common_rename">重命名</string>
   <string name="common_remove">删除</string>
-  <string name="confirmation_remove_alert">你确定要删除 %1$s 吗?</string>
+  <string name="confirmation_remove_file_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_file_remote">来自服务器</string>
   <string name="confirmation_remove_remote_and_local">远程 &amp; 本地</string>
   <string name="remove_success_msg">成功删除</string>
   <string name="remove_fail_msg">无法完成删除</string>
   <string name="file_list__footer__files_and_folder">%1$d 个文件,1 个文件夹</string>
   <string name="file_list__footer__files_and_folders">%1$d 个文件,%2$d 个文件夹</string>
   <string name="share_dialog_title">共享</string>
+  <string name="share_via_link_section_title">分享链接</string>
+  <string name="share_via_link_expiration_date_label">设置过期日期</string>
+  <string name="share_via_link_password_label">密码保护</string>
   <string name="share_search">搜索</string>
 </resources>
index 50f708a..aba6546 100644 (file)
@@ -38,8 +38,7 @@
   <string name="filedetails_created">建立時間:</string>
   <string name="filedetails_modified">修改時間:</string>
   <string name="filedetails_download">下載</string>
-  <string name="action_share_file">分享連結</string>
-  <string name="action_unshare_file">取消分享連結</string>
+  <string name="action_share">分享</string>
   <string name="common_yes">是</string>
   <string name="common_no">否</string>
   <string name="common_ok">確定</string>
@@ -78,5 +77,8 @@
   <string name="prefs_category_security">安全</string>
   <string name="auth_host_address">伺服器地址</string>
   <string name="share_dialog_title">分享</string>
+  <string name="share_via_link_section_title">分享連結</string>
+  <string name="share_via_link_expiration_date_label">設定分享期限</string>
+  <string name="share_via_link_password_label">密碼保護</string>
   <string name="share_search">尋找</string>
 </resources>
index 819568b..7b0ec25 100644 (file)
@@ -80,8 +80,7 @@
   <string name="filedetails_download">下載</string>
   <string name="filedetails_renamed_in_upload_msg">檔案名稱在上傳時已被更改為 %1$s</string>
   <string name="list_layout">列表版型</string>
-  <string name="action_share_file">分享連結</string>
-  <string name="action_unshare_file">取消共享連結</string>
+  <string name="action_share">分享</string>
   <string name="common_yes">是</string>
   <string name="common_no">否</string>
   <string name="common_ok">好</string>
   <string name="unfavorite">不喜愛的</string>
   <string name="common_rename">重新命名</string>
   <string name="common_remove">移除</string>
-  <string name="confirmation_remove_alert">您真的要移除 %1$s ?</string>
+  <string name="confirmation_remove_file_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_file_remote">來自伺服器</string>
   <string name="confirmation_remove_remote_and_local">遠端 &amp; 本地</string>
   <string name="remove_success_msg">成功地移除</string>
   <string name="remove_fail_msg">刪除失敗</string>
   <string name="file_list__footer__files_and_folder">%1$d 個檔案, 1 個資料夾</string>
   <string name="file_list__footer__files_and_folders">%1$d 個檔案, %2$d 個資料夾</string>
   <string name="share_dialog_title">分享</string>
-  <string name="share_with_user_section_title">與用戶或群組分享</string>
   <string name="share_no_users">目前沒有任何您分享的內容</string>
   <string name="share_add_user_or_group">新增使用者或是群組</string>
+  <string name="share_via_link_section_title">分享連結</string>
+  <string name="share_via_link_expiration_date_label">指定到期日</string>
+  <string name="share_via_link_password_label">密碼保護</string>
   <string name="share_search">搜尋</string>
 </resources>
index 800a4b6..7d80983 100644 (file)
 
        </declare-styleable>
 
+       <string-array name="pref_behaviour_entries">
+               <item>@string/pref_behaviour_entries_do_nothing</item>
+               <item>@string/pref_behaviour_entries_copy</item>
+               <item>@string/pref_behaviour_entries_move</item>
+               <item>@string/pref_behaviour_entries_delete</item>
+       </string-array>
+
+       <string-array name="pref_behaviour_entryValues">
+               <item>NOTHING</item>
+               <item>COPY</item>
+               <item>MOVE</item>
+               <item>DELETE</item>
+       </string-array>
 </resources>
\ No newline at end of file
index a138288..694e231 100644 (file)
     <color name="owncloud_blue_accent">#35537A</color>
     <color name="owncloud_blue_bright">#00ddff</color>
 
-    <color name="list_item_lastmod_and_filesize_text">#989898</color>
+    <color name="list_item_lastmod_and_filesize_text">@color/secondaryTextColor</color>
     <color name="black">#000000</color>
     <color name="white">#FFFFFF</color>
-    <color name="textColor">#303030</color>
+    <color name="fab_white">#fafafa</color>
+    <color name="white_pressed">#f1f1f1</color>
+    <color name="half_black">#808080</color>
+    <color name="black_semi_transparent">#B2000000</color>
+    <color name="textColor">@color/black</color>
     <color name="drawerMenuTextColor">#000000</color>
     <color name="list_divider_background">#eee</color>
     <color name="filelist_icon_backgorund">#DDDDDD</color>
@@ -36,6 +40,9 @@
     <color name="primary_button_color">@color/owncloud_blue_accent</color>
     <color name="secondary_button_color">#D6D7D7</color>
     <color name="transparent">#00000000</color>
+    <color name="secondaryTextColor">#a0a0a0</color>
+    <color name="listItemHighlighted">#f8f8f8</color>
+    <color name="highlightTextColor">#55739a</color>
 
     <!-- Colors -->
     <color name="color_accent">@color/owncloud_blue_accent</color>
index 287eb69..f47df78 100644 (file)
@@ -23,7 +23,7 @@
         <!--TODO re-enable when "Accounts" is available in Navigation Drawer-->
         <!--<item>@string/prefs_accounts</item>-->
         <item>@string/drawer_item_all_files</item>
-        <!--<item>@string/drawer_item_on_device</item>-->
+        <item>@string/drawer_item_on_device</item>
         <item>@string/actionbar_settings</item>
         <item>@string/actionbar_logger</item>
     </string-array>
@@ -33,7 +33,7 @@
         <!-- TODO re-enable when "Accounts" is available in Navigation Drawer-->
         <!--<item>@string/drawer_item_accounts</item>-->
         <item>@string/drawer_item_all_files</item>
-        <!--<item>@string/drawer_item_on_device</item>-->
+        <item>@string/drawer_item_on_device</item>
         <item>@string/drawer_item_settings</item>
         <item>@string/drawer_item_logs</item>
     </string-array>
index f10a3b7..b23f7b1 100644 (file)
@@ -1,14 +1,15 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
     <!-- App name  and other strings-->
-    <string name="app_name">ownCloud</string>
-    <string name="account_type">owncloud</string>      <!-- better if was a domain name; but changing it now would require migrate accounts when the app is updated -->
-    <string name="authority">org.owncloud</string>     <!-- better if was the app package with ".provider" appended ; it identifies the provider -->
+    <string name="app_name">ownCloud beta</string>
+    <string name="account_type">owncloud.beta</string> <!-- better if was a domain name; but changing it now would require migrate accounts when the app is updated -->
+    <string name="authority">org.owncloud.beta.provider</string>       <!-- better if was the app package with ".provider" appended ; it identifies the provider -->
+    <string name="authorityCache">org.owncloud.beta.imageCache.provider</string>
     <string name ="db_file">owncloud.db</string>
     <string name ="db_name">ownCloud</string>
-    <string name ="data_folder">owncloud</string>
+    <string name ="data_folder">owncloud-beta</string>
     <string name ="log_name">Owncloud_</string>
-    <string name ="default_display_name_for_root_folder">ownCloud</string>
+    <string name ="default_display_name_for_root_folder">ownCloud beta</string>
     <string name ="user_agent">Mozilla/5.0 (Android) ownCloud-android/%1$s</string>
     
     <!-- URLs and flags related -->
@@ -46,6 +47,7 @@
     <bool name="recommend_enabled">true</bool>
     <bool name="feedback_enabled">true</bool>
     <string name="url_help">http://owncloud.com/mobile/help</string>
+    <string name="beta_link">https://github.com/owncloud/android/raw/beta/apks/owncloud-beta-</string>
     <string name="url_imprint"></string>
     <string name="mail_recommend">"mailto:"</string>
     <string name="mail_feedback">"mailto:apps@owncloud.com"</string>
index 320eea1..68597bf 100644 (file)
@@ -23,8 +23,7 @@
     <!-- TODO re-enable when "Accounts" is available in Navigation Drawer -->
     <!--<string name="drawer_item_accounts">Accounts</string>-->
     <string name="drawer_item_all_files">All files</string>
-    <!-- TODO re-enable when "On Device" is available
-    <string name="drawer_item_on_device">On device</string>-->
+    <string name="drawer_item_on_device">On device</string>
     <string name="drawer_item_settings">Settings</string>
     <string name="drawer_item_logs">Logs</string>
        <string name="drawer_close">Close</string>
@@ -62,7 +61,7 @@
     <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_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="uploader_wrn_no_account_setup_btn_text">Setup</string>
@@ -85,9 +84,7 @@
     <string name="filedetails_sync_file">Synchronize</string>
     <string name="filedetails_renamed_in_upload_msg">File was renamed to %1$s during upload</string>
     <string name="list_layout">List Layout</string>
-    <string name="action_share_file">Share link</string>
-    <string name="action_unshare_file">Unshare link</string>
-    <string name="action_share_with_users">Share with users</string>
+    <string name="action_share">Share</string>
     <string name="common_yes">Yes</string>
     <string name="common_no">No</string>
     <string name="common_ok">OK</string>
     <string name="unfavorite">Unfavorite</string>
     <string name="common_rename">Rename</string>
     <string name="common_remove">Remove</string>
-    <string name="confirmation_remove_alert">"Do you really want to remove %1$s?"</string>
+    <string name="confirmation_remove_file_alert">"Do you really want to remove %1$s?"</string>
     <string name="confirmation_remove_folder_alert">"Do you really want to remove %1$s and its contents?"</string>
     <string name="confirmation_remove_local">Local only</string>
     <string name="confirmation_remove_folder_local">Local only</string>
-    <string name="confirmation_remove_remote">From server</string>
+    <string name="confirmation_remove_file_remote">From server</string>
     <string name="confirmation_remove_remote_and_local">Remote &amp; local</string>
     <string name="remove_success_msg">"Removal succeeded"</string>
     <string name="remove_fail_msg">"Removal failed"</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">Upload pictures via WiFi only</string>
-    <string name="instant_video_upload_on_wifi">Upload videos via WiFi only</string>
+    
+    <string name="instant_upload_on_wifi">Upload pictures via wifi only</string>
+    <string name="instant_upload_on_charging">Upload when charging only</string>
+    <string name="instant_video_upload_on_wifi">Upload videos via wifi only</string>
+    <string name="instant_video_upload_on_charging">Upload when charging only</string>
     <string name="instant_upload_path">/InstantUpload</string>
     <string name="conflict_title">File conflict</string>
     <string name="conflict_message">Which files do you want to keep? If you select both versions, the local file will have a number added to its name.</string>
     <string name="preview_image_error_unknown_format">This image cannot be shown</string>
 
     <string name="error__upload__local_file_not_copied">%1$s could not be copied to %2$s local folder</string>
-    <string name="prefs_instant_upload_path_title">Upload Path</string>
+    <string name="prefs_instant_upload_path_title">Upload path</string>
 
        <string name="share_link_no_support_share_api">Sorry, sharing is not enabled on your server. Please contact your
                administrator.</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="update_link_file_no_exist">Unable to update. Please check whether the file exists </string>
+    <string name="update_link_file_error">An error occurred while trying to update the shared link</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="forbidden_permissions_delete">to delete this file</string>
     <string name="share_link_forbidden_permissions">to share this file</string>
     <string name="unshare_link_forbidden_permissions">to unshare this file</string>
+    <string name="update_link_forbidden_permissions">to update this shared link</string>
     <string name="forbidden_permissions_create">to create the file</string>
     <string name="uploader_upload_forbidden_permissions">to upload in this folder</string>
     <string name="downloader_download_file_not_found">The file is no longer available on the server</string>
 
+    <string name="file_migration_finish_button">Finish</string>
+    <string name="file_migration_preparing">Preparing for migration...</string>
+    <string name="file_migration_checking_destination">Checking destination...</string>
+    <string name="file_migration_saving_accounts_configuration">Saving accounts configuration...</string>
+    <string name="file_migration_waiting_for_unfinished_sync">Waiting for unfinished synchronizations...</string>
+    <string name="file_migration_migrating">Moving data...</string>
+    <string name="file_migration_updating_index">Updating index...</string>
+    <string name="file_migration_cleaning">Cleaning...</string>
+    <string name="file_migration_restoring_accounts_configuration">Restoring accounts configuration...</string>
+    <string name="file_migration_ok_finished">Finished</string>
+    <string name="file_migration_failed_not_enough_space">ERROR: Not enough space</string>
+    <string name="file_migration_failed_not_writable">ERROR: File is not writable</string>
+    <string name="file_migration_failed_not_readable">ERROR: File is not readable</string>
+    <string name="file_migration_failed_dir_already_exists">ERROR: owncloud directory already exists</string>
+    <string name="file_migration_failed_while_coping">ERROR: While migrating</string>
+    <string name="file_migration_failed_while_updating_index">ERROR: While updating index</string>
+
     <string name="prefs_category_accounts">Accounts</string>
     <string name="prefs_add_account">Add account</string>
     <string name="auth_redirect_non_secure_connection_title">Secure connection is redirected through an unsecured route.</string>
     <string name="prefs_category_instant_uploading">Instant Uploads</string>
        <string name="prefs_category_security">Security</string>
 
-       <string name="prefs_instant_video_upload_path_title">Upload Video Path</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="sync_folder_failed_content">Synchronization of %1$s folder could not be completed</string>
 
        <string name="shared_subject_header">shared</string>
     <string name="file_list__footer__files">%1$d files</string>
     <string name="file_list__footer__files_and_folder">%1$d files, 1 folder</string>
     <string name="file_list__footer__files_and_folders">%1$d files, %2$d folders</string>
+    <string name="action_switch_grid_view">Switch to grid view</string>
+    <string name="action_switch_list_view">Switch to list view</string>
+    <string name="common_category">Common</string>
+    <string name="pref_cache_size">Cache size</string>
+    <string name="prefs_instant_behaviour_dialogTitle">Upload file to server and ...</string>
+    <string name="prefs_instant_behaviour_title">Behaviour</string>
+    <string name="upload_copy_files">Copy file</string>
+    <string name="upload_move_files">Move file</string>
+    <string name="prefs_storage_path">Storage path</string>
+    <string name="prefs_common">Common</string>
+
+    <string name="pref_behaviour_entries_do_nothing">do nothing</string>
+    <string name="pref_behaviour_entries_copy">copy file to OC folder</string>
+    <string name="pref_behaviour_entries_move">move file to OC folder</string>
+    <string name="pref_behaviour_entries_delete">delete origin file</string>
+    <string name="confirmation_remove_files_alert">Do you really want to remove selected items?</string>
+    <string name="confirmation_remove_folders_alert">Do you really want to remove a folder and its content?</string>
+    <string name="confirmation_remove_files">selected items</string>
+    <string name="error_log_exit">Exit</string>
+    <string name="error_log_send">Send Log</string>
+    <string name="error_log_title">Error Log</string>
+    <string name="action_stream_file">Stream file with external player</string>
+    <string name="stream_expose_password">Do you want to stream this file with an external app?\n\nCAUTION: This may expose your password!</string>
+    <string name="set_picture_as">Set picture as</string>
+    <string name="set_as">Set As</string>
 
     <string name="share_dialog_title">Sharing</string>
-    <string name="share_with_user_section_title">Share with Users and Groups</string>
+    <string name="share_with_user_section_title">Share with users and groups</string>
     <string name="share_no_users">No data shared with users yet</string>
     <string name="share_add_user_or_group">Add User or Group</string>
+    <string name="share_via_link_section_title">Share link</string>
+    <string name="share_via_link_expiration_date_label">Set expiration date</string>
+    <string name="share_via_link_password_label">Password protect</string>
+    <string name="share_via_link_password_title">Secured</string>
+    <string name="share_get_public_link_button">Get link</string>
+
     <string name="share_search">Search</string>
 
     <string name="search_users_and_groups_hint">Search users and groups</string>
 
     <string name="share_sharee_unavailable">Sorry, your server version does not allow share with users within clients.
         \nPlease contact your administrator</string>
+    <string name="changelog">https://github.com/owncloud/android/raw/beta/CHANGELOG.md</string>
 
 </resources>
index 4c07250..934b755 100644 (file)
@@ -51,7 +51,9 @@
                <item name="android:textColorPrimary">@color/primary</item>
        </style>
 
-       <style name="ownCloud.Dialog" parent="Theme.AppCompat.Light.Dialog" />
+       <style name="ownCloud.Dialog" parent="Theme.AppCompat.Light.Dialog">
+               <item name="colorAccent">@color/color_accent</item>
+       </style>
 
        <style name="ProgressDialogTheme" parent="ownCloud.Dialog">
                <item name="colorAccent">@color/color_accent</item>
 
        <style name="Theme.ownCloud.Fullscreen" parent="style/Theme.AppCompat">
         <item name="android:windowFullscreen">true</item>
+               <item name="colorAccent">@color/color_accent</item>
     </style>
        
        
                <item name="buttonBarStyle">@style/Theme.ownCloud.Dialog.ButtonBar</item>
        </style>
 
+       <style name="menu_labels_style">
+               <item name="android:background">@drawable/fab_label_background</item>
+               <item name="android:textColor">@color/fab_white</item>
+       </style>
+
        <!-- Button Bar hack due to Lollipop bug:
                https://code.google.com/p/android/issues/detail?id=78302
        fix see:
index 4823a83..3972e9e 100644 (file)
@@ -3,7 +3,7 @@
   ownCloud Android client application
 
   Copyright (C) 2012  Bartek Przybylski
-  Copyright (C) 2015 ownCloud Inc.
+  Copyright (C) 2012-2013 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,
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+       <PreferenceCategory android:title="@string/prefs_category_general">
+               <com.owncloud.android.ui.PreferenceWithLongSummary
+                       android:title="@string/prefs_storage_path"
+                       android:key="storage_path" />
+       </PreferenceCategory>
     <PreferenceCategory android:title="@string/prefs_category_accounts" android:key="accounts_category">
     </PreferenceCategory>
-    
+
        <PreferenceCategory android:title="@string/prefs_category_security">
-           <android.preference.CheckBoxPreference android:title="@string/prefs_passcode" android:key="set_pincode" />
+               <android.preference.CheckBoxPreference android:title="@string/prefs_passcode" android:key="set_pincode" />
        </PreferenceCategory>
 
     <PreferenceCategory android:title="@string/prefs_category_instant_uploading" android:key="instant_uploading_category">
-         <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_uploading"
+         <com.owncloud.android.ui.dialog.OwnCloudListPreference android:key="prefs_instant_behaviour"
+                        android:dialogTitle="@string/prefs_instant_behaviour_dialogTitle"
+                        android:title="@string/prefs_instant_behaviour_title"
+                        android:entries="@array/pref_behaviour_entries"
+                        android:entryValues="@array/pref_behaviour_entryValues"
+                        android:defaultValue="NOTHING"
+                        android:summary="%s"
+                        />
+
+               <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_uploading"
                                android:title="@string/prefs_instant_upload"
                                android:summary="@string/prefs_instant_upload_summary"/>
          <com.owncloud.android.ui.PreferenceWithLongSummary
                                                        android:title="@string/prefs_instant_upload_path_title"
                                                        android:key="instant_upload_path" />
            <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
-                                               android:title="@string/instant_upload_on_wifi"
-                                               android:key="instant_upload_on_wifi"/>
-           <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle android:key="instant_video_uploading"
-                               android:title="@string/prefs_instant_video_upload"
-                               android:summary="@string/prefs_instant_video_upload_summary" />
+                       android:dependency="instant_uploading"
+                       android:disableDependentsState="true"
+               android:title="@string/instant_upload_on_wifi"
+               android:key="instant_upload_on_wifi"/>
+               <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
+                       android:dependency="instant_uploading"
+                       android:disableDependentsState="true"
+                       android:title="@string/instant_upload_on_charging"
+                       android:key="instant_upload_on_charging"/>
+
+               <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
+                       android:key="instant_video_uploading"
+               android:title="@string/prefs_instant_video_upload"
+               android:summary="@string/prefs_instant_video_upload_summary" />
            <com.owncloud.android.ui.PreferenceWithLongSummary
-                                                       android:title="@string/prefs_instant_video_upload_path_title"
-                                                       android:key="instant_video_upload_path" />
+                       android:dependency="instant_video_uploading"
+                       android:disableDependentsState="true"
+                       android:title="@string/prefs_instant_video_upload_path_title"
+                       android:key="instant_video_upload_path" />
            <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
-                                               android:title="@string/instant_video_upload_on_wifi"
-                                               android:key="instant_video_upload_on_wifi"/>
-           <!-- DISABLED FOR RELEASE UNTIL FIXED
+                       android:dependency="instant_video_uploading"
+                       android:disableDependentsState="true"
+               android:title="@string/instant_video_upload_on_wifi"
+               android:key="instant_video_upload_on_wifi"/>
+               <com.owncloud.android.ui.CheckBoxPreferenceWithLongTitle
+                       android:dependency="instant_video_uploading"
+                       android:disableDependentsState="true"
+                       android:title="@string/instant_video_upload_on_charging"
+                       android:key="instant_video_upload_on_charging"/>
+       </PreferenceCategory>
+
+       <PreferenceCategory android:title="@string/common_category" android:key="common_category">
+               <EditTextPreference android:title="@string/pref_cache_size"
+                                                       android:key="pref_cache_size"
+                                                       android:digits="0123456789"/>
+       </PreferenceCategory>
+
+       <PreferenceCategory android:title="@string/prefs_category_more" android:key="more">
+               <!-- DISABLED FOR RELEASE UNTIL FIXED
            CheckBoxPreference android:key="log_to_file"
                                android:title="@string/prefs_log_title"
                                android:summary="@string/prefs_log_summary"/>
                <Preference             android:key="log_history"
                                android:title="@string/prefs_log_title_history"
                                android:summary="@string/prefs_log_summary_history"/ -->
-                        
-    </PreferenceCategory>
-       
-       <PreferenceCategory android:title="@string/prefs_category_more" android:key="more">
     <Preference android:title="@string/prefs_help" android:key="help" />
     <Preference android:title="@string/prefs_recommend" android:key="recommend" />
     <Preference android:title="@string/prefs_feedback" android:key="feedback" />
     <Preference android:title="@string/prefs_imprint" android:key="imprint" />
-                        
-       <Preference             android:id="@+id/about_app" 
-                                       android:title="@string/about_title" 
+
+       <Preference             android:id="@+id/about_app"
+                                       android:title="@string/about_title"
                                        android:key="about_app" />
-       </PreferenceCategory>
-    
 
+       <Preference android:id="@+id/beta_link"
+                               android:title="Download latest beta version"
+                               android:key="beta_link" />
+
+       <Preference android:id="@+id/changelog_link"
+               android:title="Changelog beta version"
+               android:key="changelog_link" />
+
+       </PreferenceCategory>
 </PreferenceScreen>
index 8ccfeee..b0fef5e 100644 (file)
@@ -23,6 +23,7 @@ call git submodule init
 call git submodule update
 
 call android.bat update project -p libs/android-support-appcompat-v7-exploded-aar --target android-22
+call android.bat update project -p libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar --target android-22
 call android.bat update lib-project -p owncloud-android-library
 call android.bat update project -p .
 call android.bat update project -p oc_jb_workaround
index 76ba2a3..6ca3a85 100755 (executable)
@@ -18,6 +18,7 @@ function initForAnt {
 
        #Prepare project android-support-appcompat-v7 ; JAR file is not enough, includes resources
        android update lib-project -p libs/android-support-appcompat-v7-exploded-aar --target android-22
+       android update lib-project -p libs/com-getbase-floatingactionbutton-1-10-1-exploded-aar --target android-22
        
        #As default it updates the ant scripts
        android update lib-project -p owncloud-android-library
index c805f9f..401f607 100644 (file)
@@ -23,16 +23,21 @@ package com.owncloud.android;
 import android.app.Activity;
 import android.app.Application;
 import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Environment;
+import android.preference.PreferenceManager;
 
 import com.owncloud.android.authentication.PassCodeManager;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.utils.ExceptionHandler;
 
 
 /**
@@ -54,15 +59,24 @@ public class MainApp extends Application {
 
     private static Context mContext;
 
-    // TODO Enable when "On Device" is recovered?
-    // TODO better place
-    // private static boolean mOnlyOnDevice = false;
+    private static String storagePath;
+
+    private static boolean mOnlyOnDevice = false;
 
     
     public void onCreate(){
         super.onCreate();
         MainApp.mContext = getApplicationContext();
+
+        // Setup handler for uncaught exceptions.
+        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
         
+
+        SharedPreferences appPrefs =
+                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+        MainApp.storagePath = appPrefs.getString("storage_path", Environment.
+                              getExternalStorageDirectory().getAbsolutePath());
+
         boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
 
         OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
@@ -82,7 +96,7 @@ public class MainApp extends Application {
             // Set folder for store logs
             Log_OC.setLogDataFolder(dataFolder);
 
-            Log_OC.startLogging();
+            Log_OC.startLogging(MainApp.storagePath);
             Log_OC.d("Debug", "start logging");
         }
 
@@ -135,6 +149,14 @@ public class MainApp extends Application {
         return MainApp.mContext;
     }
 
+    public static String getStoragePath(){
+        return MainApp.storagePath;
+    }
+
+    public static void setStoragePath(String path){
+        MainApp.storagePath = path;
+    }
+
     // Methods to obtain Strings referring app_name 
     //   From AccountAuthenticator 
     //   public static final String ACCOUNT_TYPE = "owncloud";    
@@ -176,14 +198,13 @@ public class MainApp extends Application {
         return getAppContext().getResources().getString(R.string.log_name);
     }
 
-    // TODO Enable when "On Device" is recovered ?
-//    public static void showOnlyFilesOnDevice(boolean state){
-//        mOnlyOnDevice = state;
-//    }
-//
-//    public static boolean getOnlyOnDevice(){
-//        return mOnlyOnDevice;
-//    }
+    public static void showOnlyFilesOnDevice(boolean state){
+        mOnlyOnDevice = state;
+    }
+
+    public static boolean getOnlyOnDevice(){
+        return mOnlyOnDevice;
+    }
 
     // user agent
     public static String getUserAgent() {
index e60233d..5fcccba 100644 (file)
@@ -74,7 +74,7 @@ public class PassCodeManager {
                 ){
 
             Intent i = new Intent(MainApp.getAppContext(), PassCodeActivity.class);
-            i.setAction(PassCodeActivity.ACTION_REQUEST);
+            i.setAction(PassCodeActivity.ACTION_CHECK);
             i.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
             activity.startActivity(i);
 
index 237c846..3e07375 100644 (file)
 
 package com.owncloud.android.datamodel;
 
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-
 import android.accounts.Account;
 import android.content.ContentProviderClient;
 import android.content.ContentProviderOperation;
@@ -47,18 +37,26 @@ import android.provider.MediaStore;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
 import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.lib.resources.files.FileUtils;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.lib.resources.status.CapabilityBooleanType;
 import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.utils.FileStorageUtils;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
 
 public class FileDataStorageManager {
 
@@ -144,10 +142,9 @@ public class FileDataStorageManager {
     }
 
 
-    public Vector<OCFile> getFolderContent(OCFile f/*, boolean onlyOnDevice*/) {
+    public Vector<OCFile> getFolderContent(OCFile f, boolean onlyOnDevice) {
         if (f != null && f.isFolder() && f.getFileId() != -1) {
-            // TODO Enable when "On Device" is recovered ?
-            return getFolderContent(f.getFileId()/*, onlyOnDevice*/);
+            return getFolderContent(f.getFileId(), onlyOnDevice);
 
         } else {
             return new Vector<OCFile>();
@@ -155,13 +152,12 @@ public class FileDataStorageManager {
     }
 
 
-    public Vector<OCFile> getFolderImages(OCFile folder/*, boolean onlyOnDevice*/) {
-        Vector<OCFile> ret = new Vector<OCFile>();
+    public Vector<OCFile> getFolderImages(OCFile folder, boolean onlyOnDevice) {
+        Vector<OCFile> ret = new Vector<OCFile>(); 
         if (folder != null) {
             // TODO better implementation, filtering in the access to database instead of here
-            // TODO Enable when "On Device" is recovered ?
-            Vector<OCFile> tmp = getFolderContent(folder/*, onlyOnDevice*/);
-            OCFile current = null;
+            Vector<OCFile> tmp = getFolderContent(folder, onlyOnDevice);
+            OCFile current = null; 
             for (int i=0; i<tmp.size(); i++) {
                 current = tmp.get(i);
                 if (current.isImage()) {
@@ -515,8 +511,7 @@ public class FileDataStorageManager {
         File localFolder = new File(localFolderPath);
         if (localFolder.exists()) {
             // stage 1: remove the local files already registered in the files database
-            // TODO Enable when "On Device" is recovered ?
-            Vector<OCFile> files = getFolderContent(folder.getFileId()/*, false*/);
+            Vector<OCFile> files = getFolderContent(folder.getFileId(), false);
             if (files != null) {
                 for (OCFile file : files) {
                     if (file.isFolder()) {
@@ -714,46 +709,78 @@ public class FileDataStorageManager {
                 if (!targetFolder.exists()) {
                     targetFolder.mkdirs();
                 }
-                copied = copyFile(localFile, targetFile);
+                copied = FileStorageUtils.copyFile(localFile, targetFile);
             }
             Log_OC.d(TAG, "Local file COPIED : " + copied);
         }
     }
 
-    private boolean copyFile(File src, File target) {
-        boolean ret = true;
+    public void migrateStoredFiles(String srcPath, String dstPath) throws Exception {
+        Cursor c = null;
+        if (getContentResolver() != null) {
+            c = getContentResolver().query(ProviderTableMeta.CONTENT_URI_FILE,
+                    null,
+                    ProviderTableMeta.FILE_STORAGE_PATH  + " IS NOT NULL",
+                    null,
+                    null);
+
+        } else {
+            try {
+                c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI_FILE,
+                        new String[]{ProviderTableMeta._ID, ProviderTableMeta.FILE_STORAGE_PATH},
+                        ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL",
+                        null,
+                        null);
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, e.getMessage());
+                throw e;
+            }
+        }
+
+        ArrayList<ContentProviderOperation> operations =
+                new ArrayList<ContentProviderOperation>(c.getCount());
+        if (c.moveToFirst()) {
+            do {
+                ContentValues cv = new ContentValues();
+                long fileId = c.getLong(c.getColumnIndex(ProviderTableMeta._ID));
+                String oldFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
+
+                if (oldFileStoragePath.startsWith(srcPath)) {
 
-        InputStream in = null;
-        OutputStream out = null;
+                    cv.put(
+                            ProviderTableMeta.FILE_STORAGE_PATH,
+                            oldFileStoragePath.replaceFirst(srcPath, dstPath));
 
+                    operations.add(
+                            ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                                    withValues(cv).
+                                    withSelection(
+                                            ProviderTableMeta._ID + "=?",
+                                            new String[]{String.valueOf(fileId)}
+                                    )
+                                    .build());
+                }
+
+            } while (c.moveToNext());
+        }
+        c.close();
+
+        /// 3. apply updates in batch
         try {
-            in = new FileInputStream(src);
-            out = new FileOutputStream(target);
-            byte[] buf = new byte[1024];
-            int len;
-            while ((len = in.read(buf)) > 0) {
-                out.write(buf, 0, len);
-            }
-        } catch (IOException ex) {
-            ret = false;
-        } finally {
-            if (in != null) try {
-                in.close();
-            } catch (IOException e) {
-                e.printStackTrace(System.err);
-            }
-            if (out != null) try {
-                out.close();
-            } catch (IOException e) {
-                e.printStackTrace(System.err);
+            if (getContentResolver() != null) {
+                getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+
+            } else {
+                getContentProviderClient().applyBatch(operations);
             }
-        }
 
-        return ret;
+        } catch (Exception e) {
+            throw e;
+        }
     }
 
-
-    private Vector<OCFile> getFolderContent(long parentId/*, boolean onlyOnDevice*/) {
+    
+    private Vector<OCFile> getFolderContent(long parentId, boolean onlyOnDevice) {
 
         Vector<OCFile> ret = new Vector<OCFile>();
 
@@ -780,10 +807,9 @@ public class FileDataStorageManager {
         if (c.moveToFirst()) {
             do {
                 OCFile child = createFileInstance(c);
-                // TODO Enable when "On Device" is recovered ?
-                // if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){
-                ret.add(child);
-                // }
+                 if (child.isFolder() || !onlyOnDevice || onlyOnDevice && child.isDown()){
+                    ret.add(child);
+                 }
             } while (c.moveToNext());
         }
 
@@ -935,20 +961,20 @@ public class FileDataStorageManager {
         );
         cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
         cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
-        cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+        cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
         cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
-        if (shareExists(share.getIdRemoteShared())) {// for renamed files; no more delete and create
+        if (shareExists(share.getRemoteId())) {// for renamed files; no more delete and create
             overriden = true;
             if (getContentResolver() != null) {
                 getContentResolver().update(ProviderTableMeta.CONTENT_URI_SHARE, cv,
                         ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
-                        new String[]{String.valueOf(share.getIdRemoteShared())});
+                        new String[]{String.valueOf(share.getRemoteId())});
             } else {
                 try {
                     getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_SHARE,
                             cv, ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
-                            new String[]{String.valueOf(share.getIdRemoteShared())});
+                            new String[]{String.valueOf(share.getRemoteId())});
                 } catch (RemoteException e) {
                     Log_OC.e(TAG,
                             "Fail to insert insert file to database "
@@ -981,16 +1007,42 @@ public class FileDataStorageManager {
     }
 
 
+    /**
+     * Get first share bound to a file with a known path and given {@link ShareType}.
+     *
+     * @param path          Path of the file.
+     * @param type          Type of the share to get
+     * @param shareWith     Target of the share. Ignored in type is {@link ShareType#PUBLIC_LINK}
+     * @return              First {@OCShare} instance found in DB bound to the file in 'path'
+     */
     public OCShare getFirstShareByPathAndType(String path, ShareType type, String shareWith) {
         Cursor c = null;
+        if (shareWith == null) {
+            shareWith = "";
+        }
 
         String selection = ProviderTableMeta.OCSHARES_PATH + "=? AND "
                 + ProviderTableMeta.OCSHARES_SHARE_TYPE + "=? AND "
-                + ProviderTableMeta.OCSHARES_SHARE_WITH + "=? AND "
                 + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" ;
+        if (!ShareType.PUBLIC_LINK.equals(type)) {
+            selection += " AND " + ProviderTableMeta.OCSHARES_SHARE_WITH + "=?";
+        }
 
-        String [] selectionArgs =  new String[]{path, Integer.toString(type.getValue()),
-                shareWith, mAccount.name};
+        String [] selectionArgs;
+        if (ShareType.PUBLIC_LINK.equals(type)) {
+            selectionArgs = new String[]{
+                    path,
+                    Integer.toString(type.getValue()),
+                    mAccount.name
+            };
+        } else {
+            selectionArgs = new String[]{
+                    path,
+                    Integer.toString(type.getValue()),
+                    mAccount.name,
+                    shareWith
+            };
+        }
 
         if (getContentResolver() != null) {
             c = getContentResolver().query(
@@ -1190,16 +1242,16 @@ public class FileDataStorageManager {
                 );
                 cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
                 cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
-                cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+                cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
                 cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
-                if (shareExists(share.getIdRemoteShared())) {
+                if (shareExists(share.getRemoteId())) {
                     // updating an existing file
                     operations.add(
                             ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
                                     withValues(cv).
                                     withSelection(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
-                                            new String[]{String.valueOf(share.getIdRemoteShared())})
+                                            new String[]{String.valueOf(share.getRemoteId())})
                                     .build());
                 } else {
                     // adding a new file
@@ -1403,6 +1455,30 @@ public class FileDataStorageManager {
 //        updateSharedFiles(sharedFiles);
     }
 
+    public void removeSharesForFile(String remotePath) {
+        resetShareFlagInAFile(remotePath);
+        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
+        operations = prepareRemoveSharesInFile(remotePath, operations);
+        // apply operations in batch
+        if (operations.size() > 0) {
+            Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
+            try {
+                if (getContentResolver() != null) {
+                    getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+
+                } else {
+                    getContentProviderClient().applyBatch(operations);
+                }
+
+            } catch (OperationApplicationException e) {
+                Log_OC.e(TAG, "Exception in batch of operations " + e.getMessage());
+
+            } catch (RemoteException e) {
+                Log_OC.e(TAG, "Exception in batch of operations  " + e.getMessage());
+            }
+        }
+    }
+
 
     public void saveSharesInFolder(ArrayList<OCShare> shares, OCFile folder) {
         resetShareFlagsInFolder(folder);
@@ -1463,7 +1539,7 @@ public class FileDataStorageManager {
                 );
                 cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
                 cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
-                cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
+                cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getRemoteId());
                 cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
 
                 // adding a new share resource
@@ -1484,9 +1560,8 @@ public class FileDataStorageManager {
                     + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
             String [] whereArgs = new String[]{ "", mAccount.name };
 
-            // TODO Enable when "On Device" is recovered ?
-            Vector<OCFile> files = getFolderContent(folder /*, false*/);
-
+            Vector<OCFile> files = getFolderContent(folder, false);
+            
             for (OCFile file : files) {
                 whereArgs[0] = file.getRemotePath();
                 preparedOperations.add(
@@ -1557,10 +1632,12 @@ public class FileDataStorageManager {
         return shares;
     }
 
-    public void triggerMediaScan(String path) {
-        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
-        intent.setData(Uri.fromFile(new File(path)));
-        MainApp.getAppContext().sendBroadcast(intent);
+    public static void triggerMediaScan(String path) {
+        if (path != null) {
+            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+            intent.setData(Uri.fromFile(new File(path)));
+            MainApp.getAppContext().sendBroadcast(intent);
+        }
     }
 
     public void deleteFileInMediaScan(String path) {
@@ -1860,6 +1937,8 @@ public class FileDataStorageManager {
 
         if (c.moveToFirst()) {
             capability = createCapabilityInstance(c);
+        } else {
+            capability = new OCCapability();    // return default with all UNKNOWN
         }
         c.close();
         return capability;
index 2b9bd5e..8cbb95e 100644 (file)
@@ -35,13 +35,11 @@ import java.io.File;
 import third_parties.daveKoeller.AlphanumComparator;
 public class OCFile implements Parcelable, Comparable<OCFile> {
 
-    public static final Parcelable.Creator<OCFile> CREATOR = new Parcelable.Creator<OCFile>() {
-        @Override
+    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
         public OCFile createFromParcel(Parcel source) {
             return new OCFile(source);
         }
 
-        @Override
         public OCFile[] newArray(int size) {
             return new OCFile[size];
         }
@@ -80,6 +78,8 @@ public class OCFile implements Parcelable, Comparable<OCFile> {
 
     private boolean mIsDownloading;
 
+    private boolean mShowGridView;
+
     private String mEtagInConflict;    // Save file etag in the server, when there is a conflict. No conflict =  null
 
     private boolean mShareWithSharee;
index f0ecf76..8c36fa2 100644 (file)
@@ -24,23 +24,34 @@ package com.owncloud.android.datamodel;
 import java.io.File;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
+import java.net.FileNameMap;
+import java.net.URLConnection;
 
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.methods.GetMethod;
 
 import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
+import android.graphics.Point;
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.media.ThumbnailUtils;
 import android.net.Uri;
 import android.os.AsyncTask;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
 import android.widget.ImageView;
+import android.widget.ProgressBar;
 
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
@@ -53,6 +64,7 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.ui.adapter.DiskLruImageCache;
 import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.FileStorageUtils;
 
 /**
  * Manager for concurrent access to thumbnails cache.
@@ -140,13 +152,40 @@ public class ThumbnailsCacheManager {
         return null;
     }
 
+    /**
+     * Sets max size of cache
+     * @param maxSize in MB
+     * @return
+     */
+    public static boolean setMaxSize(long maxSize){
+        if (mThumbnailCache != null){
+            mThumbnailCache.setMaxSize(maxSize * 1024 * 1024);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Shows max cache size
+     * @return max cache size in MB.
+     */
+    public static long getMaxSize(){
+        if (mThumbnailCache != null) {
+            return mThumbnailCache.getMaxSize() / 1024 / 1024;
+        } else {
+            return -1l;
+        }
+    }
+
     public static class ThumbnailGenerationTask extends AsyncTask<Object, Void, Bitmap> {
         private final WeakReference<ImageView> mImageViewReference;
+        private WeakReference<ProgressBar> mProgressWheelRef;
         private static Account mAccount;
         private Object mFile;
+        private Boolean mIsThumbnail;
         private FileDataStorageManager mStorageManager;
 
-
         public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager,
                                        Account account) {
             // Use a WeakReference to ensure the ImageView can be garbage collected
@@ -157,6 +196,12 @@ public class ThumbnailsCacheManager {
             mAccount = account;
         }
 
+        public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager,
+                                       Account account, ProgressBar progressWheel) {
+        this(imageView, storageManager, account);
+        mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
+        }
+
         public ThumbnailGenerationTask(ImageView imageView) {
             // Use a WeakReference to ensure the ImageView can be garbage collected
             mImageViewReference = new WeakReference<ImageView>(imageView);
@@ -175,11 +220,24 @@ public class ThumbnailsCacheManager {
                 }
 
                 mFile = params[0];
+                mIsThumbnail = (Boolean) params[1];
+
                 
                 if (mFile instanceof OCFile) {
-                    thumbnail = doOCFileInBackground();
+                    thumbnail = doOCFileInBackground(mIsThumbnail);
+
+                    if (((OCFile) mFile).isVideo()){
+                        thumbnail = addVideoOverlay(thumbnail);
+                    }
                 }  else if (mFile instanceof File) {
-                    thumbnail = doFileInBackground();
+                    thumbnail = doFileInBackground(mIsThumbnail);
+
+                    String url = ((File) mFile).getAbsolutePath();
+                    String mMimeType = FileStorageUtils.getMimeTypeFromName(url);
+
+                    if (mMimeType != null && mMimeType.startsWith("video/")){
+                        thumbnail = addVideoOverlay(thumbnail);
+                    }
                 //} else {  do nothing
                 }
 
@@ -206,7 +264,14 @@ public class ThumbnailsCacheManager {
                         tagId = String.valueOf(mFile.hashCode());
                     }
                     if (String.valueOf(imageView.getTag()).equals(tagId)) {
+                        if (mProgressWheelRef != null) {
+                            final ProgressBar progressWheel = mProgressWheelRef.get();
+                            if (progressWheel != null) {
+                                progressWheel.setVisibility(View.GONE);
+                            }
+                        }
                         imageView.setImageBitmap(bitmap);
+                        // imageView.setVisibility(View.VISIBLE);
                     }
                 }
             }
@@ -217,12 +282,13 @@ public class ThumbnailsCacheManager {
          * @param imageKey: thumb key
          * @param bitmap:   image for extracting thumbnail
          * @param path:     image path
-         * @param px:       thumbnail dp
+         * @param pxW:       thumbnail width
+         * @param pxH:       thumbnail height
          * @return Bitmap
          */
-        private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int px){
+        private Bitmap addThumbnailToCache(String imageKey, Bitmap bitmap, String path, int pxW, int pxH){
 
-            Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+            Bitmap thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH);
 
             // Rotate image, obeying exif tag
             thumbnail = BitmapUtils.rotateImage(thumbnail,path);
@@ -243,31 +309,56 @@ public class ThumbnailsCacheManager {
             return Math.round(r.getDimension(R.dimen.file_icon_size_grid));
         }
 
-        private Bitmap doOCFileInBackground() {
+        private Point getScreenDimension(){
+            WindowManager wm = (WindowManager) MainApp.getAppContext().getSystemService(Context.WINDOW_SERVICE);
+            Display display = wm.getDefaultDisplay();
+            Point test = new Point();
+            display.getSize(test);
+            return test;
+        }
+
+        private Bitmap doOCFileInBackground(Boolean isThumbnail) {
+            Bitmap thumbnail = null;
             OCFile file = (OCFile)mFile;
 
-            final String imageKey = String.valueOf(file.getRemoteId());
+            // distinguish between thumbnail and resized image
+            String temp = String.valueOf(file.getRemoteId());
+            if (isThumbnail){
+                temp = "t" + temp;
+            } else {
+                temp = "r" + temp;
+            }
+
+            final String imageKey = temp;
 
             // Check disk cache in background thread
-            Bitmap thumbnail = getBitmapFromDiskCache(imageKey);
+            thumbnail = getBitmapFromDiskCache(imageKey);
 
             // Not found in disk cache
             if (thumbnail == null || file.needsUpdateThumbnail()) {
-
-                int px = getThumbnailDimension();
+                int pxW = 0;
+                int pxH = 0;
+                if (mIsThumbnail) {
+                    pxW = pxH = getThumbnailDimension();
+                } else {
+                    Point p = getScreenDimension();
+                    pxW = p.x;
+                    pxH = p.y;
+                }
 
                 if (file.isDown()) {
-                    Bitmap temp = BitmapUtils.decodeSampledBitmapFromFile(
-                            file.getStoragePath(), px, px);
-                    Bitmap bitmap = ThumbnailUtils.extractThumbnail(temp, px, px);
+                    Bitmap tempBitmap = BitmapUtils.decodeSampledBitmapFromFile(
+                            file.getStoragePath(), pxW, pxH);
+                    Bitmap bitmap = ThumbnailUtils.extractThumbnail(tempBitmap, pxW, pxH);
 
                     if (bitmap != null) {
                         // Handle PNG
                         if (file.getMimetype().equalsIgnoreCase("image/png")) {
-                            bitmap = handlePNG(bitmap, px);
+                            bitmap = handlePNG(bitmap, pxW);
                         }
 
-                        thumbnail = addThumbnailToCache(imageKey, bitmap, file.getStoragePath(), px);
+                        thumbnail = addThumbnailToCache(imageKey, bitmap,
+                                                        file.getStoragePath(), pxW, pxH);
 
                         file.setNeedsUpdateThumbnail(false);
                         mStorageManager.saveFile(file);
@@ -279,27 +370,51 @@ public class ThumbnailsCacheManager {
                     if (mClient != null && serverOCVersion != null) {
                         if (serverOCVersion.supportsRemoteThumbnails()) {
                             try {
-                                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);
-                                int status = mClient.executeMethod(get);
-                                if (status == HttpStatus.SC_OK) {
-                                    InputStream inputStream = get.getResponseBodyAsStream();
-                                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
-                                    thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
-
-                                    // Handle PNG
-                                    if (file.getMimetype().equalsIgnoreCase("image/png")) {
-                                        thumbnail = handlePNG(thumbnail, px);
+                                if (mIsThumbnail) {
+                                    String uri = mClient.getBaseUri() + "" +
+                                            "/index.php/apps/files/api/v1/thumbnail/" +
+                                            pxW + "/" + pxH + Uri.encode(file.getRemotePath(), "/");
+                                    Log_OC.d("Thumbnail", "Download URI: " + uri);
+                                    GetMethod get = new GetMethod(uri);
+                                    int status = mClient.executeMethod(get);
+                                    if (status == HttpStatus.SC_OK) {
+                                        InputStream inputStream = get.getResponseBodyAsStream();
+                                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
+                                        thumbnail = ThumbnailUtils.extractThumbnail(bitmap, pxW, pxH);
+                                    } else {
+                                        Log_OC.d(TAG, "Status: " + status);
+                                    }
+                                } else {
+                                    String gallery = "";
+                                    if (serverOCVersion.supportsNativeGallery()){
+                                        gallery = "gallery";
+                                    } else {
+                                        gallery = "galleryplus";
                                     }
 
-                                    // Add thumbnail to cache
-                                    if (thumbnail != null) {
-                                        addBitmapToCache(imageKey, thumbnail);
+                                    String uri = mClient.getBaseUri() +
+                                            "/index.php/apps/" + gallery + "/api/preview/" + Integer.parseInt(file.getRemoteId().substring(0,8)) +
+                                            "/" + pxW + "/" + pxH;
+                                    Log_OC.d("Thumbnail", "FileName: " + file.getFileName() + " Download URI: " + uri);
+                                    GetMethod get = new GetMethod(uri);
+                                    int status = mClient.executeMethod(get);
+                                    if (status == HttpStatus.SC_OK) {
+                                        InputStream inputStream = get.getResponseBodyAsStream();
+                                        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
+                                        // Download via gallery app
+                                        thumbnail = bitmap;
                                     }
                                 }
+
+                                // Handle PNG
+                                if (thumbnail != null && file.getMimetype().equalsIgnoreCase("image/png")) {
+                                    thumbnail = handlePNG(thumbnail, pxW);
+                                }
+
+                                // Add thumbnail to cache
+                                if (thumbnail != null) {
+                                    addBitmapToCache(imageKey, thumbnail);
+                                }
                             } catch (Exception e) {
                                 e.printStackTrace();
                             }
@@ -327,24 +442,39 @@ public class ThumbnailsCacheManager {
             return resultBitmap;
         }
 
-        private Bitmap doFileInBackground() {
+        private Bitmap doFileInBackground(Boolean mIsThumbnail) {
             File file = (File)mFile;
 
-            final String imageKey = String.valueOf(file.hashCode());
+            // distinguish between thumbnail and resized image
+            String temp = String.valueOf(file.hashCode());
+            if (mIsThumbnail){
+                temp = "t" + temp;
+            } else {
+                temp = "r" + temp;
+            }
+
+            final String imageKey = temp;
 
             // Check disk cache in background thread
             Bitmap thumbnail = getBitmapFromDiskCache(imageKey);
 
             // Not found in disk cache
             if (thumbnail == null) {
-
-                int px = getThumbnailDimension();
+                int pxW = 0;
+                int pxH = 0;
+                if (mIsThumbnail) {
+                    pxW = pxH = getThumbnailDimension();
+                } else {
+                    Point p = getScreenDimension();
+                    pxW = p.x;
+                    pxH = p.y;
+                }
 
                 Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
-                        file.getAbsolutePath(), px, px);
+                        file.getAbsolutePath(), pxW, pxH);
 
                 if (bitmap != null) {
-                    thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), px);
+                    thumbnail = addThumbnailToCache(imageKey, bitmap, file.getPath(), pxW, pxH);
                 }
             }
             return thumbnail;
@@ -382,6 +512,51 @@ public class ThumbnailsCacheManager {
         return null;
     }
 
+    public static Bitmap addVideoOverlay(Bitmap thumbnail){
+        Bitmap playButton = BitmapFactory.decodeResource(MainApp.getAppContext().getResources(),
+                R.drawable.view_play);
+
+        Bitmap resizedPlayButton = Bitmap.createScaledBitmap(playButton,
+                (int) (thumbnail.getWidth() * 0.3),
+                (int) (thumbnail.getHeight() * 0.3), true);
+
+        Bitmap resultBitmap = Bitmap.createBitmap(thumbnail.getWidth(),
+                thumbnail.getHeight(),
+                Bitmap.Config.ARGB_8888);
+
+        Canvas c = new Canvas(resultBitmap);
+
+        // compute visual center of play button, according to resized image
+        int x1 = resizedPlayButton.getWidth();
+        int y1 = resizedPlayButton.getHeight() / 2;
+        int x2 = 0;
+        int y2 = resizedPlayButton.getWidth();
+        int x3 = 0;
+        int y3 = 0;
+
+        double ym = ( ((Math.pow(x3,2) - Math.pow(x1,2) + Math.pow(y3,2) - Math.pow(y1,2)) *
+                    (x2 - x1)) - (Math.pow(x2,2) - Math.pow(x1,2) + Math.pow(y2,2) -
+                    Math.pow(y1,2)) * (x3 - x1) )  /  (2 * ( ((y3 - y1) * (x2 - x1)) -
+                    ((y2 - y1) * (x3 - x1)) ));
+        double xm = ( (Math.pow(x2,2) - Math.pow(x1,2)) + (Math.pow(y2,2) - Math.pow(y1,2)) -
+                    (2*ym*(y2 - y1)) ) / (2*(x2 - x1));
+
+        // offset to top left
+        double ox = - xm;
+        double oy = thumbnail.getHeight() - ym;
+
+
+        c.drawBitmap(thumbnail, 0, 0, null);
+
+        Paint p = new Paint();
+        p.setAlpha(230);
+
+        c.drawBitmap(resizedPlayButton, (float) ((thumbnail.getWidth() / 2) + ox),
+                                        (float) ((thumbnail.getHeight() / 2) - ym), p);
+
+        return resultBitmap;
+    }
+
     public static class AsyncDrawable extends BitmapDrawable {
         private final WeakReference<ThumbnailGenerationTask> bitmapWorkerTaskReference;
 
index 25d3027..6525303 100644 (file)
@@ -184,34 +184,19 @@ public class FileMenuFilter {
         }
 
         // SHARE FILE
-        // TODO add check on SHARE available on server side?
         boolean shareAllowed = (mContext != null  &&
                 mContext.getString(R.string.share_feature).equalsIgnoreCase("on"));
-        if (!shareAllowed || mFile == null) {
-            toHide.add(R.id.action_share_file);
-        } else {
-            toShow.add(R.id.action_share_file);
-        }
-
-        // UNSHARE FILE
-        // TODO add check on SHARE available on server side?
-        if ( !shareAllowed || (mFile == null || !mFile.isSharedViaLink())) {
-            toHide.add(R.id.action_unshare_file);
-        } else {
-            toShow.add(R.id.action_unshare_file);
-        }
-
-        // SHARE FILE, with Users
         OCCapability capability = mComponentsGetter.getStorageManager().getCapability(mAccount.name);
         boolean shareApiEnabled  = capability != null &&
-                (capability.getFilesSharingApiEnabled().isTrue() || capability.getFilesSharingApiEnabled().isUnknown());
-        if (!shareAllowed ||  mFile == null || !shareApiEnabled ) {
-            toHide.add(R.id.action_share_with_users);
+                (capability.getFilesSharingApiEnabled().isTrue() ||
+                        capability.getFilesSharingApiEnabled().isUnknown()
+                );
+        if (!shareAllowed ||  mFile == null || !shareApiEnabled) {
+            toHide.add(R.id.action_share_file);
         } else {
-            toShow.add(R.id.action_share_with_users);
+            toShow.add(R.id.action_share_file);
         }
 
-
         // SEE DETAILS
         if (mFile == null || mFile.isFolder()) {
             toHide.add(R.id.action_see_details);
@@ -242,6 +227,20 @@ public class FileMenuFilter {
             toShow.add(R.id.action_unfavorite_file);
         }
 
+        // STREAM
+        if (mFile != null && !mFile.isDown() && (mFile.isAudio() || mFile.isVideo())){
+            toShow.add(R.id.action_stream_file);
+        } else {
+            toHide.add(R.id.action_stream_file);
+        }
+
+        // SET PICTURE AS
+        if (mFile == null || !mFile.isImage()){
+            toHide.add(R.id.action_set_as_wallpaper);
+        } else {
+            toShow.add(R.id.action_set_as_wallpaper);
+        }
+
     }
 
 }
index a22de8e..989b848 100644 (file)
@@ -25,16 +25,20 @@ import android.accounts.Account;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Bitmap;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.graphics.Bitmap;
 import android.net.Uri;
 import android.support.v4.app.DialogFragment;
 import android.webkit.MimeTypeMap;
 import android.widget.Toast;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 import com.owncloud.android.lib.common.network.WebdavUtils;
@@ -44,11 +48,24 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.services.observer.FileObserverService;
 import com.owncloud.android.ui.activity.FileActivity;
+import com.owncloud.android.ui.adapter.DiskLruImageCacheFileProvider;
 import com.owncloud.android.ui.activity.ShareActivity;
 import com.owncloud.android.ui.dialog.ShareLinkToDialog;
+import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
+
+
+import java.io.File;
+import java.util.List;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 
 import org.apache.http.protocol.HTTP;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -139,19 +156,32 @@ public class FileOperationsHelper {
                 .show();
     }
 
-    public void shareFileWithLink(OCFile file) {
 
+    /**
+     * Helper method to share a file via a public link. Starts a request to do it in {@link OperationsService}
+     *
+     * @param file          The file to share.
+     * @param password      Optional password to protect the public share.
+     */
+    public void shareFileViaLink(OCFile file, String password) {
         if (isSharedSupported()) {
             if (file != null) {
-                String link = "https://fake.url";
-                Intent intent = createShareWithLinkIntent(link);
-                String[] packagesToExclude = new String[]{mFileActivity.getPackageName()};
-                DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intent,
-                        packagesToExclude, file);
-                chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
+                mFileActivity.showLoadingDialog(
+                        mFileActivity.getApplicationContext().
+                                getString(R.string.wait_a_moment)
+                );
+                Intent service = new Intent(mFileActivity, OperationsService.class);
+                service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK);
+                service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+                if (password != null && password.length() > 0) {
+                    service.putExtra(OperationsService.EXTRA_SHARE_PASSWORD, password);
+                }
+                service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+                mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
 
             } else {
                 Log_OC.wtf(TAG, "Trying to share a NULL OCFile");
+                // TODO user-level error?
             }
 
         } else {
@@ -164,6 +194,30 @@ public class FileOperationsHelper {
         }
     }
 
+    public void getFileWithLink(OCFile file){
+        if (isSharedSupported()) {
+            if (file != null) {
+                mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
+                        getString(R.string.wait_a_moment));
+
+                Intent service = new Intent(mFileActivity, OperationsService.class);
+                service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK);
+                service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+                service.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+                mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
+
+            } else {
+                Log_OC.wtf(TAG, "Trying to share a NULL OCFile");
+            }
+        } else {
+            // Show a Message
+            Toast t = Toast.makeText(
+                    mFileActivity, mFileActivity.getString(R.string.share_link_no_support_share_api),
+                    Toast.LENGTH_LONG
+            );
+            t.show();
+        }
+    }
 
     public void shareFileWithLinkToApp(OCFile file, String password, Intent sendIntent) {
         
@@ -175,7 +229,7 @@ public class FileOperationsHelper {
             service.setAction(OperationsService.ACTION_CREATE_SHARE_VIA_LINK);
             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_SHARE_PASSWORD, password);
             service.putExtra(OperationsService.EXTRA_SEND_INTENT, sendIntent);
             mWaitingForOpId = mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
             
@@ -184,17 +238,8 @@ public class FileOperationsHelper {
         }
     }
 
-
-    private Intent createShareWithLinkIntent(String link) {
-        Intent intentToShareLink = new Intent(Intent.ACTION_SEND);
-        intentToShareLink.putExtra(Intent.EXTRA_TEXT, link);
-        intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE);
-        return intentToShareLink;
-    }
-
-
     /**
-     * Helper method to share a file with a know sharee. Starts a request to do it in {@link OperationsService}
+     * Helper method to share a file with a known sharee. Starts a request to do it in {@link OperationsService}
      *
      * @param file          The file to share.
      * @param shareeName    Name (user name or group name) of the target sharee.
@@ -232,7 +277,13 @@ public class FileOperationsHelper {
     }
 
 
-    public void unshareFileWithLink(OCFile file) {
+    /**
+     * Helper method to unshare a file publicly shared via link.
+     * Starts a request to do it in {@link OperationsService}
+     *
+     * @param file      The file to unshare.
+     */
+    public void unshareFileViaLink(OCFile file) {
 
         // Unshare the file: Create the intent
         Intent unshareService = new Intent(mFileActivity, OperationsService.class);
@@ -242,7 +293,7 @@ public class FileOperationsHelper {
         unshareService.putExtra(OperationsService.EXTRA_SHARE_TYPE, ShareType.PUBLIC_LINK);
         unshareService.putExtra(OperationsService.EXTRA_SHARE_WITH, "");
 
-        unshareFile(unshareService);
+        queueShareIntent(unshareService);
     }
 
     public void unshareFileWithUserOrGroup(OCFile file, ShareType shareType, String userOrGroup){
@@ -255,15 +306,15 @@ public class FileOperationsHelper {
         unshareService.putExtra(OperationsService.EXTRA_SHARE_TYPE, shareType);
         unshareService.putExtra(OperationsService.EXTRA_SHARE_WITH, userOrGroup);
 
-        unshareFile(unshareService);
+        queueShareIntent(unshareService);
     }
 
 
-    private void unshareFile(Intent unshareService){
+    private void queueShareIntent(Intent shareIntent){
         if (isSharedSupported()) {
             // Unshare the file
             mWaitingForOpId = mFileActivity.getOperationsServiceBinder().
-                    queueNewOperation(unshareService);
+                    queueNewOperation(shareIntent);
 
             mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
                     getString(R.string.wait_a_moment));
@@ -293,6 +344,67 @@ public class FileOperationsHelper {
 
 
     /**
+     * Starts a dialog that requests a password to the user to protect a share link.
+     *
+     * @param   file            File which public share will be protected by the requested password
+     * @param   createShare     When 'true', the request for password will be followed by the creation of a new
+     *                          public link; when 'false', a public share is assumed to exist, and the password
+     *                          is bound to it.
+     */
+    public void requestPasswordForShareViaLink(OCFile file, boolean createShare) {
+        SharePasswordDialogFragment dialog =
+                SharePasswordDialogFragment.newInstance(file, createShare);
+        dialog.show(
+                mFileActivity.getSupportFragmentManager(),
+                SharePasswordDialogFragment.PASSWORD_FRAGMENT
+        );
+    }
+
+    /**
+     * Updates a public share on a file to set its password.
+     * Starts a request to do it in {@link OperationsService}
+     *
+     * @param file          File which public share will be protected with a password.
+     * @param password      Password to set for the public link; null or empty string to clear
+     *                      the current password
+     */
+    public void setPasswordToShareViaLink(OCFile file, String password) {
+        // Set password updating share
+        Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class);
+        updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE);
+        updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+        updateShareIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+        updateShareIntent.putExtra(
+                OperationsService.EXTRA_SHARE_PASSWORD,
+                (password == null) ? "" : password
+        );
+
+        queueShareIntent(updateShareIntent);
+    }
+
+
+    /**
+     * Updates a public share on a file to set its expiration date.
+     * Starts a request to do it in {@link OperationsService}
+     *
+     * @param file                      File which public share will be constrained with an expiration date.
+     * @param expirationTimeInMillis    Expiration date to set. A negative value clears the current expiration
+     *                                  date, leaving the link unrestricted. Zero makes no change.
+     */
+    public void setExpirationDateToShareViaLink(OCFile file, long expirationTimeInMillis) {
+        Intent updateShareIntent = new Intent(mFileActivity, OperationsService.class);
+        updateShareIntent.setAction(OperationsService.ACTION_UPDATE_SHARE);
+        updateShareIntent.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
+        updateShareIntent.putExtra(OperationsService.EXTRA_REMOTE_PATH, file.getRemotePath());
+        updateShareIntent.putExtra(
+                OperationsService.EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS,
+                expirationTimeInMillis
+        );
+        queueShareIntent(updateShareIntent);
+    }
+
+
+    /**
      * @return 'True' if the server supports the Search Users API
      */
     public boolean isSearchUsersSupportedSupported() {
@@ -315,8 +427,7 @@ public class FileOperationsHelper {
 
             // Show dialog, without the own app
             String[] packagesToExclude = new String[]{mFileActivity.getPackageName()};
-            DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent,
-                    packagesToExclude, file);
+            DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude);
             chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
 
         } else {
@@ -324,6 +435,65 @@ public class FileOperationsHelper {
         }
     }
 
+    public void setPictureAs(OCFile file) {
+        if (file != null){
+            if (file.isDown()) {
+                File externalFile = new File(file.getStoragePath());
+                Uri sendUri = Uri.fromFile(externalFile);
+                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
+                intent.setDataAndType(sendUri, file.getMimetype());
+                intent.putExtra("mimeType", file.getMimetype());
+                mFileActivity.startActivityForResult(Intent.createChooser(intent,
+                                                    mFileActivity.getString(R.string.set_as)), 200);
+            } else {
+                // TODO re-enable after resized images is available
+                Uri sendUri = Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath());
+                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
+                intent.setDataAndType(sendUri, file.getMimetype());
+                intent.putExtra("mimeType", file.getMimetype());
+                mFileActivity.startActivityForResult(Intent.createChooser(intent, "Set As"), 200);
+
+//                Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
+//                // set MimeType
+//                sendIntent.setType(file.getMimetype());
+////            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + "/#" + file.getRemoteId() + "#" + file.getFileName()));
+//                sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath()));
+//                sendIntent.putExtra(Intent.ACTION_SEND, true);      // Send Action
+//
+//                // Show dialog, without the own app
+//                String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
+//                DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file);
+//                chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
+            }
+        } else {
+            Log_OC.wtf(TAG, "Trying to send a NULL OCFile");
+        }
+    }
+
+    public void sendCachedImage(OCFile file) {
+        if (file != null) {
+            Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
+            // set MimeType
+            sendIntent.setType(file.getMimetype());
+//            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + "/#" + file.getRemoteId() + "#" + file.getFileName()));
+            sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://" + DiskLruImageCacheFileProvider.AUTHORITY + file.getRemotePath()));
+            sendIntent.putExtra(Intent.ACTION_SEND, true);      // Send Action
+
+            // Show dialog, without the own app
+            String[] packagesToExclude = new String[] { mFileActivity.getPackageName() };
+            DialogFragment chooserDialog = ShareLinkToDialog.newInstance(sendIntent, packagesToExclude, file);
+            chooserDialog.show(mFileActivity.getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
+        } else {
+            Log_OC.wtf(TAG, "Trying to send a NULL OCFile");
+        }
+    }
+
+    public void syncFiles(ArrayList<OCFile> files) {
+        for (OCFile file: files) {
+            syncFile(file);
+        }
+    }
+
     /**
      * Request the synchronization of a file or folder with the OC server, including its contents.
      *
@@ -350,6 +520,12 @@ public class FileOperationsHelper {
         }
     }
 
+    public void toggleFavorites(ArrayList<OCFile> files, boolean isFavorite){
+        for (OCFile file: files) {
+            toggleFavorite(file, isFavorite);
+        }
+    }
+
     public void toggleFavorite(OCFile file, boolean isFavorite) {
         file.setFavorite(isFavorite);
         mFileActivity.getStorageManager().saveFile(file);
@@ -449,8 +625,9 @@ public class FileOperationsHelper {
         service.putExtra(OperationsService.EXTRA_ACCOUNT, mFileActivity.getAccount());
         mWaitingForOpId =  mFileActivity.getOperationsServiceBinder().queueNewOperation(service);
 
-        mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
-                getString(R.string.wait_a_moment));
+        // TODO Tobi loading dialog?
+//        mFileActivity.showLoadingDialog(mFileActivity.getApplicationContext().
+//                getString(R.string.wait_a_moment));
     }
 
     /**
@@ -492,4 +669,5 @@ public class FileOperationsHelper {
         }
         return false;
     }
+
 }
index 47f7127..dc32ecc 100644 (file)
@@ -29,14 +29,16 @@ import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.FileStorageUtils;
 
-
 import android.accounts.Account;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo.State;
+import android.os.BatteryManager;
 import android.preference.PreferenceManager;
 import android.provider.MediaStore.Images;
 import android.provider.MediaStore.Video;
@@ -58,7 +60,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         Log_OC.d(TAG, "Received: " + intent.getAction());
-        if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {
+        if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION) || intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
             handleConnectivityAction(context, intent);
         }else if (intent.getAction().equals(NEW_PHOTO_ACTION_UNOFFICIAL)) {
             handleNewPictureAction(context, intent); 
@@ -103,7 +105,6 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         file_name = c.getString(c.getColumnIndex(Images.Media.DISPLAY_NAME));
         mime_type = c.getString(c.getColumnIndex(Images.Media.MIME_TYPE));
         c.close();
-        
         Log_OC.d(TAG, file_path + "");
 
         // save always temporally the picture to upload
@@ -111,7 +112,10 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         db.putFileForLater(file_path, account.name, null);
         db.close();
 
-        if (!isOnline(context) || (instantPictureUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))) {
+        if (!isOnline(context) 
+                || (instantPictureUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))
+                || (instantUploadWhenChargingOnly(context) && !isCharging(context))
+           ) {
             return;
         }
 
@@ -122,9 +126,34 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
         i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
         i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
+
+        // instant upload behaviour
+        i = addInstantUploadBehaviour(i, context);
+
         context.startService(i);
     }
 
+    private Intent addInstantUploadBehaviour(Intent i, Context context){
+        SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+        String behaviour = appPreferences.getString("prefs_instant_behaviour", "NOTHING");
+
+        if (behaviour.equalsIgnoreCase("NOTHING")) {
+            Log_OC.d(TAG, "upload file and do nothing");
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_FORGET);
+        } else if (behaviour.equalsIgnoreCase("COPY")) {
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_COPY);
+            Log_OC.d(TAG, "upload file and copy file to oc folder");
+        } else if (behaviour.equalsIgnoreCase("MOVE")) {
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
+            Log_OC.d(TAG, "upload file and move file to oc folder");
+        } else if (behaviour.equalsIgnoreCase("DELETE")){
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_REMOVE);
+            Log_OC.d(TAG, "upload file and delete file in original place");
+        }
+
+        return i;
+    }
+
     private void handleNewVideoAction(Context context, Intent intent) {
         Cursor c = null;
         String file_path = null;
@@ -155,8 +184,16 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         mime_type = c.getString(c.getColumnIndex(Video.Media.MIME_TYPE));
         c.close();
         Log_OC.d(TAG, file_path + "");
+        
+        // save always temporally the picture to upload
+        DbHandler db = new DbHandler(context);
+        db.putFileForLater(file_path, account.name, null);
+        db.close();
 
-        if (!isOnline(context) || (instantVideoUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))) {
+        if (!isOnline(context) 
+                || (instantVideoUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))
+                || (instantVideoUploadWhenChargingOnly(context) && !isCharging(context))
+           ) {
             return;
         }
 
@@ -167,23 +204,49 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
         i.putExtra(FileUploader.KEY_MIME_TYPE, mime_type);
         i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
+
+        // instant upload behaviour
+        i = addInstantUploadBehaviour(i, context);
+
         context.startService(i);
 
     }
 
     private void handleConnectivityAction(Context context, Intent intent) {
-        if (!instantPictureUploadEnabled(context)) {
+        if (!instantPictureUploadEnabled(context) && !instantVideoUploadEnabled(context)) {
             Log_OC.d(TAG, "Instant upload disabled, don't upload anything");
             return;
         }
 
+        if (instantPictureUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context)){
+            Account account = AccountUtils.getCurrentOwnCloudAccount(context);
+            if (account == null) {
+                Log_OC.w(TAG, "No owncloud account found for instant upload, aborting");
+                return;
+            }
+
+            Intent i = new Intent(context, FileUploader.class);
+            i.putExtra(FileUploader.KEY_ACCOUNT, account);
+            i.putExtra(FileUploader.KEY_CANCEL_ALL, true);
+            context.startService(i);
+        }
+
         if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY)
                 && isOnline(context)
-                && (!instantPictureUploadViaWiFiOnly(context) || (instantPictureUploadViaWiFiOnly(context) == isConnectedViaWiFi(context) == true))) {
+                && (!instantUploadWhenChargingOnly(context) || (instantUploadWhenChargingOnly(context) && isCharging(context)))
+                && (!instantVideoUploadWhenChargingOnly(context) || (instantVideoUploadWhenChargingOnly(context) && isCharging(context)))
+                && (!instantPictureUploadViaWiFiOnly(context) || (instantPictureUploadViaWiFiOnly(context) && isConnectedViaWiFi(context)))
+                && (!instantVideoUploadViaWiFiOnly(context) || (instantVideoUploadViaWiFiOnly(context) && isConnectedViaWiFi(context)))
+            ) {
             DbHandler db = new DbHandler(context);
             Cursor c = db.getAwaitingFiles();
             if (c.moveToFirst()) {
                 do {
+                    if (instantPictureUploadViaWiFiOnly(context) &&
+                            !isConnectedViaWiFi(context)){
+                        break;
+                    }
+
                     String account_name = c.getString(c.getColumnIndex("account"));
                     String file_path = c.getString(c.getColumnIndex("path"));
                     File f = new File(file_path);
@@ -207,6 +270,10 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
                         i.putExtra(FileUploader.KEY_REMOTE_FILE, FileStorageUtils.getInstantUploadFilePath(context, f.getName()));
                         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
                         i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
+
+                        // instant upload behaviour
+                        i = addInstantUploadBehaviour(i, context);
+
                         context.startService(i);
 
                     } else {
@@ -217,7 +284,6 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
             c.close();
             db.close();
         }
-
     }
 
     public static boolean isOnline(Context context) {
@@ -231,6 +297,18 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
                 && cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI
                 && cm.getActiveNetworkInfo().getState() == State.CONNECTED;
     }
+    
+    public static boolean isCharging(Context context){
+        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        Intent batteryStatus = context.registerReceiver(null, ifilter);
+
+        int status = 0;
+        if (batteryStatus != null) {
+            status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
+        }
+        return status == BatteryManager.BATTERY_STATUS_CHARGING ||
+                status == BatteryManager.BATTERY_STATUS_FULL;
+    }
 
     public static boolean instantPictureUploadEnabled(Context context) {
         return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false);
@@ -247,4 +325,10 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
     public static boolean instantVideoUploadViaWiFiOnly(Context context) {
         return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_video_upload_on_wifi", false);
     }
+    public static boolean instantUploadWhenChargingOnly(Context context) {
+        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_upload_on_charging", false);
+    }
+    public static boolean instantVideoUploadWhenChargingOnly(Context context) {
+        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_video_upload_on_charging", false);
+    }
 }
index 7c953b8..9bc2742 100644 (file)
@@ -98,9 +98,12 @@ public class FileUploader extends Service
     public static final String KEY_INSTANT_UPLOAD = "INSTANT_UPLOAD";
     public static final String KEY_LOCAL_BEHAVIOUR = "BEHAVIOUR";
 
+    public static final String KEY_CANCEL_ALL = "CANCEL_ALL";
+
     public static final int LOCAL_BEHAVIOUR_COPY = 0;
     public static final int LOCAL_BEHAVIOUR_MOVE = 1;
     public static final int LOCAL_BEHAVIOUR_FORGET = 2;
+    public static final int LOCAL_BEHAVIOUR_REMOVE = 3;
 
     public static final int UPLOAD_SINGLE_FILE = 0;
     public static final int UPLOAD_MULTIPLE_FILES = 1;
@@ -194,6 +197,21 @@ public class FileUploader extends Service
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log_OC.d(TAG, "Starting command with id " + startId);
 
+        if (intent.hasExtra(KEY_CANCEL_ALL) && intent.hasExtra(KEY_ACCOUNT)){
+            Account account = intent.getParcelableExtra(KEY_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
+            cancelUploadsForAccount(account);
+        }
+
         if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_UPLOAD_TYPE)
                 || !(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) {
             Log_OC.e(TAG, "Not enough information provided in intent");
index e53c635..d6fbfcc 100644 (file)
 package com.owncloud.android.media;
 
 import android.accounts.Account;
+import android.app.Activity;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.media.AudioManager;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaPlayer.OnPreparedListener;
+import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.IBinder;
 import android.os.PowerManager;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.NotificationCompat;
 import android.widget.Toast;
 
 import java.io.IOException;
 
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
@@ -123,7 +129,6 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
 
     /** Notification to keep in the notification bar while a song is playing */
     private NotificationManager mNotificationManager;
-    private Notification mNotification = null;
 
     /** File being played */
     private OCFile mFile;
@@ -142,8 +147,9 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
 
     /** Control panel shown to the user to control the playback, to register through binding */
     private MediaControlView mMediaController;
-    
 
+    /** Notification builder to create notifications, new reuse way since Android 6 */
+    private NotificationCompat.Builder mNotificationBuilder;
     
     /**
      * Helper method to get an error message suitable to show to users for errors occurred in media playback,
@@ -210,6 +216,25 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
         return context.getString(messageId);
     }
 
+    public static AlertDialog.Builder streamWithExternalApp(final String uri, final Activity activity){
+        AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+        builder.setMessage(activity.getString(R.string.stream_expose_password))
+                .setPositiveButton(activity.getString(R.string.common_yes),
+                                   new DialogInterface.OnClickListener() {
+                                        public void onClick(DialogInterface dialog, int id) {
+                                            Intent i = new Intent(Intent.ACTION_VIEW);
+                                            i.setData(Uri.parse(uri));
+                                            activity.startActivity(i);
+                                        }
+                                    })
+                .setNegativeButton(activity.getString(R.string.common_no), new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int id) {
+                        // User cancelled the dialog
+                    }
+                });
+        return builder;
+    }
+
 
     
     /**
@@ -226,6 +251,8 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
                 createWifiLock(WifiManager.WIFI_MODE_FULL, MEDIA_WIFI_LOCK_TAG);
 
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+        mNotificationBuilder = new NotificationCompat.Builder(this);
+        mNotificationBuilder.setColor(this.getResources().getColor(R.color.primary));
         mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
         mBinder = new MediaServiceBinder(this);
     }
@@ -286,7 +313,6 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
             mState = State.PLAYING;
             setUpAsForeground(String.format(getString(R.string.media_state_playing), mFile.getFileName()));
             configAndStartMediaPlayer();
-            
         }
     }
 
@@ -430,12 +456,7 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
         releaseResources(false); // release everything except MediaPlayer
 
         try {
-            if (mFile == null) { 
-                Toast.makeText(this, R.string.media_err_nothing_to_play, Toast.LENGTH_LONG).show();
-                processStopRequest(true);
-                return;
-                
-            } else if (mAccount == null) {
+            if (mAccount == null) {
                 Toast.makeText(this, R.string.media_err_not_in_owncloud, Toast.LENGTH_LONG).show();
                 processStopRequest(true);
                 return;
@@ -444,12 +465,12 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
             createMediaPlayerIfNeeded();
             mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
             String url = mFile.getStoragePath();
-            /* Streaming is not possible right now
+
             if (url == null || url.length() <= 0) {
                 url = AccountUtils.constructFullURLForAccount(this, mAccount) + mFile.getRemotePath();
             }
             mIsStreaming = url.startsWith("http:") || url.startsWith("https:");
-            */
+
             mIsStreaming = false;
             
             mPlayer.setDataSource(url);
@@ -486,6 +507,8 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
             Log_OC.e(TAG, "IllegalArgumentException " + mAccount.name + mFile.getRemotePath(), e);
             Toast.makeText(this, String.format(getString(R.string.media_err_unexpected), mFile.getFileName()), Toast.LENGTH_LONG).show();
             processStopRequest(true);
+        } catch (AccountUtils.AccountNotFoundException e) {
+            e.printStackTrace();
         }
     }
 
@@ -532,22 +555,25 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
     /** 
      * Updates the status notification
      */
-    @SuppressWarnings("deprecation")
     private void updateNotification(String content) {
+        String ticker = String.format(getString(R.string.media_notif_ticker), getString(R.string.app_name));
+
         // TODO check if updating the Intent is really necessary
         Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class);
         showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, mFile);
         showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount);
         showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 
-                                                                (int)System.currentTimeMillis(), 
-                                                                showDetailsIntent, 
-                                                                PendingIntent.FLAG_UPDATE_CURRENT);
-        mNotification.when = System.currentTimeMillis();
-        //mNotification.contentView.setTextViewText(R.id.status_text, content);
-        String ticker = String.format(getString(R.string.media_notif_ticker), getString(R.string.app_name));
-        mNotification.setLatestEventInfo(getApplicationContext(), ticker, content, mNotification.contentIntent);
-        mNotificationManager.notify(R.string.media_notif_ticker, mNotification);
+
+        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(getApplicationContext(),
+                (int) System.currentTimeMillis(),
+                showDetailsIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT));
+        mNotificationBuilder.setWhen(System.currentTimeMillis());
+        mNotificationBuilder.setTicker(ticker);
+        mNotificationBuilder.setContentTitle(ticker);
+        mNotificationBuilder.setContentText(content);
+
+        mNotificationManager.notify(R.string.media_notif_ticker, mNotificationBuilder.build());
     }
 
     
@@ -558,35 +584,29 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
      * 
      * A notification must be created to keep the user aware of the existance of the service.
      */
-    @SuppressWarnings("deprecation")
     private void setUpAsForeground(String content) {
+        String ticker = String.format(getString(R.string.media_notif_ticker), getString(R.string.app_name));
+
         /// creates status notification
         // TODO put a progress bar to follow the playback progress
-        mNotification = new Notification();
-        mNotification.icon = android.R.drawable.ic_media_play;
+        mNotificationBuilder.setSmallIcon(R.drawable.ic_play_arrow);
         //mNotification.tickerText = text;
-        mNotification.when = System.currentTimeMillis();
-        mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
-        //mNotification.contentView.setTextViewText(R.id.status_text, "ownCloud Music Player");     // NULL POINTER
-        //mNotification.contentView.setTextViewText(R.id.status_text, getString(R.string.downloader_download_in_progress_content));
-
+        mNotificationBuilder.setWhen(System.currentTimeMillis());
+        mNotificationBuilder.setOngoing(true);
         
         /// includes a pending intent in the notification showing the details view of the file
         Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class);
         showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, mFile);
         showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, mAccount);
         showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 
-                                                                (int)System.currentTimeMillis(), 
-                                                                showDetailsIntent, 
-                                                                PendingIntent.FLAG_UPDATE_CURRENT);
-        
-        
-        //mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotification);
-        String ticker = String.format(getString(R.string.media_notif_ticker), getString(R.string.app_name));
-        mNotification.setLatestEventInfo(getApplicationContext(), ticker, content, mNotification.contentIntent);
-        startForeground(R.string.media_notif_ticker, mNotification);
-        
+        mNotificationBuilder.setContentIntent(PendingIntent.getActivity(getApplicationContext(),
+                (int) System.currentTimeMillis(),
+                showDetailsIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT));
+        mNotificationBuilder.setContentTitle(ticker);
+        mNotificationBuilder.setContentText(content);
+
+        startForeground(R.string.media_notif_ticker, mNotificationBuilder.build());
     }
 
     /**
@@ -639,6 +659,7 @@ public class MediaService extends Service implements OnCompletionListener, OnPre
         mState = State.STOPPED;
         releaseResources(true);
         giveUpAudioFocus();
+        stopForeground(true);
         super.onDestroy();
     }
     
index b020b92..0b3343c 100644 (file)
@@ -121,4 +121,8 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
             Log_OC.d(TAG, "Create directory " + mRemotePath + " in Database");
         }
     }
+
+    public String getRemotePath() {
+        return mRemotePath;
+    }
 }
index 373c57d..e9cb7d2 100644 (file)
@@ -30,7 +30,6 @@ import android.content.Context;
 import android.content.Intent;
 
 import com.owncloud.android.R;
-import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -42,9 +41,9 @@ import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
 import com.owncloud.android.operations.common.SyncOperation;
 
-public class CreateShareViaLinkOperation extends SyncOperation {
+import java.util.ArrayList;
 
-    protected FileDataStorageManager mStorageManager;
+public class CreateShareViaLinkOperation extends SyncOperation {
 
     private String mPath;
     private String mPassword;
@@ -76,10 +75,21 @@ public class CreateShareViaLinkOperation extends SyncOperation {
         // Check if the share link already exists
         RemoteOperation operation = new GetRemoteSharesForFileOperation(mPath, false, false);
         RemoteOperationResult result = operation.execute(client);
-        // TODO - fix this check; if the user already shared the file with users or group, a share via link will not be created
 
-        if (!result.isSuccess() || result.getData().size() <= 0) {
-            operation = new CreateRemoteShareOperation(
+        boolean shareByLink = false;
+        // Check if the file is shared by link
+        if (result.isSuccess() && result.getData().size() > 0){
+            ArrayList<Object> shares = result.getData();
+            for(Object object: shares){
+                if (((OCShare) object).getShareType() == ShareType.PUBLIC_LINK){
+                    shareByLink = true;
+                    break;
+                }
+            }
+        }
+
+        if (!result.isSuccess() || !shareByLink) {
+            CreateRemoteShareOperation createOp = new CreateRemoteShareOperation(
                     mPath,
                     ShareType.PUBLIC_LINK,
                     "",
@@ -87,7 +97,8 @@ public class CreateShareViaLinkOperation extends SyncOperation {
                     mPassword,
                     OCShare.DEFAULT_PERMISSION
             );
-            result = operation.execute(client);
+            createOp.setGetShareDetails(true);
+            result = createOp.execute(client);
         }
         
         if (result.isSuccess()) {
@@ -148,10 +159,12 @@ public class CreateShareViaLinkOperation extends SyncOperation {
         // Update OCFile with data from share: ShareByLink  and publicLink
         OCFile file = getStorageManager().getFileByPath(mPath);
         if (file!=null) {
-            mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink());
             file.setPublicLink(share.getShareLink());
             file.setShareViaLink(true);
             getStorageManager().saveFile(file);
+            if (mSendIntent != null) {
+                mSendIntent.putExtra(Intent.EXTRA_TEXT, share.getShareLink());
+            }
         }
     }
 
index 62c3be1..a04d415 100644 (file)
@@ -72,6 +72,11 @@ public class GetSharesForFileOperation extends SyncOperation {
             }
 
             getStorageManager().saveSharesDB(shares);
+
+        } else if (result.getCode() == RemoteOperationResult.ResultCode.SHARE_NOT_FOUND) {
+            // no share on the file - remove local shares
+            getStorageManager().removeSharesForFile(mPath);
+
         }
 
         return result;
index 71baf23..f9f9e8c 100644 (file)
@@ -197,7 +197,7 @@ public class RefreshFolderOperation extends RemoteOperation {
                 result = fetchAndSyncRemoteFolder(client);
             } else {
                 fetchFavoritesToSyncFromLocalData();
-                mChildren = mStorageManager.getFolderContent(mLocalFolder/*, false*/);
+                mChildren = mStorageManager.getFolderContent(mLocalFolder, false);
             }
 
             if (result.isSuccess()) {
@@ -246,7 +246,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         GetCapabilitiesOperarion getCapabilities = new GetCapabilitiesOperarion();
         RemoteOperationResult  result = getCapabilities.execute(mStorageManager,mContext);
         if (!result.isSuccess()){
-            Log_OC.d(TAG, "Update Capabilities unsuccessfully");
+            Log_OC.w(TAG, "Update Capabilities unsuccessfully");
         }
     }
 
@@ -361,8 +361,7 @@ public class RefreshFolderOperation extends RemoteOperation {
         mFilesToSyncContents.clear();
 
         // get current data about local contents of the folder to synchronize
-        // TODO Enable when "On Device" is recovered ?
-        List<OCFile> localFiles = mStorageManager.getFolderContent(mLocalFolder/*, false*/);
+        List<OCFile> localFiles = mStorageManager.getFolderContent(mLocalFolder, false);
         Map<String, OCFile> localFilesMap = new HashMap<String, OCFile>(localFiles.size());
         for (OCFile file : localFiles) {
             localFilesMap.put(file.getRemotePath(), file);
@@ -525,7 +524,7 @@ public class RefreshFolderOperation extends RemoteOperation {
 
 
     private void fetchFavoritesToSyncFromLocalData() {
-        List<OCFile> children = mStorageManager.getFolderContent(mLocalFolder);
+        List<OCFile> children = mStorageManager.getFolderContent(mLocalFolder, false);
         for (OCFile child : children) {
             if (!child.isFolder() && child.isFavorite()) {
                 SynchronizeFileOperation operation = new SynchronizeFileOperation(
index 675295a..227e2b2 100644 (file)
@@ -294,8 +294,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
         }
 
         // get current data about local contents of the folder to synchronize
-        // TODO Enable when "On Device" is recovered ?
-        List<OCFile> localFiles = storageManager.getFolderContent(mLocalFolder/*, false*/);
+        List<OCFile> localFiles = storageManager.getFolderContent(mLocalFolder, false);
         Map<String, OCFile> localFilesMap = new HashMap<String, OCFile>(localFiles.size());
         for (OCFile file : localFiles) {
             localFilesMap.put(file.getRemotePath(), file);
@@ -383,8 +382,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
     
     
     private void prepareOpsFromLocalKnowledge() throws OperationCancelledException {
-        // TODO Enable when "On Device" is recovered ?
-        List<OCFile> children = getStorageManager().getFolderContent(mLocalFolder/*, false*/);
+        List<OCFile> children = getStorageManager().getFolderContent(mLocalFolder, false);
         for (OCFile child : children) {
             /// classify file to sync/download contents later
             if (child.isFolder()) {
index 4167831..d819abf 100644 (file)
@@ -69,11 +69,11 @@ public class UnshareOperation extends SyncOperation {
         if (share != null) {
             OCFile file = getStorageManager().getFileByPath(mRemotePath);
             RemoveRemoteShareOperation operation =
-                    new RemoveRemoteShareOperation((int) share.getIdRemoteShared());
+                    new RemoveRemoteShareOperation((int) share.getRemoteId());
             result = operation.execute(client);
 
             if (result.isSuccess()) {
-                Log_OC.d(TAG, "Share id = " + share.getIdRemoteShared() + " deleted");
+                Log_OC.d(TAG, "Share id = " + share.getRemoteId() + " deleted");
 
                 if (mShareType == ShareType.PUBLIC_LINK) {
                     file.setShareViaLink(false);
diff --git a/src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java b/src/com/owncloud/android/operations/UpdateShareViaLinkOperation.java
new file mode 100644 (file)
index 0000000..14b60e8
--- /dev/null
@@ -0,0 +1,152 @@
+/**
+ *   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.operations;
+
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.operations.RemoteOperation;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.resources.files.FileUtils;
+import com.owncloud.android.lib.resources.shares.GetRemoteShareOperation;
+import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.lib.resources.shares.ShareType;
+import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation;
+import com.owncloud.android.operations.common.SyncOperation;
+
+import java.util.Calendar;
+
+
+/**
+ * Updates an existing public share for a given file
+ */
+
+public class UpdateShareViaLinkOperation extends SyncOperation {
+
+    private String mPath;
+    private String mPassword;
+    private long mExpirationDateInMillis;
+
+    /**
+     * Constructor
+     *
+     * @param path          Full path of the file/folder being shared. Mandatory argument
+     */
+    public UpdateShareViaLinkOperation(String path) {
+
+        mPath = path;
+        mPassword = null;
+        mExpirationDateInMillis = 0;
+    }
+
+
+    /**
+     * Set password to update in public link.
+     *
+     * @param password      Password to set to the public link.
+     *                      Empty string clears the current password.
+     *                      Null results in no update applied to the password.
+     */
+    public void setPassword(String password) {
+        mPassword = password;
+    }
+
+
+    /**
+     * Set expiration date to update in Share resource.
+     *
+     * @param expirationDateInMillis    Expiration date to set to the public link.
+     *                                  A negative value clears the current expiration date.
+     *                                  Zero value (start-of-epoch) results in no update done on
+     *                                  the expiration date.
+     */
+    public void setExpirationDate(long expirationDateInMillis) {
+        mExpirationDateInMillis = expirationDateInMillis;
+    }
+
+
+    @Override
+    protected RemoteOperationResult run(OwnCloudClient client) {
+
+        OCShare publicShare = getStorageManager().getFirstShareByPathAndType(
+                mPath,
+                ShareType.PUBLIC_LINK,
+                ""
+        );
+
+        if (publicShare == null) {
+            // TODO try to get remote share before failing?
+            return new RemoteOperationResult(
+                    RemoteOperationResult.ResultCode.SHARE_NOT_FOUND
+            );
+        }
+
+        // Update remote share with password
+        UpdateRemoteShareOperation udpateOp = new UpdateRemoteShareOperation(
+            publicShare.getRemoteId()
+        );
+        udpateOp.setPassword(mPassword);
+        udpateOp.setExpirationDate(mExpirationDateInMillis);
+        RemoteOperationResult result = udpateOp.execute(client);
+
+        if (result.isSuccess()) {
+            // Retrieve updated share / save directly with password? -> no; the password is not be saved
+            RemoteOperation getShareOp = new GetRemoteShareOperation(publicShare.getRemoteId());
+            result = getShareOp.execute(client);
+            if (result.isSuccess()) {
+                OCShare share = (OCShare) result.getData().get(0);
+                updateData(share);
+            }
+        }
+
+        return result;
+    }
+
+    public String getPath() {
+        return mPath;
+    }
+
+    public String getPassword() {
+        return mPassword;
+    }
+
+    private void updateData(OCShare share) {
+        // Update DB with the response
+        share.setPath(mPath);
+        if (mPath.endsWith(FileUtils.PATH_SEPARATOR)) {
+            share.setIsFolder(true);
+        } else {
+            share.setIsFolder(false);
+        }
+
+        getStorageManager().saveShare(share);   // TODO info about having a password? ask to Gonzalo
+
+        // Update OCFile with data from share: ShareByLink  and publicLink
+        // TODO check & remove if not needed
+        OCFile file = getStorageManager().getFileByPath(mPath);
+        if (file != null) {
+            file.setPublicLink(share.getShareLink());
+            file.setShareViaLink(true);
+            getStorageManager().saveFile(file);
+        }
+    }
+
+}
+
index ee9f7c8..512056b 100644 (file)
@@ -26,6 +26,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.channels.FileChannel;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
@@ -39,6 +40,7 @@ import android.content.Context;
 import android.net.Uri;
 
 import com.owncloud.android.MainApp;
+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.OwnCloudClient;
@@ -331,7 +333,9 @@ public class UploadFileOperation extends RemoteOperation {
             if (result.isSuccess()) {
                 if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_FORGET) {
                     mFile.setStoragePath(null);
-
+                } else if (mLocalBehaviour == FileUploader.LOCAL_BEHAVIOUR_REMOVE){
+                    mFile.setStoragePath(null);
+                    originalFile.delete();
                 } else {
                     mFile.setStoragePath(expectedPath);
                     File fileToMove = null;
@@ -345,21 +349,42 @@ public class UploadFileOperation extends RemoteOperation {
                     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 (expectedFolder.isDirectory()){
+                            if (!fileToMove.renameTo(expectedFile)){
+                                // try to copy and then delete
+                                expectedFile.createNewFile();
+                                FileChannel inChannel = new FileInputStream(fileToMove).getChannel();
+                                FileChannel outChannel = new FileOutputStream(expectedFile).getChannel();
+
+                                try {
+                                    inChannel.transferTo(0, inChannel.size(), outChannel);
+                                    fileToMove.delete();
+                                } catch (Exception e){
+                                    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;
+                                }
+                                finally {
+                                    if (inChannel != null) inChannel.close();
+                                    if (outChannel != null) outChannel.close();
+                                }
+                            }
+
+                        } else {
+                            mFile.setStoragePath(null);
                         }
                     }
                 }
-
+                FileDataStorageManager.triggerMediaScan(originalFile.getAbsolutePath());
+                FileDataStorageManager.triggerMediaScan(expectedFile.getAbsolutePath());
             } else if (result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED ) {
                 result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
             }
@@ -371,6 +396,9 @@ public class UploadFileOperation extends RemoteOperation {
             if (temporalFile != null && !originalFile.equals(temporalFile)) {
                 temporalFile.delete();
             }
+            if (result == null){
+                return new RemoteOperationResult(false, 404, null);
+            }
             if (result.isSuccess()) {
                 Log_OC.i(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " +
                         result.getLogMessage());
index eff8e03..b8658c9 100644 (file)
@@ -64,9 +64,11 @@ import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
 import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.UnshareOperation;
+import com.owncloud.android.operations.UpdateShareViaLinkOperation;
 import com.owncloud.android.operations.common.SyncOperation;
 
 import java.io.IOException;
+import java.util.Calendar;
 import java.util.Iterator;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -88,15 +90,19 @@ 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";
+    public static final String EXTRA_SHARE_PASSWORD = "SHARE_PASSWORD";
     public static final String EXTRA_SHARE_TYPE = "SHARE_TYPE";
     public static final String EXTRA_SHARE_WITH = "SHARE_WITH";
+    public static final String EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS = "SHARE_EXPIRATION_YEAR";
+    public static final String EXTRA_SHARE_EXPIRATION_MONTH_OF_YEAR = "SHARE_EXPIRATION_MONTH_OF_YEAR";
+    public static final String EXTRA_SHARE_EXPIRATION_DAY_OF_MONTH = "SHARE_EXPIRATION_DAY_OF_MONTH";
 
     public static final String EXTRA_COOKIE = "COOKIE";
 
     public static final String ACTION_CREATE_SHARE_VIA_LINK = "CREATE_SHARE_VIA_LINK";
     public static final String ACTION_CREATE_SHARE_WITH_SHAREE = "CREATE_SHARE_WITH_SHAREE";
     public static final String ACTION_UNSHARE = "UNSHARE";
+    public static final String ACTION_UPDATE_SHARE = "UPDATE_SHARE";
     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_GET_USER_NAME = "GET_USER_NAME";
@@ -553,7 +559,7 @@ public class OperationsService extends Service {
                 String action = operationIntent.getAction();
                 if (action.equals(ACTION_CREATE_SHARE_VIA_LINK)) {  // Create public share via link
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                    String password = operationIntent.getStringExtra(EXTRA_PASSWORD_SHARE);
+                    String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
                     Intent sendIntent = operationIntent.getParcelableExtra(EXTRA_SEND_INTENT);
                     if (remotePath.length() > 0) {
                         operation = new CreateShareViaLinkOperation(
@@ -563,17 +569,35 @@ public class OperationsService extends Service {
                         );
                     }
 
-                } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) {  // Create private share with user or group
-                        String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
-                        String shareeName = operationIntent.getStringExtra(EXTRA_SHARE_WITH);
-                        ShareType shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE);
-                        if (remotePath.length() > 0) {
-                            operation = new CreateShareWithShareeOperation(
-                                    remotePath,
-                                    shareeName,
-                                    shareType
-                            );
-                        }
+                } else if (ACTION_UPDATE_SHARE.equals(action)) {
+                    String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+                    if (remotePath.length() > 0) {
+                        operation = new UpdateShareViaLinkOperation(remotePath);
+
+                        String password = operationIntent.getStringExtra(EXTRA_SHARE_PASSWORD);
+                        ((UpdateShareViaLinkOperation)operation).setPassword(password);
+
+                        long expirationDate = operationIntent.getLongExtra(
+                                EXTRA_SHARE_EXPIRATION_DATE_IN_MILLIS,
+                                0
+                        );
+                        ((UpdateShareViaLinkOperation)operation).setExpirationDate(
+                                expirationDate
+                        );
+                    }
+
+                } else if (action.equals(ACTION_CREATE_SHARE_WITH_SHAREE)) {
+                    // Create private share with user or group
+                    String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
+                    String shareeName = operationIntent.getStringExtra(EXTRA_SHARE_WITH);
+                    ShareType shareType = (ShareType) operationIntent.getSerializableExtra(EXTRA_SHARE_TYPE);
+                    if (remotePath.length() > 0) {
+                        operation = new CreateShareWithShareeOperation(
+                                remotePath,
+                                shareeName,
+                                shareType
+                        );
+                    }
 
                 } else if (action.equals(ACTION_UNSHARE)) {  // Unshare file
                     String remotePath = operationIntent.getStringExtra(EXTRA_REMOTE_PATH);
diff --git a/src/com/owncloud/android/ui/activity/ErrorReportActivity.java b/src/com/owncloud/android/ui/activity/ErrorReportActivity.java
new file mode 100644 (file)
index 0000000..d9b5ba0
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ *   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.activity;
+
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.app.AppCompatActivity;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.owncloud.android.R;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.ui.dialog.LoadingDialog;
+import com.owncloud.android.utils.FileStorageUtils;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+
+
+public class ErrorReportActivity extends AppCompatActivity {
+
+    private static final String TAG = ErrorReportActivity.class.getSimpleName();
+
+    private String mLogText;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.error_send);
+        setTitle(getString(R.string.error_log_title));
+        Button cancelErrorLogButton = (Button) findViewById(R.id.cancelErrorLogButton);
+        Button sendErrorLogButton = (Button) findViewById(R.id.sendErrorLogButton);
+        TextView logTV = (TextView) findViewById(R.id.logTV);
+
+        Intent intent = getIntent();
+        String action = intent.getAction();
+        String type = intent.getType();
+
+        if (Intent.ACTION_SEND.equals(action) && type != null) {
+                mLogText = intent.getStringExtra(Intent.EXTRA_TEXT);
+        } else {
+            // Handle other intents, such as being started from the home screen
+            mLogText = "Error, nothing received!";
+        }
+
+        logTV.setText(mLogText);
+
+        cancelErrorLogButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                finishAffinity();
+
+            }
+        });
+
+        sendErrorLogButton.setOnClickListener(new OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                sendMail();
+            }
+        });
+    }
+
+    /**
+     * Start activity for sending email with logs attached
+     */
+    private void sendMail() {
+        Intent sendIntent = new Intent();
+        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.putExtra(Intent.EXTRA_TEXT, mLogText);
+        sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        sendIntent.setType("text/plain");
+        startActivity(sendIntent);
+    }
+}
\ No newline at end of file
index 7dc13b9..8a79443 100644 (file)
@@ -67,12 +67,14 @@ import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.operations.CreateShareViaLinkOperation;
 import com.owncloud.android.operations.CreateShareWithShareeOperation;
 import com.owncloud.android.operations.GetSharesForFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
 import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.UnshareOperation;
+import com.owncloud.android.operations.UpdateShareViaLinkOperation;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.services.OperationsService.OperationsServiceBinder;
 import com.owncloud.android.ui.NavigationDrawerItem;
@@ -93,8 +95,6 @@ public class FileActivity extends AppCompatActivity
 
     public static final String EXTRA_FILE = "com.owncloud.android.ui.activity.FILE";
     public static final String EXTRA_ACCOUNT = "com.owncloud.android.ui.activity.ACCOUNT";
-    public static final String EXTRA_WAITING_TO_PREVIEW =
-            "com.owncloud.android.ui.activity.WAITING_TO_PREVIEW";
     public static final String EXTRA_FROM_NOTIFICATION =
             "com.owncloud.android.ui.activity.FROM_NOTIFICATION";
 
@@ -113,9 +113,13 @@ public class FileActivity extends AppCompatActivity
     /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located.*/
     private Account mAccount;
 
-    /** Main {@link OCFile} handled by the activity.*/
+    /** Capabilites of the server where {@link #mAccount} lives */
+     private OCCapability mCapabilities;
+
+     /** Main {@link OCFile} handled by the activity.*/
     private OCFile mFile;
 
+
     /** Flag to signal that the activity will is finishing to enforce the creation of an ownCloud
      * {@link Account} */
     private boolean mRedirectingToSetupAccount = false;
@@ -141,12 +145,12 @@ public class FileActivity extends AppCompatActivity
 
     private OperationsServiceBinder mOperationsServiceBinder = null;
 
+    private boolean mResumed = false;
+
     protected FileDownloaderBinder mDownloaderBinder = null;
     protected FileUploaderBinder mUploaderBinder = null;
     private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
 
-    private boolean mTryShareAgain = false;
-
     // Navigation Drawer
     protected DrawerLayout mDrawerLayout;
     protected ActionBarDrawerToggle mDrawerToggle;
@@ -161,6 +165,7 @@ public class FileActivity extends AppCompatActivity
     protected NavigationDrawerListAdapter mNavigationDrawerAdapter = null;
 
 
+
     // TODO re-enable when "Accounts" is available in Navigation Drawer
 //    protected boolean mShowAccounts = false;
 
@@ -183,7 +188,6 @@ public class FileActivity extends AppCompatActivity
             mFileOperationsHelper.setOpIdWaitingFor(
                     savedInstanceState.getLong(KEY_WAITING_FOR_OP_ID, Long.MAX_VALUE)
                     );
-            mTryShareAgain = savedInstanceState.getBoolean(KEY_TRY_SHARE_AGAIN);
             if (getSupportActionBar() != null) {
                 getSupportActionBar().setTitle(savedInstanceState.getString(KEY_ACTION_BAR_TITLE));
             }
@@ -255,7 +259,7 @@ public class FileActivity extends AppCompatActivity
     @Override
     protected void onResume() {
         super.onResume();
-
+        mResumed = true;
         if (mOperationsServiceBinder != null) {
             doOnResumeAndBound();
         }
@@ -266,7 +270,7 @@ public class FileActivity extends AppCompatActivity
         if (mOperationsServiceBinder != null) {
             mOperationsServiceBinder.removeOperationListener(this);
         }
-
+        mResumed = false;
         super.onPause();
     }
 
@@ -387,18 +391,17 @@ public class FileActivity extends AppCompatActivity
         mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[0], mDrawerContentDescriptions[0],
                 R.drawable.ic_folder_open));
 
-        // TODO Enable when "On Device" is recovered
         // On Device
-        //mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2],
-        //        mDrawerContentDescriptions[2]));
+        mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[1], mDrawerContentDescriptions[1],
+                R.drawable.ic_action_download_grey));
 
         // Settings
-        mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[1], mDrawerContentDescriptions[1],
-                R.drawable.ic_settings));
+        mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2], mDrawerContentDescriptions[2],
+                R.drawable.ic_action_settings));
         // Logs
         if (BuildConfig.DEBUG) {
-            mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2],
-                    mDrawerContentDescriptions[2],R.drawable.ic_log));
+            mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[3],
+                    mDrawerContentDescriptions[3],R.drawable.ic_log));
         }
 
         // setting the nav drawer list adapter
@@ -564,7 +567,6 @@ public class FileActivity extends AppCompatActivity
         outState.putParcelable(FileActivity.EXTRA_FILE, mFile);
         outState.putBoolean(FileActivity.EXTRA_FROM_NOTIFICATION, mFromNotification);
         outState.putLong(KEY_WAITING_FOR_OP_ID, mFileOperationsHelper.getOpIdWaitingFor());
-        outState.putBoolean(KEY_TRY_SHARE_AGAIN, mTryShareAgain);
         if(getSupportActionBar() != null && getSupportActionBar().getTitle() != null) {
             // Null check in case the actionbar is used in ActionBar.NAVIGATION_MODE_LIST
             // since it doesn't have a title then
@@ -608,6 +610,18 @@ public class FileActivity extends AppCompatActivity
         mAccount = account;
     }
 
+
+    /**
+     * Getter for the capabilities of the server where the current OC account lives.
+     *
+     * @return  Capabilities of the server where the current OC account lives. Null if the account is not
+     *          set yet.
+     */
+    public OCCapability getCapabilities() {
+        return mCapabilities;
+    }
+
+
     /**
      * @return Value of mFromNotification: True if the Activity is launched by a notification
      */
@@ -622,14 +636,6 @@ public class FileActivity extends AppCompatActivity
         return mRedirectingToSetupAccount;
     }
 
-    public boolean isTryShareAgain(){
-        return mTryShareAgain;
-    }
-
-    public void setTryShareAgain(boolean tryShareAgain) {
-       mTryShareAgain = tryShareAgain;
-    }
-
     public OperationsServiceBinder getOperationsServiceBinder() {
         return mOperationsServiceBinder;
     }
@@ -686,6 +692,7 @@ public class FileActivity extends AppCompatActivity
     protected void onAccountSet(boolean stateWasRecovered) {
         if (getAccount() != null) {
             mStorageManager = new FileDataStorageManager(getAccount(), getContentResolver());
+            mCapabilities = mStorageManager.getCapability(mAccount.name);
 
         } else {
             Log_OC.wtf(TAG, "onAccountChanged was called with NULL account associated!");
@@ -740,12 +747,12 @@ public class FileActivity extends AppCompatActivity
                         Toast.LENGTH_LONG);
                 t.show();
             }
-            mTryShareAgain = false;
 
         } else if (operation == null ||
                 operation instanceof CreateShareWithShareeOperation ||
                 operation instanceof UnshareOperation ||
-                operation instanceof SynchronizeFolderOperation
+                operation instanceof SynchronizeFolderOperation ||
+                operation instanceof UpdateShareViaLinkOperation
                 ) {
             if (result.isSuccess()) {
                 updateFileFromDB();
@@ -764,10 +771,10 @@ public class FileActivity extends AppCompatActivity
             onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result);
 
         } else if (operation instanceof GetSharesForFileOperation) {
-            if (result.isSuccess()) {
+            if (result.isSuccess() || result.getCode() == ResultCode.SHARE_NOT_FOUND) {
                 updateFileFromDB();
 
-            } else if (result.getCode() != ResultCode.SHARE_NOT_FOUND) {
+            } else {
                 Toast t = Toast.makeText(this,
                         ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
                         Toast.LENGTH_LONG);
@@ -791,25 +798,31 @@ public class FileActivity extends AppCompatActivity
     private void onCreateShareViaLinkOperationFinish(CreateShareViaLinkOperation operation,
                                                      RemoteOperationResult result) {
         if (result.isSuccess()) {
-            mTryShareAgain = false;
             updateFileFromDB();
 
             Intent sendIntent = operation.getSendIntentWithSubject(this);
-            startActivity(sendIntent);
+            if (sendIntent != null) {
+                startActivity(sendIntent);
+            }
+
         } else {
             // Detect Failure (403) --> needs Password
             if (result.getCode() == ResultCode.SHARE_FORBIDDEN) {
-                if (!isTryShareAgain()) {
+                String password = operation.getPassword();
+                if ((password == null || password.length() == 0) &&
+                    getCapabilities().getFilesSharingPublicEnabled().isUnknown())
+                    {
+                    // Was tried without password, but not sure that it's optional. Try with password.
+                    // Try with password before giving up.
+                    // See also ShareFileFragment#OnShareViaLinkListener
                     SharePasswordDialogFragment dialog =
-                            SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()),
-                                    operation.getSendIntent());
+                            SharePasswordDialogFragment.newInstance(new OCFile(operation.getPath()), true);
                     dialog.show(getSupportFragmentManager(), DIALOG_SHARE_PASSWORD);
                 } else {
                     Toast t = Toast.makeText(this,
                         ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
                         Toast.LENGTH_LONG);
                     t.show();
-                    mTryShareAgain = false;
                 }
             } else {
                 Toast t = Toast.makeText(this,
@@ -869,6 +882,7 @@ public class FileActivity extends AppCompatActivity
     public void dismissLoadingDialog() {
         Fragment frag = getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
         if (frag != null) {
+            Log_OC.d(TAG, "dismiss loading dialog");
             LoadingDialog loading = (LoadingDialog) frag;
             loading.dismiss();
         }
@@ -901,7 +915,9 @@ public class FileActivity extends AppCompatActivity
                 /*if (!mOperationsServiceBinder.isPerformingBlockingOperation()) {
                     dismissLoadingDialog();
                 }*/
-                doOnResumeAndBound();
+                if (mResumed) {
+                    doOnResumeAndBound();
+                }
 
             } else {
                 return;
@@ -938,6 +954,12 @@ public class FileActivity extends AppCompatActivity
         startActivity(i);
     }
 
+    public void refresh(){
+        Intent i = new Intent(this, FileDisplayActivity.class);
+        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        startActivity(i);
+    }
+
 //    TODO re-enable when "Accounts" is available in Navigation Drawer
 //    public void closeDrawer() {
 //        mDrawerLayout.closeDrawers();
@@ -947,6 +969,10 @@ public class FileActivity extends AppCompatActivity
         restart();
     }
 
+    public void refreshDirectory(){
+        // overridden by FileDisplayActivity
+    }
+
     private class DrawerItemClickListener implements ListView.OnItemClickListener {
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -963,24 +989,25 @@ public class FileActivity extends AppCompatActivity
 //                    break;
 
                 case 0: // All Files
-                    allFilesOption();
+                    MainApp.showOnlyFilesOnDevice(false);
+                    refreshDirectory();
                     mDrawerLayout.closeDrawers();
                     break;
 
-                // TODO Enable when "On Device" is recovered ?
-//                case 2:
-//                    MainApp.showOnlyFilesOnDevice(true);
-//                    mDrawerLayout.closeDrawers();
-//                    break;
+                case 1: // On Device
+                    MainApp.showOnlyFilesOnDevice(true);
+                    refreshDirectory();
+                    mDrawerLayout.closeDrawers();
+                    break;
 
-                case 1: // Settings
+                case 2: // Settings
                     Intent settingsIntent = new Intent(getApplicationContext(),
                             Preferences.class);
                     startActivity(settingsIntent);
                     mDrawerLayout.closeDrawers();
                     break;
 
-                case 2: // Logs
+                case 3: // Logs
                     Intent loggerIntent = new Intent(getApplicationContext(),
                             LogHistoryActivity.class);
                     startActivity(loggerIntent);
index 89d22c6..e69eb04 100644 (file)
@@ -26,6 +26,7 @@ import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AuthenticatorException;
 import android.annotation.TargetApi;
+import android.os.Parcelable;
 import android.support.v7.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -50,6 +51,7 @@ import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.view.GravityCompat;
+import android.support.v7.app.AlertDialog;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -79,14 +81,11 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCo
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.operations.CopyFileOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
-import com.owncloud.android.operations.CreateShareViaLinkOperation;
-import com.owncloud.android.operations.CreateShareWithShareeOperation;
 import com.owncloud.android.operations.MoveFileOperation;
 import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
-import com.owncloud.android.operations.UnshareOperation;
 import com.owncloud.android.services.observer.FileObserverService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@ -108,6 +107,8 @@ import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.UriUtils;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
 
 /**
  * Displays, what files the user has available in his ownCloud.
@@ -148,13 +149,14 @@ public class FileDisplayActivity extends HookActivity
     private boolean mSyncInProgress = false;
 
     private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT";
-    private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
+    public static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
     private static String DIALOG_UPLOAD_SOURCE = "DIALOG_UPLOAD_SOURCE";
     private static String DIALOG_CERT_NOT_SAVED = "DIALOG_CERT_NOT_SAVED";
 
     private OCFile mWaitingToSend;
+    private Menu mOptionsMenu;
+
 
-    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         Log_OC.v(TAG, "onCreate() start");
@@ -300,10 +302,7 @@ public class FileDisplayActivity extends HookActivity
             /// First fragment
             OCFileListFragment listOfFiles = getListOfFilesFragment();
             if (listOfFiles != null) {
-                listOfFiles.listDirectory(getCurrentDir());
-                // TODO Enable when "On Device" is recovered
-                // listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice());
-
+                listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice());
             } else {
                 Log_OC.e(TAG, "Still have a chance to lose the initializacion of list fragment >(");
             }
@@ -322,6 +321,8 @@ public class FileDisplayActivity extends HookActivity
                     startTextPreview(file);
             }
 
+            switchLayout(getFile());
+
         } else {
             Log_OC.wtf(TAG, "initFragments() called with invalid NULLs!");
             if (getAccount() == null) {
@@ -333,6 +334,14 @@ public class FileDisplayActivity extends HookActivity
         }
     }
 
+    private void switchLayout(OCFile file){
+        if (DisplayUtils.isGridView(file, getStorageManager())){
+            switchToGridView();
+        } else {
+            switchToListView();
+        }
+    }
+
     private Fragment chooseInitialSecondFragment(OCFile file) {
         Fragment secondFragment = null;
         if (file != null && !file.isFolder()) {
@@ -432,9 +441,7 @@ public class FileDisplayActivity extends HookActivity
     protected void refreshListOfFilesFragment() {
         OCFileListFragment fileListFragment = getListOfFilesFragment();
         if (fileListFragment != null) {
-            fileListFragment.listDirectory();
-            // TODO Enable when "On Device" is recovered ?
-            // fileListFragment.listDirectory(MainApp.getOnlyOnDevice());
+            fileListFragment.listDirectory(MainApp.getOnlyOnDevice());
         }
     }
 
@@ -486,10 +493,9 @@ public class FileDisplayActivity extends HookActivity
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
         boolean drawerOpen = mDrawerLayout.isDrawerOpen(GravityCompat.START);
-        menu.findItem(R.id.action_upload).setVisible(!drawerOpen);
-        menu.findItem(R.id.action_create_dir).setVisible(!drawerOpen);
         menu.findItem(R.id.action_sort).setVisible(!drawerOpen);
         menu.findItem(R.id.action_sync_account).setVisible(!drawerOpen);
+        menu.findItem(R.id.action_switch_view).setVisible(!drawerOpen);
         
         return super.onPrepareOptionsMenu(menu);
     }
@@ -498,6 +504,13 @@ public class FileDisplayActivity extends HookActivity
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.main_menu, menu);
+        menu.findItem(R.id.action_create_dir).setVisible(false);
+        mOptionsMenu = menu;
+
+        MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view);
+
+        changeGridIcon();
+
         return true;
     }
     
@@ -506,23 +519,10 @@ public class FileDisplayActivity extends HookActivity
     public boolean onOptionsItemSelected(MenuItem item) {
         boolean retval = true;
         switch (item.getItemId()) {
-            case R.id.action_create_dir: {
-                CreateFolderDialogFragment dialog =
-                        CreateFolderDialogFragment.newInstance(getCurrentDir());
-                dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
-                break;
-            }
-
             case R.id.action_sync_account: {
                 startSynchronization();
                 break;
             }
-            case R.id.action_upload: {
-                UploadSourceDialogFragment dialog =
-                        UploadSourceDialogFragment.newInstance(getAccount());
-                dialog.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE);
-                break;
-            }
             case android.R.id.home: {
                 FileFragment second = getSecondFragment();
                 OCFile currentDir = getCurrentDir();
@@ -565,12 +565,57 @@ public class FileDisplayActivity extends HookActivity
                 builder.create().show();
                 break;
             }
+            case R.id.action_switch_view:{
+                if (isGridView()){
+                    item.setTitle(getApplicationContext().getString(R.string.action_switch_grid_view));
+                    item.setIcon(ContextCompat.getDrawable(getApplicationContext(),
+                            R.drawable.ic_view_module));
+                    DisplayUtils.setViewMode(getFile(), false);
+                    switchToListView();
+                } else {
+                    item.setTitle(getApplicationContext().getString(R.string.action_switch_list_view));
+                    item.setIcon(ContextCompat.getDrawable(getApplicationContext(),
+                            R.drawable.ic_view_list));
+                    DisplayUtils.setViewMode(getFile(), true);
+                    switchToGridView();
+                }
+
+                return true;
+            }
         default:
             retval = super.onOptionsItemSelected(item);
         }
         return retval;
     }
 
+    public void createFolder() {
+        CreateFolderDialogFragment dialog =
+                CreateFolderDialogFragment.newInstance(getCurrentDir());
+        dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
+    }
+
+    public void uploadLocalFilesSelected() {
+        Intent action = new Intent(this, UploadFilesActivity.class);
+        action.putExtra(
+                UploadFilesActivity.EXTRA_ACCOUNT,
+                getAccount()
+        );
+        startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
+    }
+
+    public void uploadFromOtherAppsSelected() {
+        Intent action = new Intent(Intent.ACTION_GET_CONTENT);
+        action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
+        //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+            action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+        }
+        startActivityForResult(
+                Intent.createChooser(action, getString(R.string.upload_chooser_title)),
+                ACTION_SELECT_CONTENT_FROM_APPS
+        );
+    }
+
     private void startSynchronization() {
         Log_OC.d(TAG, "Got to start sync");
         if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
@@ -765,8 +810,12 @@ public class FileDisplayActivity extends HookActivity
      */
     private void requestMoveOperation(Intent data, int resultCode) {
         OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
-        OCFile targetFile = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
-        getFileOperationsHelper().moveFile(folderToMoveAt, targetFile);
+
+        ArrayList<OCFile> files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES);
+
+        for (Parcelable file : files) {
+            getFileOperationsHelper().moveFile(folderToMoveAt, (OCFile) file);
+        }
     }
 
     /**
@@ -777,13 +826,36 @@ public class FileDisplayActivity extends HookActivity
      */
     private void requestCopyOperation(Intent data, int resultCode) {
         OCFile folderToMoveAt = data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
-        OCFile targetFile = data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
-        getFileOperationsHelper().copyFile(folderToMoveAt, targetFile);
+
+        ArrayList<OCFile> files = data.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES);
+
+        for (Parcelable file : files) {
+            getFileOperationsHelper().copyFile(folderToMoveAt, (OCFile) file);
+        }
     }
 
     @Override
     public void onBackPressed() {
-        if (!isDrawerOpen()){
+        boolean isFabOpen = isFabOpen();
+        boolean isDrawerOpen = isDrawerOpen();
+
+        /*
+         * BackPressed priority/hierarchy:
+         *    1. close drawer if opened
+         *    2. close FAB if open (only if drawer isn't open)
+         *    3. navigate up (only if drawer and FAB aren't open)
+         */
+        if(isDrawerOpen && isFabOpen) {
+            // close drawer first
+            super.onBackPressed();
+        } else if(isDrawerOpen && !isFabOpen) {
+            // close drawer
+            super.onBackPressed();
+        } else if (!isDrawerOpen && isFabOpen) {
+            // close fab
+            getListOfFilesFragment().getFabMain().collapse();
+        } else {
+            // all closed
             OCFileListFragment listOfFiles = getListOfFilesFragment();
             if (mDualPane || getSecondFragment() == null) {
                 OCFile currentDir = getCurrentDir();
@@ -799,8 +871,20 @@ public class FileDisplayActivity extends HookActivity
                 setFile(listOfFiles.getCurrentFile());
             }
             cleanSecondFragment();
+            changeGridIcon();
+        }
+    }
+
+    private void changeGridIcon(){
+        MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view);
+        if (DisplayUtils.isGridView(getFile(), getStorageManager())){
+            menuItem.setTitle(getApplicationContext().getString(R.string.action_switch_list_view));
+            menuItem.setIcon(ContextCompat.getDrawable(getApplicationContext(),
+                    R.drawable.ic_view_list));
         } else {
-            super.onBackPressed();
+            menuItem.setTitle(getApplicationContext().getString(R.string.action_switch_grid_view));
+            menuItem.setIcon(ContextCompat.getDrawable(getApplicationContext(),
+                    R.drawable.ic_view_module));
         }
     }
 
@@ -879,6 +963,14 @@ public class FileDisplayActivity extends HookActivity
         Log_OC.v(TAG, "onPause() end");
     }
 
+    public boolean isFabOpen() {
+        if(getListOfFilesFragment() != null && getListOfFilesFragment().getFabMain() != null && getListOfFilesFragment().getFabMain().isExpanded()) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
 
     private class SyncBroadcastReceiver extends BroadcastReceiver {
 
@@ -934,10 +1026,8 @@ public class FileDisplayActivity extends HookActivity
                                     currentDir.getRemotePath().equals(synchFolderRemotePath)) {
                                 OCFileListFragment fileListFragment = getListOfFilesFragment();
                                 if (fileListFragment != null) {
-                                    fileListFragment.listDirectory();
-                                    // TODO Enable when "On Device" is recovered ?
-                                    // fileListFragment.listDirectory(currentDir,
-                                    // MainApp.getOnlyOnDevice());
+                                    fileListFragment.listDirectory(currentDir,
+                                    MainApp.getOnlyOnDevice());
                                 }
                             }
                             setFile(currentFile);
@@ -1193,9 +1283,7 @@ public class FileDisplayActivity extends HookActivity
         OCFileListFragment listOfFiles = getListOfFilesFragment();
         if (listOfFiles != null) {  // should never be null, indeed
             OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
-            listOfFiles.listDirectory(root);
-            // TODO Enable when "On Device" is recovered ?
-            // listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice());
+            listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice());
             setFile(listOfFiles.getCurrentFile());
             startSyncFolderOperation(root, false);
         }
@@ -1214,6 +1302,11 @@ public class FileDisplayActivity extends HookActivity
         cleanSecondFragment();
         // Sync Folder
         startSyncFolderOperation(directory, false);
+
+        MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view);
+
+        changeGridIcon();
+        switchLayout(directory);
     }
 
     /**
@@ -1280,9 +1373,7 @@ public class FileDisplayActivity extends HookActivity
             // getFileDownloadBinder() - THIS IS A MESS
             OCFileListFragment listOfFiles = getListOfFilesFragment();
             if (listOfFiles != null) {
-                listOfFiles.listDirectory();
-                // TODO Enable when "On Device" is recovered ?
-                // listOfFiles.listDirectory(MainApp.getOnlyOnDevice());
+                listOfFiles.listDirectory(MainApp.getOnlyOnDevice());
             }
             FileFragment secondFragment = getSecondFragment();
             if (secondFragment != null && secondFragment instanceof FileDetailFragment) {
@@ -1348,15 +1439,6 @@ public class FileDisplayActivity extends HookActivity
         } else if (operation instanceof CreateFolderOperation) {
             onCreateFolderOperationFinish((CreateFolderOperation) operation, result);
 
-        } else if (operation instanceof CreateShareViaLinkOperation ||
-                    operation instanceof CreateShareWithShareeOperation ) {
-
-            refreshShowDetails();
-            refreshListOfFilesFragment();
-
-        } else if (operation instanceof UnshareOperation) {
-            onUnshareLinkOperationFinish((UnshareOperation) operation, result);
-
         } else if (operation instanceof MoveFileOperation) {
             onMoveFileOperationFinish((MoveFileOperation) operation, result);
 
@@ -1366,18 +1448,6 @@ public class FileDisplayActivity extends HookActivity
 
     }
 
-    private void onUnshareLinkOperationFinish(UnshareOperation operation,
-                                              RemoteOperationResult result) {
-        if (result.isSuccess()) {
-            refreshShowDetails();
-            refreshListOfFilesFragment();
-
-        } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
-            cleanSecondFragment();
-            refreshListOfFilesFragment();
-        }
-    }
-
     private void refreshShowDetails() {
         FileFragment details = getSecondFragment();
         if (details != null) {
@@ -1832,8 +1902,19 @@ public class FileDisplayActivity extends HookActivity
     private void sortByName(boolean ascending) {
         getListOfFilesFragment().sortByName(ascending);
     }
+    private boolean isGridView(){ return getListOfFilesFragment().isGridView(); }
+    private void switchToGridView() {
+        getListOfFilesFragment().switchToGridView();
+    }
+    private void switchToListView() {
+        getListOfFilesFragment().switchToListView();
+    }
 
    public void allFilesOption() {
        browseToRoot();
    }
+
+    public void refreshDirectory(){
+        getListOfFilesFragment().refreshDirectory();
+    }
 }
index 2f02dcd..dc05de9 100644 (file)
@@ -61,6 +61,8 @@ import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.ui.fragment.OCFileListFragment;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 
+import java.util.ArrayList;
+
 public class FolderPickerActivity extends FileActivity implements FileFragment.ContainerActivity, 
     OnClickListener, OnEnforceableRefreshListener {
 
@@ -68,6 +70,8 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
                                                             + ".EXTRA_FOLDER";
     public static final String EXTRA_FILE = UploadFilesActivity.class.getCanonicalName()
                                                             + ".EXTRA_FILE";
+    public static final String EXTRA_FILES = UploadFilesActivity.class.getCanonicalName()
+            + ".EXTRA_FILES";
     //TODO: Think something better
 
     private SyncBroadcastReceiver mSyncBroadcastReceiver;
@@ -140,7 +144,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
             
             if (!stateWasRecovered) {
                 OCFileListFragment listOfFolders = getListOfFilesFragment(); 
-                listOfFolders.listDirectory(folder/*, false*/);
+                listOfFolders.listDirectory(folder, false);
                 
                 startSyncFolderOperation(folder, false);
             }
@@ -154,6 +158,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
         Bundle args = new Bundle();
         args.putBoolean(OCFileListFragment.ARG_JUST_FOLDERS, true);
         args.putBoolean(OCFileListFragment.ARG_ALLOW_CONTEXTUAL_ACTIONS, false);
+        args.putBoolean(OCFileListFragment.ARG_HIDE_FAB, true);
         listOfFiles.setArguments(args);
         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
         transaction.add(R.id.fragment_container, listOfFiles, TAG_LIST_OF_FOLDERS);
@@ -262,7 +267,6 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.main_menu, menu);
-        menu.findItem(R.id.action_upload).setVisible(false);
         menu.findItem(R.id.action_sort).setVisible(false);
         return true;
     }
@@ -309,9 +313,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
     protected void refreshListOfFilesFragment() {
         OCFileListFragment fileListFragment = getListOfFilesFragment();
         if (fileListFragment != null) {
-            fileListFragment.listDirectory();
-            // TODO Enable when "On Device" is recovered ?
-            // fileListFragment.listDirectory(false);
+            fileListFragment.listDirectory(false);
         }
     }
 
@@ -319,9 +321,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
         OCFileListFragment listOfFiles = getListOfFilesFragment(); 
         if (listOfFiles != null) {  // should never be null, indeed
             OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
-            listOfFiles.listDirectory(root);
-            // TODO Enable when "On Device" is recovered ?
-            // listOfFiles.listDirectory(root, false);
+            listOfFiles.listDirectory(root, false);
             setFile(listOfFiles.getCurrentFile());
             updateNavigationElementsInActionBar();
             startSyncFolderOperation(root, false);
@@ -372,12 +372,16 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
         } else if (v == mChooseBtn) {
             Intent i = getIntent();
             Parcelable targetFile = i.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
+            ArrayList<Parcelable> targetFiles = i.getParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES);
 
             Intent data = new Intent();
             data.putExtra(EXTRA_FOLDER, getCurrentFolder());
             if (targetFile != null) {
                 data.putExtra(EXTRA_FILE, targetFile);
             }
+            if (targetFiles != null){
+                data.putParcelableArrayListExtra(EXTRA_FILES, targetFiles);
+            }
             setResult(RESULT_OK, data);
             finish();
         }
@@ -471,9 +475,7 @@ public class FolderPickerActivity extends FileActivity implements FileFragment.C
                                     equals(synchFolderRemotePath)) {
                                 OCFileListFragment fileListFragment = getListOfFilesFragment();
                                 if (fileListFragment != null) {
-                                    fileListFragment.listDirectory(currentDir);
-                                    // TODO Enable when "On Device" is recovered ?
-                                    // fileListFragment.listDirectory(currentDir, false);
+                                    fileListFragment.listDirectory(currentDir, false);
                                 }
                             }
                             setFile(currentFile);
diff --git a/src/com/owncloud/android/ui/activity/LocalDirectorySelectorActivity.java b/src/com/owncloud/android/ui/activity/LocalDirectorySelectorActivity.java
new file mode 100644 (file)
index 0000000..83b44c5
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartosz Przybylski
+ *   Copyright (C) 2015 ownCloud Inc.
+ *   Copyright (C) 2015 Bartosz Przybylski
+ *
+ *   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.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+
+import com.owncloud.android.R;
+
+/**
+ * Created by Bartosz Przybylski on 07.11.2015.
+ */
+public class LocalDirectorySelectorActivity extends UploadFilesActivity {
+
+       @Override
+       public void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+               mUploadBtn.setText(R.string.folder_picker_choose_button_text);
+       }
+
+       @Override
+       public void onClick(View v) {
+               if (v.getId() == R.id.upload_files_btn_cancel) {
+                       setResult(RESULT_CANCELED);
+                       finish();
+
+               } else if (v.getId() == R.id.upload_files_btn_upload) {
+                       Intent resultIntent = new Intent();
+                       resultIntent.putExtra(EXTRA_CHOSEN_FILES, getInitialDirectory().getAbsolutePath());
+                       setResult(RESULT_OK, resultIntent);
+                       finish();
+               }
+       }
+}
index cc4170f..d06306b 100644 (file)
@@ -24,6 +24,7 @@ package com.owncloud.android.ui.activity;
 
 import java.util.Arrays;
 
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
@@ -45,18 +46,18 @@ public class PassCodeActivity extends AppCompatActivity {
 
     private static final String TAG = PassCodeActivity.class.getSimpleName();
 
-    public final static String ACTION_ENABLE = PassCodeActivity.class.getCanonicalName() +
-            ".ENABLE";
-    public final static String ACTION_DISABLE = PassCodeActivity.class.getCanonicalName() +
-            ".DISABLE";
-    public final static String ACTION_REQUEST = PassCodeActivity.class.getCanonicalName()  +
-            ".REQUEST";
+    public final static String ACTION_REQUEST_WITH_RESULT = "ACTION_REQUEST_WITH_RESULT";
+    public final static String ACTION_CHECK_WITH_RESULT = "ACTION_CHECK_WITH_RESULT";
+    public final static String ACTION_CHECK = "ACTION_CHECK";
+
+    public final static String KEY_PASSCODE  = "KEY_PASSCODE";
+    public final static String KEY_CHECK_RESULT = "KEY_CHECK_RESULT";
 
     private Button mBCancel;
     private TextView mPassCodeHdr;
     private TextView mPassCodeHdrExplanation;
     private EditText[] mPassCodeEditTexts = new EditText[4];
-    
+
     private String [] mPassCodeDigits = {"","","",""};
     private static String KEY_PASSCODE_DIGITS = "PASSCODE_DIGITS";
     private boolean mConfirmingPassCode = false;
@@ -88,13 +89,13 @@ public class PassCodeActivity extends AppCompatActivity {
         mPassCodeEditTexts[2] = (EditText) findViewById(R.id.txt2);
         mPassCodeEditTexts[3] = (EditText) findViewById(R.id.txt3);
 
-        if (ACTION_REQUEST.equals(getIntent().getAction())) {
+        if (ACTION_CHECK.equals(getIntent().getAction())) {
             /// this is a pass code request; the user has to input the right value
             mPassCodeHdr.setText(R.string.pass_code_enter_pass_code);
             mPassCodeHdrExplanation.setVisibility(View.INVISIBLE);
             setCancelButtonEnabled(false);      // no option to cancel
 
-        } else if (ACTION_ENABLE.equals(getIntent().getAction())) {
+        } else if (ACTION_REQUEST_WITH_RESULT.equals(getIntent().getAction())) {
             if (savedInstanceState != null) {
                 mConfirmingPassCode = savedInstanceState.getBoolean(PassCodeActivity.KEY_CONFIRMING_PASSCODE);
                 mPassCodeDigits = savedInstanceState.getStringArray(PassCodeActivity.KEY_PASSCODE_DIGITS);
@@ -112,7 +113,7 @@ public class PassCodeActivity extends AppCompatActivity {
                 setCancelButtonEnabled(true);
             }
 
-        } else if (ACTION_DISABLE.equals(getIntent().getAction())) {
+        } else if (ACTION_CHECK_WITH_RESULT.equals(getIntent().getAction())) {
             /// pass code preference has just been disabled in Preferences;
             // will confirm user knows pass code, then remove it
             mPassCodeHdr.setText(R.string.pass_code_remove_your_pass_code);
@@ -284,7 +285,7 @@ public class PassCodeActivity extends AppCompatActivity {
      * the previously typed pass code, if any.
      */
     private void processFullPassCode() {
-        if (ACTION_REQUEST.equals(getIntent().getAction())) {
+        if (ACTION_CHECK.equals(getIntent().getAction())) {
             if (checkPassCode()) {
                 /// pass code accepted in request, user is allowed to access the app
                 finish();
@@ -294,24 +295,20 @@ public class PassCodeActivity extends AppCompatActivity {
                         View.INVISIBLE);
             }
 
-        } else if (ACTION_DISABLE.equals(getIntent().getAction())) {
+        } else if (ACTION_CHECK_WITH_RESULT.equals(getIntent().getAction())) {
             if (checkPassCode()) {
-                /// pass code accepted when disabling, pass code is removed
-                SharedPreferences.Editor appPrefs = PreferenceManager
-                        .getDefaultSharedPreferences(getApplicationContext()).edit();
-                appPrefs.putBoolean("set_pincode", false);  // TODO remove; this should be
-                // unnecessary, was done before entering in the activity
-                appPrefs.commit();
-
-                Toast.makeText(PassCodeActivity.this, R.string.pass_code_removed, Toast.LENGTH_LONG).show();
-                finish();
 
+                Intent resultIntent = new Intent();
+                resultIntent.putExtra(KEY_CHECK_RESULT, true);
+                setResult(RESULT_OK, resultIntent);
+
+                finish();
             } else {
                 showErrorAndRestart(R.string.pass_code_wrong, R.string.pass_code_enter_pass_code,
                         View.INVISIBLE);
             }
 
-        } else if (ACTION_ENABLE.equals(getIntent().getAction())) {
+        } else if (ACTION_REQUEST_WITH_RESULT.equals(getIntent().getAction())) {
             /// enabling pass code
             if (!mConfirmingPassCode) {
                 requestPassCodeConfirmation();
@@ -403,7 +400,7 @@ public class PassCodeActivity extends AppCompatActivity {
 
     /**
      * Overrides click on the BACK arrow to correctly cancel ACTION_ENABLE or ACTION_DISABLE, while
-     * preventing than ACTION_REQUEST may be worked around.
+     * preventing than ACTION_CHECK may be worked around.
      *
      * @param keyCode       Key code of the key that triggered the down event.
      * @param event         Event triggered.
@@ -412,8 +409,8 @@ public class PassCodeActivity extends AppCompatActivity {
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event){
         if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
-            if (ACTION_ENABLE.equals(getIntent().getAction()) ||
-                    ACTION_DISABLE.equals(getIntent().getAction())) {
+            if (ACTION_REQUEST_WITH_RESULT.equals(getIntent().getAction()) ||
+                    ACTION_CHECK_WITH_RESULT.equals(getIntent().getAction())) {
                 revertActionAndExit();
             }
             return true;
@@ -427,16 +424,12 @@ public class PassCodeActivity extends AppCompatActivity {
     protected void savePassCodeAndExit() {
         SharedPreferences.Editor appPrefs = PreferenceManager
                 .getDefaultSharedPreferences(getApplicationContext()).edit();
-        
-        appPrefs.putString("PrefPinCode1", mPassCodeDigits[0]);
-        appPrefs.putString("PrefPinCode2", mPassCodeDigits[1]);
-        appPrefs.putString("PrefPinCode3", mPassCodeDigits[2]);
-        appPrefs.putString("PrefPinCode4", mPassCodeDigits[3]);
-        appPrefs.putBoolean("set_pincode", true);    /// TODO remove; unnecessary,
-                                                     // Preferences did it before entering here
-        appPrefs.commit();
-
-        Toast.makeText(this, R.string.pass_code_stored, Toast.LENGTH_LONG).show();
+
+        Intent resultIntent = new Intent();
+        resultIntent.putExtra(KEY_PASSCODE,
+                mPassCodeDigits[0] + mPassCodeDigits[1] + mPassCodeDigits[2] + mPassCodeDigits[3]);
+
+        setResult(RESULT_OK, resultIntent);
         finish();
     }
 
@@ -467,7 +460,6 @@ public class PassCodeActivity extends AppCompatActivity {
         outState.putStringArray(PassCodeActivity.KEY_PASSCODE_DIGITS, mPassCodeDigits);
     }
 
-
     private class PassCodeDigitTextWatcher implements TextWatcher {
 
         private int mIndex = -1;
index e1c5c10..863a0e4 100644 (file)
@@ -34,7 +34,9 @@ import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.preference.CheckBoxPreference;
@@ -62,6 +64,7 @@ import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.ListAdapter;
 import android.widget.ListView;
+import android.widget.Toast;
 
 import com.owncloud.android.BuildConfig;
 import com.owncloud.android.MainApp;
@@ -70,15 +73,25 @@ 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.datamodel.ThumbnailsCacheManager;
 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.PreferenceWithLongSummary;
 import com.owncloud.android.ui.RadioButtonPreference;
 import com.owncloud.android.utils.DisplayUtils;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.ExecutionException;
+import java.io.File;
+
 
 /**
  * An Activity that allows the user to change the application's settings.
@@ -93,6 +106,10 @@ public class Preferences extends PreferenceActivity
 
     private static final int ACTION_SELECT_UPLOAD_PATH = 1;
     private static final int ACTION_SELECT_UPLOAD_VIDEO_PATH = 2;
+    private static final int ACTION_REQUEST_PASSCODE = 5;
+    private static final int ACTION_CONFIRM_PASSCODE = 6;
+    private static final int ACTION_SELECT_STORAGE_PATH = 3;
+    private static final int ACTION_PERFORM_MIGRATION = 4;
 
     private DbHandler mDbHandler;
     private CheckBoxPreference pCode;
@@ -116,6 +133,9 @@ public class Preferences extends PreferenceActivity
     protected FileDownloader.FileDownloaderBinder mDownloaderBinder = null;
     protected FileUploader.FileUploaderBinder mUploaderBinder = null;
     private ServiceConnection mDownloadServiceConnection, mUploadServiceConnection = null;
+    private PreferenceWithLongSummary mPrefStoragePath;
+    private String mStoragePath;
+
 
     @SuppressWarnings("deprecation")
     @Override
@@ -219,28 +239,53 @@ public class Preferences extends PreferenceActivity
         registerForContextMenu(getListView());
 
         pCode = (CheckBoxPreference) findPreference("set_pincode");
-        if (pCode != null){
+        if (pCode != null) {
             pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                 @Override
                 public boolean onPreferenceChange(Preference preference, Object newValue) {
                     Intent i = new Intent(getApplicationContext(), PassCodeActivity.class);
-                    Boolean enable = (Boolean) newValue;
+                    Boolean incoming = (Boolean) newValue;
+
                     i.setAction(
-                            enable.booleanValue() ? PassCodeActivity.ACTION_ENABLE :
-                                    PassCodeActivity.ACTION_DISABLE
+                            incoming.booleanValue() ? PassCodeActivity.ACTION_REQUEST_WITH_RESULT :
+                                    PassCodeActivity.ACTION_CHECK_WITH_RESULT
                     );
-                    startActivity(i);
-                    
-                    return true;
+
+                    startActivityForResult(i, incoming.booleanValue() ? ACTION_REQUEST_PASSCODE :
+                            ACTION_CONFIRM_PASSCODE);
+
+                    // Don't update just yet, we will decide on it in onActivityResult
+                    return false;
                 }
-            });            
+            });
             
         }
 
+        final Preference pCacheSize = findPreference("pref_cache_size");
+        if (pCacheSize != null){
+            final SharedPreferences appPrefs =
+                    PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+            Long cacheSize = ThumbnailsCacheManager.getMaxSize();
+            pCacheSize.setSummary(cacheSize + " Mb");
+            pCacheSize.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+                @Override
+                public boolean onPreferenceChange(Preference preference, Object newValue) {
+                    Long size = Long.decode((String) newValue);
+                    if (ThumbnailsCacheManager.setMaxSize(size)){
+                        appPrefs.edit().putString("pref_cache_size", size.toString());
+                        pCacheSize.setSummary(size + " MB");
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            });
+        }
+
         PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference("more");
         
         boolean helpEnabled = getResources().getBoolean(R.bool.help_enabled);
-        Preference pHelp =  findPreference("help");
+        Preference pHelp = findPreference("help");
         if (pHelp != null ){
             if (helpEnabled) {
                 pHelp.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@@ -262,7 +307,7 @@ public class Preferences extends PreferenceActivity
         }
 
         if (BuildConfig.DEBUG) {
-            Preference pLog =  findPreference("log");
+            Preference pLog = findPreference("log");
             if (pLog != null ){
                 pLog.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                     @Override
@@ -305,7 +350,7 @@ public class Preferences extends PreferenceActivity
                         intent.putExtra(Intent.EXTRA_TEXT, recommendText);
                         startActivity(intent);
 
-                        return(true);
+                        return true;
 
                     }
                 });
@@ -322,9 +367,10 @@ public class Preferences extends PreferenceActivity
                 pFeedback.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                     @Override
                     public boolean onPreferenceClick(Preference preference) {
-                        String feedbackMail   =(String) getText(R.string.mail_feedback);
-                        String feedback   =(String) getText(R.string.prefs_feedback) + " - android v" + appVersion;
-                        Intent intent = new Intent(Intent.ACTION_SENDTO); 
+                        String feedbackMail = (String) getText(R.string.mail_feedback);
+                        String feedback     = String.format("%s - android v%s", getText(R.string.prefs_feedback),  appVersion);
+                        Intent intent       = new Intent(Intent.ACTION_SENDTO);
+
                         intent.setType("text/plain");
                         intent.putExtra(Intent.EXTRA_SUBJECT, feedback);
                         
@@ -363,7 +409,29 @@ public class Preferences extends PreferenceActivity
             }
         }
 
-        mPrefInstantUploadPath =  findPreference("instant_upload_path");
+        mPrefStoragePath =  (PreferenceWithLongSummary)findPreference("storage_path");
+        if (mPrefStoragePath != null) {
+
+            mPrefStoragePath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                @Override
+                public boolean onPreferenceClick(Preference preference) {
+                    Intent intent = new Intent(Preferences.this, LocalDirectorySelectorActivity.class);
+                    intent.putExtra(UploadFilesActivity.KEY_DIRECTORY_PATH, mStoragePath);
+                    startActivityForResult(intent, ACTION_SELECT_STORAGE_PATH);
+                    return true;
+                }
+            });
+
+            mPrefStoragePath.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+                    @Override
+                    public boolean onPreferenceChange(Preference preference, Object newValue) {
+                        MainApp.setStoragePath((String) newValue);
+                        return true;
+                    }
+                });
+        }
+
+        mPrefInstantUploadPath = (PreferenceWithLongSummary)findPreference("instant_upload_path");
         if (mPrefInstantUploadPath != null){
 
             mPrefInstantUploadPath.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@@ -383,7 +451,7 @@ public class Preferences extends PreferenceActivity
         mPrefInstantUploadCategory =
                 (PreferenceCategory) findPreference("instant_uploading_category");
         
-        mPrefInstantUploadPathWiFi =  findPreference("instant_upload_on_wifi");
+        mPrefInstantUploadPathWiFi = findPreference("instant_upload_on_wifi");
         mPrefInstantUpload = findPreference("instant_uploading");
         
         toggleInstantPictureOptions(((CheckBoxPreference) mPrefInstantUpload).isChecked());
@@ -429,13 +497,21 @@ public class Preferences extends PreferenceActivity
         });
             
         /* About App */
-       pAboutApp = (Preference) findPreference("about_app");
+       pAboutApp = findPreference("about_app");
        if (pAboutApp != null) { 
-               pAboutApp.setTitle(String.format(getString(R.string.about_android), getString(R.string.app_name)));
-               pAboutApp.setSummary(String.format(getString(R.string.about_version), appVersion));
+               pAboutApp.setTitle(String.format(getString(R.string.about_android),
+                                                getString(R.string.app_name)));
+           try {
+               Integer currentVersion = getPackageManager().getPackageInfo
+                  (getPackageName(), 0).versionCode;
+               pAboutApp.setSummary(String.format(getString(R.string.about_version),
+                                    currentVersion));
+           } catch (NameNotFoundException e) {
+           }
        }
 
        loadInstantUploadPath();
+       loadStoragePath();
        loadInstantUploadVideoPath();
 
         /* ComponentsGetter */
@@ -450,6 +526,65 @@ public class Preferences extends PreferenceActivity
                     Context.BIND_AUTO_CREATE);
         }
 
+        /* Link to Beta apks */
+        Preference pBetaLink =  findPreference("beta_link");
+        if (pBetaLink != null ){
+            pBetaLink.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                @Override
+                public boolean onPreferenceClick(Preference preference) {
+                    Integer latestVersion = -1;
+                    Integer currentVersion = -1;
+                    try {
+                        currentVersion = getPackageManager().getPackageInfo
+                                                 (getPackageName(), 0).versionCode;
+                        LoadingVersionNumberTask loadTask = new LoadingVersionNumberTask();
+                        loadTask.execute();
+                        latestVersion = loadTask.get();
+                    } catch (InterruptedException | ExecutionException e) {
+                        e.printStackTrace();
+                    } catch (NameNotFoundException e) {
+                        e.printStackTrace();
+                    }
+                    if (latestVersion == -1 || currentVersion == -1) {
+                        Toast.makeText(getApplicationContext(), "No information available!",
+                                       Toast.LENGTH_SHORT).show();
+                    }
+                    if (latestVersion > currentVersion) {
+                        String betaLinkWeb = (String) getText(R.string.beta_link) +
+                                                              latestVersion + ".apk";
+                        if (betaLinkWeb != null && betaLinkWeb.length() > 0) {
+                            Uri uriUrl = Uri.parse(betaLinkWeb);
+                            Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
+                            startActivity(intent);
+                            return true;
+                        }
+                    } else {
+                        Toast.makeText(getApplicationContext(), "No new version available!",
+                                       Toast.LENGTH_SHORT).show();
+                        return true;
+                    }
+                    return true;
+                }
+            });
+        }
+
+        /* Link to Beta apks */
+        Preference pChangelogLink =  findPreference("changelog_link");
+        if (pChangelogLink != null) {
+            pChangelogLink.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+                @Override
+                public boolean onPreferenceClick(Preference preference) {
+                    String betaLinkWeb = getString(R.string.changelog);
+                    if (betaLinkWeb != null && betaLinkWeb.length() > 0) {
+                        Uri uriUrl = Uri.parse(betaLinkWeb);
+                        Intent intent = new Intent(Intent.ACTION_VIEW, uriUrl);
+                        startActivity(intent);
+                        return true;
+                    }
+                    return true;
+                }
+            });
+        }
     }
     
     private void toggleInstantPictureOptions(Boolean value){
@@ -457,8 +592,8 @@ public class Preferences extends PreferenceActivity
             mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPathWiFi);
             mPrefInstantUploadCategory.addPreference(mPrefInstantUploadPath);
         } else {
-            mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPathWiFi);
-            mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPath);
+//            mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPathWiFi);
+//            mPrefInstantUploadCategory.removePreference(mPrefInstantUploadPath);
         }
     }
     
@@ -467,8 +602,8 @@ public class Preferences extends PreferenceActivity
             mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPathWiFi);
             mPrefInstantUploadCategory.addPreference(mPrefInstantVideoUploadPath);
         } else {
-            mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPathWiFi);
-            mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPath);
+//            mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPathWiFi);
+//            mPrefInstantUploadCategory.removePreference(mPrefInstantVideoUploadPath);
         }
     }
 
@@ -554,8 +689,7 @@ public class Preferences extends PreferenceActivity
 
         if (requestCode == ACTION_SELECT_UPLOAD_PATH && resultCode == RESULT_OK){
 
-            OCFile folderToUpload =
-                    (OCFile) data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
+            OCFile folderToUpload =  data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
 
             mUploadPath = folderToUpload.getRemotePath();
 
@@ -566,10 +700,9 @@ public class Preferences extends PreferenceActivity
 
             saveInstantUploadPathOnPreferences();
 
-        } else if (requestCode == ACTION_SELECT_UPLOAD_VIDEO_PATH && resultCode == RESULT_OK){
+        } else if (requestCode == ACTION_SELECT_UPLOAD_VIDEO_PATH && resultCode == RESULT_OK) {
 
-            OCFile folderToUploadVideo =
-                    (OCFile) data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
+            OCFile folderToUploadVideo = data.getParcelableExtra(UploadPathActivity.EXTRA_FOLDER);
 
             mUploadVideoPath = folderToUploadVideo.getRemotePath();
 
@@ -579,6 +712,44 @@ public class Preferences extends PreferenceActivity
             mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath);
 
             saveInstantUploadVideoPathOnPreferences();
+        } else if (requestCode == ACTION_SELECT_STORAGE_PATH && resultCode == RESULT_OK) {
+            File currentStorageDir = new File(mStoragePath);
+            File upcomingStorageDir = new File(data.getStringExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES));
+
+            if (currentStorageDir != upcomingStorageDir) {
+                Intent migrationIntent = new Intent(this, StorageMigrationActivity.class);
+                migrationIntent.putExtra(StorageMigrationActivity.KEY_MIGRATION_SOURCE_DIR,
+                        currentStorageDir.getAbsolutePath());
+                migrationIntent.putExtra(StorageMigrationActivity.KEY_MIGRATION_TARGET_DIR,
+                        upcomingStorageDir.getAbsolutePath());
+                startActivityForResult(migrationIntent, ACTION_PERFORM_MIGRATION);
+            }
+        } else if (requestCode == ACTION_PERFORM_MIGRATION && resultCode == RESULT_OK) {
+            String resultStorageDir = data.getStringExtra(StorageMigrationActivity.KEY_MIGRATION_TARGET_DIR);
+            saveStoragePath(resultStorageDir);
+        } else if (requestCode == ACTION_REQUEST_PASSCODE && resultCode == RESULT_OK) {
+            String passcode = data.getStringExtra(PassCodeActivity.KEY_PASSCODE);
+            if (passcode != null && passcode.length() == 4) {
+                SharedPreferences.Editor appPrefs = PreferenceManager
+                        .getDefaultSharedPreferences(getApplicationContext()).edit();
+
+                for (int i = 1; i <= 4; ++i) {
+                    appPrefs.putString("PrefPinCode" + i, passcode.substring(i-1, i));
+                }
+                appPrefs.putBoolean("set_pincode", true);
+                appPrefs.commit();
+                Toast.makeText(this, R.string.pass_code_stored, Toast.LENGTH_LONG).show();
+            }
+        } else if (requestCode == ACTION_CONFIRM_PASSCODE && resultCode == RESULT_OK) {
+            if (data.getBooleanExtra(PassCodeActivity.KEY_CHECK_RESULT, false)) {
+
+                SharedPreferences.Editor appPrefs = PreferenceManager
+                        .getDefaultSharedPreferences(getApplicationContext()).edit();
+                appPrefs.putBoolean("set_pincode", false);
+                appPrefs.commit();
+
+                Toast.makeText(this, R.string.pass_code_removed, Toast.LENGTH_LONG).show();
+            }
         }
     }
 
@@ -603,6 +774,7 @@ public class Preferences extends PreferenceActivity
     public void setContentView(View view) {
         getDelegate().setContentView(view);
     }
+
     @Override
     public void setContentView(View view, ViewGroup.LayoutParams params) {
         getDelegate().setContentView(view, params);
@@ -788,6 +960,31 @@ public class Preferences extends PreferenceActivity
     }
 
     /**
+     * Save storage path
+     */
+    private void saveStoragePath(String newStoragePath) {
+        SharedPreferences appPrefs =
+                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+        mStoragePath = newStoragePath;
+        MainApp.setStoragePath(mStoragePath);
+        SharedPreferences.Editor editor = appPrefs.edit();
+        editor.putString("storage_path", mStoragePath);
+        editor.commit();
+        mPrefStoragePath.setSummary(mStoragePath);
+    }
+
+    /**
+     * Load storage path set on preferences
+     */
+    private void loadStoragePath() {
+        SharedPreferences appPrefs =
+                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+        mStoragePath = appPrefs.getString("storage_path", Environment.getExternalStorageDirectory()
+                                                         .getAbsolutePath());
+        mPrefStoragePath.setSummary(mStoragePath);
+    }
+
+    /**
      * Save the "Instant Upload Path" on preferences
      */
     private void saveInstantUploadPathOnPreferences() {
@@ -802,10 +999,7 @@ public class Preferences extends PreferenceActivity
      * Load upload video path set on preferences
      */
     private void loadInstantUploadVideoPath() {
-        SharedPreferences appPrefs =
-                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-        mUploadVideoPath = appPrefs.getString("instant_video_upload_path", getString(R.string.instant_upload_path));
-        mPrefInstantVideoUploadPath.setSummary(mUploadVideoPath);
+        mPrefInstantVideoUploadPath.setSummary(MainApp.getStoragePath());
     }
 
     /**
@@ -819,7 +1013,7 @@ public class Preferences extends PreferenceActivity
         editor.commit();
     }
 
-    // Methods for ComponetsGetter
+    // Methods for ComponentsGetter
     @Override
     public FileDownloader.FileDownloaderBinder getFileDownloaderBinder() {
         return mDownloaderBinder;
@@ -858,14 +1052,10 @@ public class Preferences extends PreferenceActivity
 
             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
@@ -879,4 +1069,29 @@ public class Preferences extends PreferenceActivity
             }
         }
     };
+
+    /**
+     *
+     * Class for loading the version number
+     *
+     */
+    private class LoadingVersionNumberTask extends AsyncTask<Void, Void, Integer> {
+        protected Integer doInBackground(Void... args) {
+            try {
+                URL url = new URL("https://github.com/owncloud/android/raw/beta/apks/latest");
+                BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
+
+                Integer latestVersion = Integer.parseInt(in.readLine());
+                in.close();
+
+                return latestVersion;
+
+            } catch (MalformedURLException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            return -1;
+        }
+    }
 }
index 180b2a0..bf6e37a 100644 (file)
@@ -25,11 +25,14 @@ import android.app.SearchManager;
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentTransaction;
 
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.CreateShareViaLinkOperation;
+import com.owncloud.android.operations.GetSharesForFileOperation;
 import com.owncloud.android.providers.UsersAndGroupsSearchProvider;
 
 import com.owncloud.android.lib.common.operations.RemoteOperation;
@@ -37,10 +40,13 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.resources.shares.OCShare;
 import com.owncloud.android.lib.resources.shares.ShareType;
+import com.owncloud.android.ui.dialog.ShareLinkToDialog;
 import com.owncloud.android.ui.fragment.SearchShareesFragment;
 import com.owncloud.android.ui.fragment.ShareFileFragment;
 import com.owncloud.android.utils.GetShareWithUsersAsyncTask;
 
+import org.apache.http.protocol.HTTP;
+
 
 /**
  * Activity for sharing files
@@ -55,6 +61,8 @@ public class ShareActivity extends FileActivity
     private static final String TAG_SHARE_FRAGMENT = "SHARE_FRAGMENT";
     private static final String TAG_SEARCH_FRAGMENT = "SEARCH_USER_AND_GROUPS_FRAGMENT";
 
+    /** Tag for dialog */
+    private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -78,7 +86,7 @@ public class ShareActivity extends FileActivity
 
         // Load data into the list
         Log_OC.d(TAG, "Refreshing lists on account set");
-        refreshUsersInLists();
+        refreshSharesFromStorageManager();
 
         // Request for a refresh of the data through the server (starts an Async Task)
         refreshUsersOrGroupsListFromServer();
@@ -153,26 +161,48 @@ public class ShareActivity extends FileActivity
     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
         super.onRemoteOperationFinish(operation, result);
 
-        if (result.isSuccess()) {
-            Log_OC.d(TAG, "Refreshing lists on successful sync");
-            refreshUsersInLists();
+        if (result.isSuccess() ||
+            (operation instanceof GetSharesForFileOperation &&
+                result.getCode() == RemoteOperationResult.ResultCode.SHARE_NOT_FOUND
+            )
+        ) {
+            Log_OC.d(TAG, "Refreshing view on successful operation or finished refresh");
+            refreshSharesFromStorageManager();
+        }
+
+        if (operation instanceof CreateShareViaLinkOperation) {
+            // Send link to the app
+            String link = ((OCShare) (result.getData().get(0))).getShareLink();
+            Log_OC.d(TAG, "Share link = " + link);
+
+            Intent intentToShareLink = new Intent(Intent.ACTION_SEND);
+            intentToShareLink.putExtra(Intent.EXTRA_TEXT, link);
+            intentToShareLink.setType(HTTP.PLAIN_TEXT_TYPE);
+            String[] packagesToExclude = new String[]{getPackageName()};
+            DialogFragment chooserDialog = ShareLinkToDialog.newInstance(intentToShareLink, packagesToExclude);
+            chooserDialog.show(getSupportFragmentManager(), FTAG_CHOOSER_DIALOG);
         }
 
     }
 
-    private void refreshUsersInLists() {
+
+    /**
+     * Updates the view, reading data from {@link com.owncloud.android.datamodel.FileDataStorageManager}
+     */
+    private void refreshSharesFromStorageManager() {
+
         ShareFileFragment shareFileFragment = getShareFileFragment();
-        if (shareFileFragment != null) {          // only if added to the view hierarchy!!
-            if (shareFileFragment.isAdded()) {
-                shareFileFragment.refreshUsersOrGroupsListFromDB();
-            }
+        if (shareFileFragment != null
+                && shareFileFragment.isAdded()) {   // only if added to the view hierarchy!!
+            shareFileFragment.refreshCapabilitiesFromDB();
+            shareFileFragment.refreshUsersOrGroupsListFromDB();
+            shareFileFragment.refreshPublicShareFromDB();
         }
 
         SearchShareesFragment searchShareesFragment = getSearchFragment();
-        if (searchShareesFragment != null) {
-            if (searchShareesFragment.isAdded()) {  // only if added to the view hierarchy!!
-                searchShareesFragment.refreshUsersOrGroupsListFromDB();
-            }
+        if (searchShareesFragment != null &&
+                searchShareesFragment.isAdded()) {  // only if added to the view hierarchy!!
+            searchShareesFragment.refreshUsersOrGroupsListFromDB();
         }
     }
 
diff --git a/src/com/owncloud/android/ui/activity/StorageMigrationActivity.java b/src/com/owncloud/android/ui/activity/StorageMigrationActivity.java
new file mode 100644 (file)
index 0000000..c0b4522
--- /dev/null
@@ -0,0 +1,281 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   @author Bartosz Przybylski
+ *   Copyright (C) 2015 ownCloud Inc.
+ *   Copyright (C) 2015 Bartosz Przybylski
+ *
+ *   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.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.utils.FileStorageUtils;
+
+import java.io.File;
+
+/**
+ * Created by Bartosz Przybylski on 07.11.2015.
+ */
+public class StorageMigrationActivity extends AppCompatActivity {
+       private static final String TAG = StorageMigrationActivity.class.getName();
+       public static final String KEY_MIGRATION_TARGET_DIR = "MIGRATION_TARGET";
+       public static final String KEY_MIGRATION_SOURCE_DIR = "MIGRATION_SOURCE";
+
+       private ProgressBar mProgressBar;
+       private Button mFinishButton;
+       private TextView mFeedbackText;
+
+       @Override
+       public void onCreate(Bundle savedInstanceState) {
+               super.onCreate(savedInstanceState);
+
+               setContentView(R.layout.migration_layout);
+               mProgressBar = (ProgressBar)findViewById(R.id.migrationProgress);
+               mFinishButton = (Button)findViewById(R.id.finishButton);
+               mFeedbackText = (TextView)findViewById(R.id.migrationText);
+
+               mProgressBar.setProgress(0);
+               mFinishButton.setVisibility(View.INVISIBLE);
+               mFeedbackText.setText(R.string.file_migration_preparing);
+
+               mFinishButton.setOnClickListener(new View.OnClickListener() {
+                       @Override
+                       public void onClick(View view) {
+                               setResult(RESULT_CANCELED);
+                               finish();
+                       }
+               });
+
+               String source = getIntent().getStringExtra(KEY_MIGRATION_SOURCE_DIR);
+               String destination = getIntent().getStringExtra(KEY_MIGRATION_TARGET_DIR);
+
+               if (source == null || destination == null) {
+                       Log_OC.e(TAG, "source or destination is null");
+                       finish();
+               }
+
+               new FileMigrationTask().execute(source, destination);
+       }
+
+       private class FileMigrationTask extends AsyncTask<String, Integer, Integer> {
+
+               private String mStorageTarget;
+               private String mStorageSource;
+               private int mProgress;
+
+               private static final int mProgressCopyUpperBound = 98;
+
+               private class MigrationException extends Exception {
+                       private int mResId;
+                       /*
+                        * @param resId resource identifier to use for displaying error
+                        */
+                       MigrationException(int resId) {
+                               super();
+                               this.mResId = resId;
+                       }
+
+                       int getResId() { return mResId; }
+               }
+
+               @Override
+               protected Integer doInBackground(String... args) {
+
+                       mStorageSource = args[0];
+                       mStorageTarget = args[1];
+                       mProgress = 0;
+
+                       publishProgress(mProgress++, R.string.file_migration_preparing);
+
+                       Context context = StorageMigrationActivity.this;
+                       String ocAuthority = context.getString(R.string.authority);
+
+                       Account[] ocAccounts = AccountManager.get(context).getAccountsByType(MainApp.getAccountType());
+                       boolean[] oldAutoSync = new boolean[ocAccounts.length];
+
+                       Log_OC.stopLogging();
+
+                       try {
+                               publishProgress(mProgress++, R.string.file_migration_checking_destination);
+
+                               checkDestinationAvailability();
+
+                               publishProgress(mProgress++, R.string.file_migration_saving_accounts_configuration);
+                               saveAccountsSyncStatus(ocAuthority, ocAccounts, oldAutoSync);
+
+                               publishProgress(mProgress++, R.string.file_migration_waiting_for_unfinished_sync);
+                               stopAccountsSyncing(ocAuthority, ocAccounts);
+                               waitForUnfinishedSynchronizations(ocAuthority, ocAccounts);
+
+                               publishProgress(mProgress++, R.string.file_migration_migrating);
+                               copyFiles();
+
+                               publishProgress(mProgress++, R.string.file_migration_updating_index);
+                               updateIndex(context);
+
+                               publishProgress(mProgress++, R.string.file_migration_cleaning);
+                               cleanup();
+
+                       } catch (MigrationException e) {
+                               rollback();
+                               Log_OC.startLogging(mStorageSource);
+                               return e.getResId();
+                       } finally {
+                               publishProgress(mProgress++, R.string.file_migration_restoring_accounts_configuration);
+                               restoreAccountsSyncStatus(ocAuthority, ocAccounts, oldAutoSync);
+                       }
+
+                       Log_OC.startLogging(mStorageTarget);
+                       publishProgress(mProgress++, R.string.file_migration_ok_finished);
+
+                       return 0;
+               }
+
+               @Override
+               protected void onProgressUpdate(Integer... progress) {
+                       mProgressBar.setProgress(progress[0]);
+                       if (progress.length > 1)
+                               mFeedbackText.setText(progress[1]);
+               }
+
+               @Override
+               protected void onPostExecute(Integer code) {
+                       mFinishButton.setVisibility(View.VISIBLE);
+                       if (code != 0) {
+                               mFeedbackText.setText(code);
+                       } else {
+                               mFeedbackText.setText(R.string.file_migration_ok_finished);
+                               mFinishButton.setOnClickListener(new View.OnClickListener() {
+                                       @Override
+                                       public void onClick(View view) {
+                                               Intent resultIntent = new Intent();
+                                               resultIntent.putExtra(KEY_MIGRATION_TARGET_DIR, mStorageTarget);
+                                               setResult(RESULT_OK, resultIntent);
+                                               finish();
+                                       }
+                               });
+                       }
+               }
+
+               void checkDestinationAvailability() throws MigrationException {
+                       File srcFile = new File(mStorageSource);
+                       File dstFile = new File(mStorageTarget);
+
+                       if (!dstFile.canRead() || !srcFile.canRead())
+                               throw new MigrationException(R.string.file_migration_failed_not_readable);
+
+                       if (!dstFile.canWrite() || !srcFile.canWrite())
+                               throw new MigrationException(R.string.file_migration_failed_not_writable);
+
+                       if (new File(dstFile, MainApp.getDataFolder()).exists())
+                               throw new MigrationException(R.string.file_migration_failed_dir_already_exists);
+
+                       if (dstFile.getFreeSpace() < FileStorageUtils.getFolderSize(new File(srcFile, MainApp.getDataFolder())))
+                               throw new MigrationException(R.string.file_migration_failed_not_enough_space);
+               }
+
+               void copyFiles() throws MigrationException {
+                       File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder());
+                       File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
+
+                       copyDirs(srcFile, dstFile);
+                       mProgress = Math.max(mProgress, mProgressCopyUpperBound);
+                       publishProgress(mProgress);
+               }
+
+               void copyDirs(File src, File dst) throws MigrationException {
+                       if (!dst.mkdirs())
+                               throw new MigrationException(R.string.file_migration_failed_while_coping);
+
+                       for (File f : src.listFiles()) {
+
+                               mProgress = Math.min(mProgress+1, mProgressCopyUpperBound);
+                               publishProgress(mProgress);
+
+                               if (f.isDirectory())
+                                       copyDirs(f, new File(dst, f.getName()));
+                               else if (!FileStorageUtils.copyFile(f, new File(dst, f.getName())))
+                                       throw new MigrationException(R.string.file_migration_failed_while_coping);
+                       }
+
+               }
+
+               void updateIndex(Context context) throws MigrationException {
+                       FileDataStorageManager manager = new FileDataStorageManager(null, context.getContentResolver());
+
+                       try {
+                               manager.migrateStoredFiles(mStorageSource, mStorageTarget);
+                       } catch (Exception e) {
+                               throw new MigrationException(R.string.file_migration_failed_while_updating_index);
+                       }
+               }
+
+               void cleanup() {
+                       File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder());
+                       if (!srcFile.delete())
+                               Log_OC.w(TAG, "Migration cleanup step failed");
+               }
+
+               void rollback() {
+                       File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
+                       if (dstFile.exists())
+                               if (!dstFile.delete())
+                                       Log_OC.w(TAG, "Rollback step failed");
+               }
+
+               void saveAccountsSyncStatus(String authority, Account accounts[], boolean syncs[]) {
+                       for (int i = 0; i < accounts.length; ++i)
+                               syncs[i] = ContentResolver.getSyncAutomatically(accounts[i], authority);
+               }
+
+               void stopAccountsSyncing(String authority, Account accounts[]) {
+                       for (int i = 0; i < accounts.length; ++i)
+                               ContentResolver.setSyncAutomatically(accounts[i], authority, false);
+               }
+
+               void waitForUnfinishedSynchronizations(String authority, Account accounts[]) {
+                       for (int i = 0; i < accounts.length; ++i)
+                               while (ContentResolver.isSyncActive(accounts[i], authority))
+                                       try {
+                                               Thread.sleep(1000);
+                                       } catch (InterruptedException e) {
+                                               Log_OC.w(TAG, "Thread interrupted while waiting for account to end syncing");
+                                               Thread.currentThread().interrupt();
+                                       }
+               }
+
+               void restoreAccountsSyncStatus(String authority, Account accounts[], boolean oldSync[]) {
+                       for (int i = 0; i < accounts.length; ++i)
+                               ContentResolver.setSyncAutomatically(accounts[i], authority, oldSync[i]);
+               }
+
+       }
+}
index 9a3ce17..d6665e2 100644 (file)
 package com.owncloud.android.ui.activity;
 
 import android.accounts.Account;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.SharedPreferences;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Environment;
+import android.preference.PreferenceManager;
 import android.support.v4.app.DialogFragment;
 import android.support.v7.app.ActionBar;
+import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
+import android.widget.RadioButton;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
+import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
@@ -57,32 +65,35 @@ public class UploadFilesActivity extends FileActivity implements
     
     private ArrayAdapter<String> mDirectories;
     private File mCurrentDir = null;
-    private LocalFileListFragment mFileListFragment;
-    private Button mCancelBtn;
-    private Button mUploadBtn;
-    private Account mAccountOnCreation;
-    private DialogFragment mCurrentDialog;
+    protected LocalFileListFragment mFileListFragment;
+    protected Button mCancelBtn;
+    protected Button mUploadBtn;
+    protected Account mAccountOnCreation;
+    protected DialogFragment mCurrentDialog;
     
     public static final String EXTRA_CHOSEN_FILES =
             UploadFilesActivity.class.getCanonicalName() + ".EXTRA_CHOSEN_FILES";
 
     public static final int RESULT_OK_AND_MOVE = RESULT_FIRST_USER; 
     
-    private static final String KEY_DIRECTORY_PATH =
+    public static final String KEY_DIRECTORY_PATH =
             UploadFilesActivity.class.getCanonicalName() + ".KEY_DIRECTORY_PATH";
     private static final String TAG = "UploadFilesActivity";
     private static final String WAIT_DIALOG_TAG = "WAIT";
     private static final String QUERY_TO_MOVE_DIALOG_TAG = "QUERY_TO_MOVE";
-    
-    
+    private RadioButton mRadioBtnCopyFiles;
+    private RadioButton mRadioBtnMoveFiles;
+
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         Log_OC.d(TAG, "onCreate() start");
         super.onCreate(savedInstanceState);
 
         if(savedInstanceState != null) {
-            mCurrentDir = new File(savedInstanceState.getString(
-                    UploadFilesActivity.KEY_DIRECTORY_PATH));
+            mCurrentDir = new File(savedInstanceState.getString(KEY_DIRECTORY_PATH));
+        } else if (getIntent() != null && getIntent().hasExtra(KEY_DIRECTORY_PATH)) {
+            mCurrentDir = new File(getIntent().getStringExtra(KEY_DIRECTORY_PATH));
         } else {
             mCurrentDir = Environment.getExternalStorageDirectory();
         }
@@ -112,6 +123,21 @@ public class UploadFilesActivity extends FileActivity implements
         mCancelBtn.setOnClickListener(this);
         mUploadBtn = (Button) findViewById(R.id.upload_files_btn_upload);
         mUploadBtn.setOnClickListener(this);
+
+        SharedPreferences appPreferences = PreferenceManager
+                .getDefaultSharedPreferences(getApplicationContext());
+
+        Integer localBehaviour = appPreferences.getInt("prefs_uploader_behaviour", FileUploader.LOCAL_BEHAVIOUR_COPY);
+
+        mRadioBtnMoveFiles = (RadioButton) findViewById(R.id.upload_radio_move);
+        if (localBehaviour == FileUploader.LOCAL_BEHAVIOUR_MOVE){
+            mRadioBtnMoveFiles.setChecked(true);
+        }
+
+        mRadioBtnCopyFiles = (RadioButton) findViewById(R.id.upload_radio_copy);
+        if (localBehaviour == FileUploader.LOCAL_BEHAVIOUR_COPY){
+            mRadioBtnCopyFiles.setChecked(true);
+        }
         
             
         // Action bar setup
@@ -132,6 +158,13 @@ public class UploadFilesActivity extends FileActivity implements
         Log_OC.d(TAG, "onCreate() end");
     }
 
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.uploader_menu, menu);
+        return true;
+    }
+
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
@@ -143,6 +176,34 @@ public class UploadFilesActivity extends FileActivity implements
                 }
                 break;
             }
+            case R.id.action_sort: {
+                SharedPreferences appPreferences = PreferenceManager
+                        .getDefaultSharedPreferences(this);
+
+                // Read sorting order, default to sort by name ascending
+                Integer sortOrder = appPreferences
+                        .getInt("sortOrder", FileStorageUtils.SORT_NAME);
+
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setTitle(R.string.actionbar_sort_title)
+                        .setSingleChoiceItems(R.array.actionbar_sortby, sortOrder ,
+                                new DialogInterface.OnClickListener() {
+                                    public void onClick(DialogInterface dialog, int which) {
+                                        switch (which){
+                                            case 0:
+                                                mFileListFragment.sortByName(true);
+                                                break;
+                                            case 1:
+                                                mFileListFragment.sortByDate(false);
+                                                break;
+                                        }
+
+                                        dialog.dismiss();
+                                    }
+                                });
+                builder.create().show();
+                break;
+            }
             default:
                 retval = super.onOptionsItemSelected(item);
         }
@@ -342,9 +403,22 @@ public class UploadFilesActivity extends FileActivity implements
                 // return the list of selected files (success)
                 Intent data = new Intent();
                 data.putExtra(EXTRA_CHOSEN_FILES, mFileListFragment.getCheckedFilePaths());
-                setResult(RESULT_OK, data);
+
+                SharedPreferences.Editor appPreferencesEditor = PreferenceManager
+                        .getDefaultSharedPreferences(getApplicationContext()).edit();
+
+
+                if (mRadioBtnMoveFiles.isChecked()){
+                    setResult(RESULT_OK_AND_MOVE, data);
+                    appPreferencesEditor.putInt("prefs_uploader_behaviour",
+                            FileUploader.LOCAL_BEHAVIOUR_MOVE);
+                } else {
+                    setResult(RESULT_OK, data);
+                    appPreferencesEditor.putInt("prefs_uploader_behaviour",
+                            FileUploader.LOCAL_BEHAVIOUR_COPY);
+                }
+                appPreferencesEditor.apply();
                 finish();
-                
             } else {
                 // show a dialog to query the user if wants to move the selected files
                 // to the ownCloud folder instead of copying
index db704d1..a4e9cb7 100644 (file)
@@ -67,8 +67,7 @@ public class UploadPathActivity extends FolderPickerActivity implements FileFrag
 
             if (!stateWasRecovered) {
                 OCFileListFragment listOfFolders = getListOfFilesFragment();
-                // TODO Enable when "On Device" is recovered ?
-                listOfFolders.listDirectory(folder/*, false*/);
+                listOfFolders.listDirectory(folder, false);
 
                 startSyncFolderOperation(folder, false);
             }
index 0d1a801..cd80a94 100644 (file)
@@ -84,6 +84,7 @@ import com.owncloud.android.ui.dialog.LoadingDialog;
 import com.owncloud.android.utils.CopyTmpFileAsyncTask;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ErrorMessageAdapter;
+import com.owncloud.android.utils.FileStorageUtils;
 
 
 /**
@@ -334,7 +335,9 @@ public class Uploader extends FileActivity
         // click on folder in the list
         Log_OC.d(TAG, "on item click");
         // TODO Enable when "On Device" is recovered ?
-        Vector<OCFile> tmpfiles = getStorageManager().getFolderContent(mFile /*, false*/);
+        Vector<OCFile> tmpfiles = getStorageManager().getFolderContent(mFile , false);
+        tmpfiles = sortFileList(tmpfiles);
+
         if (tmpfiles.size() <= 0) return;
         // filter on dirtype
         Vector<OCFile> files = new Vector<OCFile>();
@@ -399,16 +402,17 @@ public class Uploader extends FileActivity
         setContentView(R.layout.uploader_layout);
         
         ListView mListView = (ListView) findViewById(android.R.id.list);
+        ActionBar actionBar = getSupportActionBar();
 
         String current_dir = mParents.peek();
         if(current_dir.equals("")){
-            getSupportActionBar().setTitle(getString(R.string.default_display_name_for_root_folder));
+            actionBar.setTitle(getString(R.string.uploader_top_message));
         }
         else{
-            getSupportActionBar().setTitle(current_dir);
+            actionBar.setTitle(current_dir);
         }
         boolean notRoot = (mParents.size() > 1);
-        ActionBar actionBar = getSupportActionBar();
+
         actionBar.setDisplayHomeAsUpEnabled(notRoot);
         actionBar.setHomeButtonEnabled(notRoot);
 
@@ -419,20 +423,23 @@ public class Uploader extends FileActivity
         mFile = getStorageManager().getFileByPath(full_path);
         if (mFile != null) {
             // TODO Enable when "On Device" is recovered ?
-            Vector<OCFile> files = getStorageManager().getFolderContent(mFile/*, false*/);
+            Vector<OCFile> files = getStorageManager().getFolderContent(mFile, false);
+            files = sortFileList(files);
+
             List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();
             for (OCFile f : files) {
-                HashMap<String, Object> h = new HashMap<String, Object>();
                 if (f.isFolder()) {
+                    HashMap<String, Object> h = new HashMap<String, Object>();
                     h.put("dirname", f.getFileName());
+                    h.put("last_mod", DisplayUtils.getRelativeTimestamp(this, f));
                     data.add(h);
                 }
             }
             SimpleAdapter sa = new SimpleAdapter(this,
                                                 data,
                                                 R.layout.uploader_list_item_layout,
-                                                new String[] {"dirname"},
-                                                new int[] {R.id.filename});
+                                                new String[] {"dirname", "last_mod"},
+                                                new int[] {R.id.filename, R.id.last_mod});
             
             mListView.setAdapter(sa);
             Button btnChooseFolder = (Button) findViewById(R.id.uploader_choose_folder);
@@ -445,6 +452,18 @@ public class Uploader extends FileActivity
         }
     }
 
+    private Vector<OCFile> sortFileList(Vector<OCFile> files) {
+        SharedPreferences sharedPreferences = PreferenceManager
+                .getDefaultSharedPreferences(this);
+
+        // Read sorting order, default to sort by name ascending
+        FileStorageUtils.mSortOrder = sharedPreferences.getInt("sortOrder", 0);
+        FileStorageUtils.mSortAscending = sharedPreferences.getBoolean("sortAscending", true);
+
+        files = FileStorageUtils.sortOcFolder(files);
+        return files;
+    }
+
     private String generatePath(Stack<String> dirs) {
         String full_path = "";
 
@@ -607,6 +626,10 @@ public class Uploader extends FileActivity
     private void onCreateFolderOperationFinish(CreateFolderOperation operation,
                                                RemoteOperationResult result) {
         if (result.isSuccess()) {
+            dismissLoadingDialog();
+            String remotePath = operation.getRemotePath().substring(0, operation.getRemotePath().length() -1);
+            String newFolder = remotePath.substring(remotePath.lastIndexOf("/") + 1);
+            mParents.push(newFolder);
             populateDirectoryList();
         } else {
             try {
@@ -656,7 +679,6 @@ public class Uploader extends FileActivity
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.main_menu, menu);
-        menu.findItem(R.id.action_upload).setVisible(false);
         menu.findItem(R.id.action_sort).setVisible(false);
         menu.findItem(R.id.action_sync_account).setVisible(false);
         return true;
index 0f2536f..5a53a86 100644 (file)
@@ -120,10 +120,10 @@ public class DiskLruImageCache {
             }
             final InputStream in = snapshot.getInputStream( 0 );
             if ( in != null ) {
-                final BufferedInputStream buffIn = 
+                final BufferedInputStream buffIn =
                 new BufferedInputStream( in, IO_BUFFER_SIZE );
-                bitmap = BitmapFactory.decodeStream( buffIn );              
-            }   
+                bitmap = BitmapFactory.decodeStream( buffIn );
+            }
         } catch ( IOException e ) {
             e.printStackTrace();
         } finally {
@@ -193,4 +193,12 @@ public class DiskLruImageCache {
             e.printStackTrace();
         }
     }
+
+    public void setMaxSize(long maxSize){
+        mDiskCache.setMaxSize(maxSize);
+    }
+
+    public long getMaxSize(){
+        return mDiskCache.getMaxSize();
+    }
 }
\ No newline at end of file
diff --git a/src/com/owncloud/android/ui/adapter/DiskLruImageCacheFileProvider.java b/src/com/owncloud/android/ui/adapter/DiskLruImageCacheFileProvider.java
new file mode 100644 (file)
index 0000000..a3c54e8
--- /dev/null
@@ -0,0 +1,140 @@
+/**
+ *   ownCloud Android client application
+ *
+ *   Copyright (C) 2015 Tobias Kaminsky
+ *   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/>.
+ *
+ *   adapted from: http://stephendnicholas.com/archives/974
+ *
+ */
+
+package com.owncloud.android.ui.adapter;
+
+import android.accounts.Account;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.provider.OpenableColumns;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+import com.owncloud.android.lib.common.utils.Log_OC;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class DiskLruImageCacheFileProvider extends ContentProvider {
+    private static String TAG = FileDataStorageManager.class.getSimpleName();
+    private FileDataStorageManager mFileDataStorageManager;
+
+    public static final String AUTHORITY = "org.owncloud.beta.imageCache.provider";
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    private OCFile getFile(Uri uri){
+        Account account = AccountUtils.getCurrentOwnCloudAccount(MainApp.getAppContext());
+        mFileDataStorageManager = new FileDataStorageManager(account,
+                MainApp.getAppContext().getContentResolver());
+
+        OCFile ocFile = mFileDataStorageManager.getFileByPath(uri.getPath());
+        return ocFile;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+        OCFile ocFile = getFile(uri);
+
+        Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                String.valueOf("r" + ocFile.getRemoteId()));
+
+        // create a file to write bitmap data
+        File f = new File(MainApp.getAppContext().getCacheDir(), ocFile.getFileName());
+        try {
+            f.createNewFile();
+
+            //Convert bitmap to byte array
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bos);
+            byte[] bitmapdata = bos.toByteArray();
+
+            //write the bytes in file
+            FileOutputStream fos = null;
+            try {
+                fos = new FileOutputStream(f);
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            }
+            fos.write(bitmapdata);
+            fos.flush();
+            fos.close();
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        OCFile ocFile = getFile(uri);
+        return ocFile.getMimetype();
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] arg1, String arg2, String[] arg3, String arg4) {
+        MatrixCursor cursor = null;
+
+        OCFile ocFile = getFile(uri);
+        File file = new File(MainApp.getAppContext().getCacheDir(), ocFile.getFileName());
+        if (file.exists()) {
+            cursor = new MatrixCursor(new String[] {
+                    OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE });
+            cursor.addRow(new Object[] { uri.getLastPathSegment(),
+                    file.length() });
+        }
+
+        return cursor;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
+    }
+}
index 3c362f3..c46b296 100644 (file)
@@ -25,12 +25,19 @@ package com.owncloud.android.ui.adapter;
 \r
 \r
 import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
 import java.util.Vector;\r
 \r
 import android.accounts.Account;\r
 import android.content.Context;\r
 import android.content.SharedPreferences;\r
 import android.graphics.Bitmap;\r
+import android.graphics.Color;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.Canvas;\r
+import android.graphics.Paint;\r
 import android.os.Build;\r
 import android.preference.PreferenceManager;\r
 import android.text.format.DateUtils;\r
@@ -78,6 +85,8 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
     private enum ViewType {LIST_ITEM, GRID_IMAGE, GRID_ITEM };\r
 \r
     private SharedPreferences mAppPreferences;\r
+\r
+    private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();\r
     \r
     public FileListListAdapter(\r
             boolean justFolders, \r
@@ -153,7 +162,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
         ViewType viewType;\r
         if (!mGridMode){\r
             viewType = ViewType.LIST_ITEM;\r
-        } else if (file.isImage()){\r
+        } else if (file.isImage() || file.isVideo()){\r
             viewType = ViewType.GRID_IMAGE;\r
         } else {\r
             viewType = ViewType.GRID_ITEM;\r
@@ -195,35 +204,34 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                     TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);\r
                     TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);\r
                     TextView lastModV = (TextView) view.findViewById(R.id.last_mod);\r
-                    ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
+\r
 \r
                     lastModV.setVisibility(View.VISIBLE);\r
-                    lastModV.setText(showRelativeTimestamp(file));\r
+                    lastModV.setText(DisplayUtils.getRelativeTimestamp(mContext, file));\r
 \r
-                    checkBoxV.setVisibility(View.GONE);\r
 \r
                     fileSizeSeparatorV.setVisibility(View.VISIBLE);\r
                     fileSizeV.setVisibility(View.VISIBLE);\r
                     fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
 \r
-                    if (!file.isFolder()) {\r
-                        AbsListView parentList = (AbsListView)parent;\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
-                                if (parentList.isItemChecked(position)) {\r
-                                    checkBoxV.setImageResource(\r
-                                            R.drawable.ic_checkbox_marked);\r
-                                } else {\r
-                                    checkBoxV.setImageResource(\r
-                                            R.drawable.ic_checkbox_blank_outline);\r
-                                }\r
-                                checkBoxV.setVisibility(View.VISIBLE);\r
-                            }\r
-                        }\r
-\r
-                    } else { //Folder\r
+//                    if (!file.isFolder()) {\r
+//                        AbsListView parentList = (AbsListView)parent;\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
+//                                if (parentList.isItemChecked(position)) {\r
+//                                    checkBoxV.setImageResource(\r
+//                                            R.drawable.ic_checkbox_marked);\r
+//                                } else {\r
+//                                    checkBoxV.setImageResource(\r
+//                                            R.drawable.ic_checkbox_blank_outline);\r
+//                                }\r
+//                                checkBoxV.setVisibility(View.VISIBLE);\r
+//                            }\r
+//                        }\r
+\r
+                    if (file.isFolder()) {\r
                         fileSizeSeparatorV.setVisibility(View.GONE);\r
                         fileSizeV.setVisibility(View.GONE);\r
                     }\r
@@ -304,6 +312,25 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
 \r
                     break;\r
             }\r
+\r
+            ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);\r
+            checkBoxV.setVisibility(View.GONE);\r
+\r
+            AbsListView parentList = (AbsListView)parent;\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 if (parentList.getCheckedItemCount() > 0){\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
+            }\r
             \r
             // For all Views\r
             \r
@@ -317,13 +344,18 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
             \r
             // No Folder\r
             if (!file.isFolder()) {\r
-                if (file.isImage() && file.getRemoteId() != null){\r
+                if ((file.isImage() || file.isVideo()) && file.getRemoteId() != null){\r
                     // Thumbnail in Cache?\r
                     Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(\r
-                            String.valueOf(file.getRemoteId())\r
-                            );\r
+                            "t" + String.valueOf(file.getRemoteId()));\r
                     if (thumbnail != null && !file.needsUpdateThumbnail()){\r
-                        fileIcon.setImageBitmap(thumbnail);\r
+\r
+                        if (file.isVideo()) {\r
+                            Bitmap withOverlay = ThumbnailsCacheManager.addVideoOverlay(thumbnail);\r
+                            fileIcon.setImageBitmap(withOverlay);\r
+                        } else {\r
+                            fileIcon.setImageBitmap(thumbnail);\r
+                        }\r
                     } else {\r
                         // generate new Thumbnail\r
                         if (ThumbnailsCacheManager.cancelPotentialWork(file, fileIcon)) {\r
@@ -341,7 +373,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
                                     task\r
                                     );\r
                             fileIcon.setImageDrawable(asyncDrawable);\r
-                            task.execute(file);\r
+                            task.execute(file, true);\r
                         }\r
                     }\r
 \r
@@ -367,6 +399,12 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
             }\r
         }\r
 \r
+        if (mSelection.get(position) != null) {\r
+            view.setBackgroundColor(Color.rgb(248, 248, 248));\r
+        } else {\r
+            view.setBackgroundColor(Color.WHITE);\r
+        }\r
+\r
         return view;\r
     }\r
 \r
@@ -393,15 +431,14 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
      *                                  mStorageManager if is different (and not NULL)\r
      */\r
     public void swapDirectory(OCFile directory, FileDataStorageManager updatedStorageManager\r
-            /*, boolean onlyOnDevice*/) {\r
+            , boolean onlyOnDevice) {\r
         mFile = directory;\r
         if (updatedStorageManager != null && updatedStorageManager != mStorageManager) {\r
             mStorageManager = updatedStorageManager;\r
             mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
         }\r
         if (mStorageManager != null) {\r
-            // TODO Enable when "On Device" is recovered ?\r
-            mFiles = mStorageManager.getFolderContent(mFile/*, onlyOnDevice*/);\r
+            mFiles = mStorageManager.getFolderContent(mFile, onlyOnDevice);\r
             mFilesOrig.clear();\r
             mFilesOrig.addAll(mFiles);\r
             \r
@@ -412,7 +449,7 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
             mFiles = null;\r
         }\r
 \r
-        mFiles = FileStorageUtils.sortFolder(mFiles);\r
+        mFiles = FileStorageUtils.sortOcFolder(mFiles);\r
         notifyDataSetChanged();\r
     }\r
     \r
@@ -445,17 +482,53 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
         FileStorageUtils.mSortAscending = ascending;\r
         \r
 \r
-        mFiles = FileStorageUtils.sortFolder(mFiles);\r
+        mFiles = FileStorageUtils.sortOcFolder(mFiles);\r
         notifyDataSetChanged();\r
 \r
     }\r
-    \r
-    private CharSequence showRelativeTimestamp(OCFile file){\r
-        return DisplayUtils.getRelativeDateTimeString(mContext, file.getModificationTimestamp(),\r
-                DateUtils.SECOND_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0);\r
-    }\r
 \r
     public void setGridMode(boolean gridMode) {\r
         mGridMode = gridMode;\r
     }\r
+\r
+    public boolean isGridMode() {\r
+        return mGridMode;\r
+    }\r
+\r
+    public void setNewSelection(int position, boolean checked) {\r
+        mSelection.put(position, checked);\r
+        notifyDataSetChanged();\r
+    }\r
+\r
+    public void removeSelection(int position) {\r
+        mSelection.remove(position);\r
+        notifyDataSetChanged();\r
+    }\r
+\r
+    public void removeSelection(){\r
+         mSelection.clear();\r
+        notifyDataSetChanged();\r
+    }\r
+\r
+    public ArrayList<Integer> getCheckedItemPositions() {\r
+        ArrayList<Integer> ids = new ArrayList<Integer>();\r
+\r
+        for (Map.Entry<Integer, Boolean> entry : mSelection.entrySet()){\r
+            if (entry.getValue()){\r
+                ids.add(entry.getKey());\r
+            }\r
+        }\r
+        return ids;\r
+    }\r
+\r
+    public ArrayList<OCFile> getCheckedItems() {\r
+        ArrayList<OCFile> files = new ArrayList<OCFile>();\r
+\r
+        for (Map.Entry<Integer, Boolean> entry : mSelection.entrySet()){\r
+            if (entry.getValue()){\r
+                files.add((OCFile) getItem(entry.getKey()));\r
+            }\r
+        }\r
+        return files;\r
+    }\r
 }\r
index fa963fd..79bad6a 100644 (file)
@@ -25,7 +25,9 @@ import java.util.Arrays;
 import java.util.Comparator;
 
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.graphics.Bitmap;
+import android.preference.PreferenceManager;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -41,6 +43,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimetypeIconUtil;
+import com.owncloud.android.utils.FileStorageUtils;
 
 /**
  * This Adapter populates a ListView with all files and directories contained
@@ -53,9 +56,18 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
     private Context mContext;
     private File mDirectory;
     private File[] mFiles = null;
+    private SharedPreferences mAppPreferences;
     
     public LocalFileListAdapter(File directory, Context context) {
         mContext = context;
+
+        mAppPreferences = PreferenceManager
+                .getDefaultSharedPreferences(mContext);
+
+        // Read sorting order, default to sort by name ascending
+        FileStorageUtils.mSortOrder = mAppPreferences.getInt("sortOrder", 0);
+        FileStorageUtils.mSortAscending = mAppPreferences.getBoolean("sortAscending", true);
+
         swapDirectory(directory);
     }
 
@@ -232,7 +244,23 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
                 }
             
             });
+
+            mFiles = FileStorageUtils.sortLocalFolder(mFiles);
         }
         notifyDataSetChanged();
     }
+
+    public void setSortOrder(Integer order, boolean ascending) {
+        SharedPreferences.Editor editor = mAppPreferences.edit();
+        editor.putInt("sortOrder", order);
+        editor.putBoolean("sortAscending", ascending);
+        editor.commit();
+
+        FileStorageUtils.mSortOrder = order;
+        FileStorageUtils.mSortAscending = ascending;
+
+        mFiles = FileStorageUtils.sortLocalFolder(mFiles);
+        notifyDataSetChanged();
+
+    }
 }
index 96414a0..e8289d0 100644 (file)
@@ -39,6 +39,7 @@ public class AccountActionsDialogFragment extends DialogFragment implements
      * Listener interface for the file action fragment.
      */
     public interface FileActionsDialogFragmentListener {
+        // TODO Tobi change to int array?
         public boolean onFileActionChosen(int menuId, int filePosition);
     }
 
diff --git a/src/com/owncloud/android/ui/dialog/ExpirationDatePickerDialogFragment.java b/src/com/owncloud/android/ui/dialog/ExpirationDatePickerDialogFragment.java
new file mode 100644 (file)
index 0000000..502e18a
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ *   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.dialog;
+
+
+import android.app.DatePickerDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.text.format.DateUtils;
+import android.widget.DatePicker;
+import android.widget.Toast;
+
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.activity.FileActivity;
+
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ *  Dialog requesting a date after today.
+ */
+public class ExpirationDatePickerDialogFragment
+        extends DialogFragment
+        implements DatePickerDialog.OnDateSetListener {
+
+    /** Tag for FragmentsManager */
+    public static final String DATE_PICKER_DIALOG = "DATE_PICKER_DIALOG";
+
+    /** Parameter constant for {@link OCFile} instance to set the expiration date */
+    private static final String ARG_FILE = "FILE";
+
+    /** Parameter constant for date chosen initially */
+    private static final String ARG_CHOSEN_DATE_IN_MILLIS = "CHOSEN_DATE_IN_MILLIS";
+
+    /** File to bind an expiration date */
+    private OCFile mFile;
+
+    /**
+     *  Factory method to create new instances
+     *
+     *  @param file                 File to bind an expiration date
+     *  @param chosenDateInMillis   Date chosen when the dialog appears
+     *  @return                     New dialog instance
+     */
+    public static ExpirationDatePickerDialogFragment newInstance(OCFile file, long chosenDateInMillis) {
+        Bundle arguments = new Bundle();
+        arguments.putParcelable(ARG_FILE, file);
+        arguments.putLong(ARG_CHOSEN_DATE_IN_MILLIS, chosenDateInMillis);
+
+        ExpirationDatePickerDialogFragment dialog = new ExpirationDatePickerDialogFragment();
+        dialog.setArguments(arguments);
+        return dialog;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return      A new dialog to let the user choose an expiration date that will be bound to a share link.
+     */
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        // Load arguments
+        mFile = getArguments().getParcelable(ARG_FILE);
+
+        // Chosen date received as an argument must be later than tomorrow ; default to tomorrow in other case
+        final Calendar chosenDate = Calendar.getInstance();
+        long tomorrowInMillis = chosenDate.getTimeInMillis() + DateUtils.DAY_IN_MILLIS;
+        long chosenDateInMillis = getArguments().getLong(ARG_CHOSEN_DATE_IN_MILLIS);
+        if (chosenDateInMillis > tomorrowInMillis) {
+            chosenDate.setTimeInMillis(chosenDateInMillis);
+        } else {
+            chosenDate.setTimeInMillis(tomorrowInMillis);
+        }
+
+        // Create a new instance of DatePickerDialog
+        DatePickerDialog dialog = new DatePickerDialog(
+                getActivity(),
+                this,
+                chosenDate.get(Calendar.YEAR),
+                chosenDate.get(Calendar.MONTH),
+                chosenDate.get(Calendar.DAY_OF_MONTH)
+        );
+
+        // Prevent days in the past may be chosen
+        DatePicker picker = dialog.getDatePicker();
+        picker.setMinDate(tomorrowInMillis - 1000);
+
+        // Enforce spinners view; ignored by MD-based theme in Android >=5, but calendar is REALLY buggy
+        // in Android < 5, so let's be sure it never appears (in tablets both spinners and calendar are
+        // shown by default)
+        picker.setCalendarViewShown(false);
+
+        return dialog;
+    }
+
+    /**
+     * Called when the user choses an expiration date.
+     *
+     * @param view              View instance where the date was chosen
+     * @param year              Year of the date chosen.
+     * @param monthOfYear       Month of the date chosen [0, 11]
+     * @param dayOfMonth        Day of the date chosen
+     */
+    @Override
+    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
+
+        Calendar chosenDate = Calendar.getInstance();
+        chosenDate.set(Calendar.YEAR, year);
+        chosenDate.set(Calendar.MONTH, monthOfYear);
+        chosenDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
+        long chosenDateInMillis = chosenDate.getTimeInMillis();
+
+        ((FileActivity)getActivity()).getFileOperationsHelper().setExpirationDateToShareViaLink(
+                mFile,
+                chosenDateInMillis
+        );
+    }
+}
diff --git a/src/com/owncloud/android/ui/dialog/OwnCloudListPreference.java b/src/com/owncloud/android/ui/dialog/OwnCloudListPreference.java
new file mode 100644 (file)
index 0000000..67ccb3e
--- /dev/null
@@ -0,0 +1,102 @@
+package com.owncloud.android.ui.dialog;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.PreferenceManager;
+import android.support.v7.app.AppCompatDialog;
+import android.util.AttributeSet;
+
+import com.owncloud.android.R;
+import com.owncloud.android.lib.common.utils.Log_OC;
+
+import java.lang.reflect.Method;
+
+public class OwnCloudListPreference extends ListPreference {
+    private static final String TAG = OwnCloudListPreference.class.getSimpleName();
+
+    private Context mContext;
+    private AppCompatDialog mDialog;
+
+    public OwnCloudListPreference(Context context) {
+        super(context);
+        this.mContext = context;
+    }
+
+    public OwnCloudListPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        this.mContext = context;
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public OwnCloudListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+    public OwnCloudListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @Override
+    protected void showDialog(Bundle state) {
+        if (getEntries() == null || getEntryValues() == null) {
+            throw new IllegalStateException(
+                    "ListPreference requires an entries array and an entryValues array.");
+        }
+
+        int preselect = findIndexOfValue(getValue());
+        // TODO for some reason value change is persisted but not directly shown in Android-15 emulator
+        // same thing happens for the Standard ListPreference though
+        android.support.v7.app.AlertDialog.Builder builder =
+                new android.support.v7.app.AlertDialog.Builder(mContext, R.style.ownCloud_AlertDialog)
+                .setTitle(getDialogTitle())
+                .setIcon(getDialogIcon())
+                .setSingleChoiceItems(getEntries(), preselect, this);
+
+        PreferenceManager pm = getPreferenceManager();
+        try {
+            Method method = pm.getClass().getDeclaredMethod(
+                    "registerOnActivityDestroyListener",
+                    PreferenceManager.OnActivityDestroyListener.class);
+            method.setAccessible(true);
+            method.invoke(pm, this);
+        } catch (Exception e) {
+            // no way to handle this but logging it
+            Log_OC.e(TAG, "error invoking registerOnActivityDestroyListener", e);
+        }
+
+        mDialog = builder.create();
+        if (state != null) {
+            mDialog.onRestoreInstanceState(state);
+        }
+        mDialog.show();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        if (which >= 0 && getEntryValues() != null) {
+            String value = getEntryValues()[which].toString();
+            if (callChangeListener(value)) {
+                setValue(value);
+            }
+            dialog.dismiss();
+        }
+    }
+
+    @Override
+    public AppCompatDialog getDialog() {
+        return mDialog;
+    }
+
+    @Override
+    public void onActivityDestroy() {
+        super.onActivityDestroy();
+        if (mDialog != null && mDialog.isShowing()) {
+            mDialog.dismiss();
+        }
+    }
+}
index f8310a1..d42cf46 100644 (file)
@@ -52,9 +52,9 @@ implements ConfirmationDialogFragmentListener {
         RemoveFileDialogFragment frag = new RemoveFileDialogFragment();
         Bundle args = new Bundle();
         
-        int messageStringId = R.string.confirmation_remove_alert;
+        int messageStringId = R.string.confirmation_remove_file_alert;
         
-        int posBtn = R.string.confirmation_remove_remote;
+        int posBtn = R.string.confirmation_remove_file_remote;
         int negBtn = -1;
         if (file.isFolder()) {
             messageStringId = R.string.confirmation_remove_folder_alert;
diff --git a/src/com/owncloud/android/ui/dialog/RemoveFilesDialogFragment.java b/src/com/owncloud/android/ui/dialog/RemoveFilesDialogFragment.java
new file mode 100644 (file)
index 0000000..6d40d8e
--- /dev/null
@@ -0,0 +1,159 @@
+/**
+ *   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.dialog;
+
+/**
+ *  Dialog requiring confirmation before removing a given OCFile.  
+ * 
+ *  Triggers the removal according to the user response.
+ */
+
+import android.app.Dialog;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.ui.activity.ComponentsGetter;
+import com.owncloud.android.ui.dialog.ConfirmationDialogFragment.ConfirmationDialogFragmentListener;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+public class RemoveFilesDialogFragment extends ConfirmationDialogFragment
+implements ConfirmationDialogFragmentListener {
+
+    private ArrayList<OCFile> mTargetFiles;
+
+    private static final String ARG_TARGET_FILES = "TARGET_FILES";
+
+    /**
+     * Public factory method to create new RemoveFileDialogFragment instances.
+     * 
+     * @param files            Files to remove.
+     * @return                Dialog ready to show.
+     */
+    public static RemoveFilesDialogFragment newInstance(ArrayList<OCFile> files) {
+        RemoveFilesDialogFragment frag = new RemoveFilesDialogFragment();
+        Bundle args = new Bundle();
+        
+        int messageStringId = R.string.confirmation_remove_files_alert;
+        
+        int posBtn = R.string.confirmation_remove_file_remote;
+        int negBtn = -1;
+
+        boolean containsFolder = false;
+        boolean containsDown = false;
+        for (OCFile file: files) {
+            if (file.isFolder()) containsFolder = true;
+            if (file.isDown()) containsDown = true;
+        }
+
+        if (containsFolder) {
+            messageStringId = R.string.confirmation_remove_folders_alert;
+            posBtn = R.string.confirmation_remove_remote_and_local;
+            negBtn = R.string.confirmation_remove_local;
+        } else if (containsDown) {
+            posBtn = R.string.confirmation_remove_remote_and_local;
+            negBtn = R.string.confirmation_remove_local;
+        }
+        
+        args.putInt(ARG_CONF_RESOURCE_ID, messageStringId);
+        args.putStringArray(ARG_CONF_ARGUMENTS, new String[]{MainApp.getAppContext().getString(R.string.confirmation_remove_files)});
+        args.putInt(ARG_POSITIVE_BTN_RES, posBtn);
+        args.putInt(ARG_NEUTRAL_BTN_RES, R.string.common_no);
+        args.putInt(ARG_NEGATIVE_BTN_RES, negBtn);
+        args.putParcelableArrayList(ARG_TARGET_FILES, files);
+        frag.setArguments(args);
+        
+        return frag;
+    }
+    
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Dialog dialog = super.onCreateDialog(savedInstanceState);
+        mTargetFiles = getArguments().getParcelableArrayList(ARG_TARGET_FILES);
+        
+        setOnConfirmationListener(this);
+        
+        return dialog;
+    }    
+
+    /**
+     * Performs the removal of the target file, both locally and in the server.
+     */
+    @Override
+    public void onConfirmation(String callerTag) {
+        ComponentsGetter cg = (ComponentsGetter) getActivity();
+        FileDataStorageManager storageManager = cg.getStorageManager();
+        for (OCFile targetFile : mTargetFiles) {
+            if (storageManager.getFileById(targetFile.getFileId()) != null) {
+                cg.getFileOperationsHelper().removeFile(targetFile, false);
+            }
+        }
+    }
+    
+    /**
+     * Performs the removal of the local copy of the target file
+     */
+    @Override
+    public void onCancel(String callerTag) {
+        ComponentsGetter cg = (ComponentsGetter) getActivity();
+
+        for (OCFile targetFile : mTargetFiles) {
+            cg.getFileOperationsHelper().removeFile(targetFile, true);
+
+            FileDataStorageManager storageManager = cg.getStorageManager();
+
+            boolean containsFavorite = false;
+            if (targetFile.isFolder()) {
+                Vector<OCFile> files = storageManager.getFolderContent(targetFile, false);
+                for (OCFile file : files) {
+                    containsFavorite = file.isFavorite() || containsFavorite;
+
+                    if (containsFavorite)
+                        break;
+                }
+            }
+
+            // Remove etag for parent, if file is a favorite
+            // or is a folder and contains favorite
+            if (targetFile.isFavorite() || containsFavorite) {
+                OCFile folder = null;
+                if (targetFile.isFolder()) {
+                    folder = targetFile;
+                } else {
+                    folder = storageManager.getFileById(targetFile.getParentId());
+                }
+
+                folder.setEtag("");
+                storageManager.saveFile(folder);
+            }
+        }
+    }
+
+    @Override
+    public void onNeutral(String callerTag) {
+        // nothing to do here
+    }
+}
\ No newline at end of file
index a315a1d..29eaac2 100644 (file)
@@ -44,11 +44,8 @@ import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.owncloud.android.R;
-import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.ui.activity.ComponentsGetter;
 import com.owncloud.android.ui.activity.CopyToClipboardActivity;
-import com.owncloud.android.ui.activity.FileActivity;
 
 /**
  * Dialog showing a list activities able to resolve a given Intent, 
@@ -61,20 +58,15 @@ public class ShareLinkToDialog  extends DialogFragment {
             ".ARG_INTENT";
     private final static String ARG_PACKAGES_TO_EXCLUDE =  ShareLinkToDialog.class.getSimpleName() +
             ".ARG_PACKAGES_TO_EXCLUDE";
-    private final static String ARG_FILE_TO_SHARE = ShareLinkToDialog.class.getSimpleName() +
-            ".FILE_TO_SHARE";
-    
+
     private ActivityAdapter mAdapter;
-    private OCFile mFile;
     private Intent mIntent;
     
-    public static ShareLinkToDialog newInstance(Intent intent, String[] packagesToExclude,
-                                                OCFile fileToShare) {
+    public static ShareLinkToDialog newInstance(Intent intent, String[] packagesToExclude) {
         ShareLinkToDialog f = new ShareLinkToDialog();
         Bundle args = new Bundle();
         args.putParcelable(ARG_INTENT, intent);
         args.putStringArray(ARG_PACKAGES_TO_EXCLUDE, packagesToExclude);
-        args.putParcelable(ARG_FILE_TO_SHARE, fileToShare);
         f.setArguments(args);
         return f;
     }
@@ -90,8 +82,7 @@ public class ShareLinkToDialog  extends DialogFragment {
         String[] packagesToExclude = getArguments().getStringArray(ARG_PACKAGES_TO_EXCLUDE);
         List<String> packagesToExcludeList = Arrays.asList(packagesToExclude != null ?
                 packagesToExclude : new String[0]);
-        mFile = getArguments().getParcelable(ARG_FILE_TO_SHARE);
-        
+
         PackageManager pm= getActivity().getPackageManager();
         List<ResolveInfo> activities = pm.queryIntentActivities(mIntent,
                 PackageManager.MATCH_DEFAULT_ONLY);
@@ -142,19 +133,10 @@ public class ShareLinkToDialog  extends DialogFragment {
                             ComponentName name=new ComponentName(
                                     actInfo.applicationInfo.packageName, 
                                     actInfo.name);
-                            mIntent.setComponent(name);                               
-
-                            if (sendAction) {
-                                dialog.dismiss();    // explicitly added for Android 2.x devices
-
-                                // Send the file
-                                ((FileActivity)getActivity()).startActivity(mIntent);
+                            mIntent.setComponent(name);
 
-                            } else {
-                                // Create a new share resource
-                                ((ComponentsGetter)getActivity()).getFileOperationsHelper()
-                                    .shareFileWithLinkToApp(mFile, "", mIntent);
-                            }
+                            // Send the file
+                            getActivity().startActivity(mIntent);
                         }
         })
         .create();
index d069b5a..1b7def2 100644 (file)
@@ -21,7 +21,6 @@ package com.owncloud.android.ui.dialog;
 import android.support.v7.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.os.Bundle;
 import android.support.v4.app.DialogFragment;
 import android.view.LayoutInflater;
@@ -45,25 +44,26 @@ public class SharePasswordDialogFragment extends DialogFragment
         implements DialogInterface.OnClickListener {
 
     private static final String ARG_FILE = "FILE";
-    private static final String ARG_SEND_INTENT = "SEND_INTENT";
+    private static final String ARG_CREATE_SHARE = "CREATE_SHARE";
 
     public static final String PASSWORD_FRAGMENT = "PASSWORD_FRAGMENT";
 
     private OCFile mFile;
-    private Intent mSendIntent;
+    private boolean mCreateShare;
 
     /**
      * Public factory method to create new SharePasswordDialogFragment instances.
      *
-     * @param file
-     * @param sendIntent
-     * @return              Dialog ready to show.
+     * @param   file            OCFile bound to the public share that which password will be set or updated
+     * @param   createShare     When 'true', the public share will be created; when 'false', will be assumed
+     *                          that the public share already exists, and its state will be directly updated.
+     * @return                  Dialog ready to show.
      */
-    public static SharePasswordDialogFragment newInstance(OCFile file, Intent sendIntent) {
+    public static SharePasswordDialogFragment newInstance(OCFile file, boolean createShare) {
         SharePasswordDialogFragment frag = new SharePasswordDialogFragment();
         Bundle args = new Bundle();
         args.putParcelable(ARG_FILE, file);
-        args.putParcelable(ARG_SEND_INTENT, sendIntent);
+        args.putBoolean(ARG_CREATE_SHARE, createShare);
         frag.setArguments(args);
         return frag;
     }
@@ -71,7 +71,7 @@ public class SharePasswordDialogFragment extends DialogFragment
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         mFile = getArguments().getParcelable(ARG_FILE);
-        mSendIntent = getArguments().getParcelable(ARG_SEND_INTENT);
+        mCreateShare = getArguments().getBoolean(ARG_CREATE_SHARE, false);
 
         // Inflate the layout for the dialog
         LayoutInflater inflater = getActivity().getLayoutInflater();
@@ -97,9 +97,6 @@ public class SharePasswordDialogFragment extends DialogFragment
     @Override
     public void onClick(DialogInterface dialog, int which) {
         if (which == AlertDialog.BUTTON_POSITIVE) {
-            // Enable the flag "Share again"
-            ((FileActivity) getActivity()).setTryShareAgain(true);
-
             String password =
                     ((TextView)(getDialog().findViewById(R.id.share_password)))
                         .getText().toString();
@@ -112,13 +109,16 @@ public class SharePasswordDialogFragment extends DialogFragment
                 return;
             }
 
-            // Share the file
-            ((FileActivity)getActivity()).getFileOperationsHelper()
-                                    .shareFileWithLinkToApp(mFile, password, mSendIntent);
+            if (mCreateShare) {
+                // Share the file
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        shareFileViaLink(mFile, password);
 
-        } else {
-            // Disable the flag "Share again"
-            ((FileActivity) getActivity()).setTryShareAgain(false);
+            } else {
+                // updat existing link
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        setPasswordToShareViaLink(mFile, password);
+            }
         }
     }
 }
index 24015d0..589ccfe 100644 (file)
@@ -22,11 +22,15 @@ package com.owncloud.android.ui.fragment;
 
 import java.util.ArrayList;
 
+import android.app.Activity;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.ActionMode;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
@@ -36,12 +40,16 @@ import android.widget.GridView;
 import android.widget.ListAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
+import android.widget.Toast;
 
+import com.getbase.floatingactionbutton.FloatingActionButton;
+import com.getbase.floatingactionbutton.FloatingActionsMenu;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.ExtendedListView;
 import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
 import com.owncloud.android.ui.adapter.FileListListAdapter;
+import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 
 import third_parties.in.srain.cube.GridViewWithHeaderAndFooter;
 
@@ -64,6 +72,11 @@ public class ExtendedListFragment extends Fragment
     private SwipeRefreshLayout mRefreshGridLayout;
     private SwipeRefreshLayout mRefreshEmptyLayout;
     private TextView mEmptyListMessage;
+
+    private FloatingActionsMenu fabMain;
+    private FloatingActionButton fabUpload;
+    private FloatingActionButton fabMkdir;
+    private FloatingActionButton fabUploadFromApp;
     
     // Save the state of the scroll in browsing
     private ArrayList<Integer> mIndexes;
@@ -96,8 +109,23 @@ public class ExtendedListFragment extends Fragment
         return mCurrentListView;
     }
 
+    public FloatingActionButton getFabUpload() {
+        return fabUpload;
+    }
+
+    public FloatingActionButton getFabUploadFromApp() {
+        return fabUploadFromApp;
+    }
 
-    protected void switchToGridView() {
+    public FloatingActionButton getFabMkdir() {
+        return fabMkdir;
+    }
+
+    public FloatingActionsMenu getFabMain() {
+        return fabMain;
+    }
+
+    public void switchToGridView() {
         if ((mCurrentListView == mListView)) {
 
             mListView.setAdapter(null);
@@ -112,8 +140,8 @@ public class ExtendedListFragment extends Fragment
             mCurrentListView = mGridView;
         }
     }
-    
-    protected void switchToListView() {
+
+    public void switchToListView() {
         if (mCurrentListView == mGridView) {
             mGridView.setAdapter(null);
             mRefreshGridLayout.setVisibility(View.GONE);
@@ -127,6 +155,13 @@ public class ExtendedListFragment extends Fragment
             mCurrentListView = mListView;
         }
     }
+
+    public boolean isGridView(){
+        if (mAdapter instanceof FileListListAdapter) {
+            return ((FileListListAdapter) mAdapter).isGridMode();
+        }
+        return false;
+    }
     
     
     @Override
@@ -134,15 +169,61 @@ public class ExtendedListFragment extends Fragment
                              Bundle savedInstanceState) {
         Log_OC.d(TAG, "onCreateView");
 
+        // TODO Tobi remove
+//         AbsListView.MultiChoiceModeListener listener = new AbsListView.MultiChoiceModeListener() {
+//            @Override
+//            public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
+//                // Capture total checked items
+//                final int checkedCount = mListView.getCheckedItemCount();
+//                // Set the CAB title according to total checked items
+//                mode.setTitle(checkedCount + " Selected");
+//                // Calls toggleSelection method from ListViewAdapter Class
+//                 // mAdapter.toggleSelection(position);
+//
+//                if (checked){
+//                    mAdapter.setNewSelection(position,checked);
+//                } else {
+//                    mAdapter.removeSelection(position);
+//                }
+//            }
+//
+//            @Override
+//            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+//                mode.getMenuInflater().inflate(R.menu.context, menu);
+//                return true;
+//            }
+//
+//            @Override
+//            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+//                return false;
+//            }
+//
+//            @Override
+//            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+//                return false;
+//            }
+//
+//            @Override
+//            public void onDestroyActionMode(ActionMode mode) {
+//                // mAdapter.removeSelection();
+//            }
+//        };
+
         View v = inflater.inflate(R.layout.list_fragment, null);
 
         mListView = (ExtendedListView)(v.findViewById(R.id.list_root));
         mListView.setOnItemClickListener(this);
+        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+        // mListView.setMultiChoiceModeListener(listener);
         mListFooterView = inflater.inflate(R.layout.list_footer, null, false);
 
         mGridView = (GridViewWithHeaderAndFooter) (v.findViewById(R.id.grid_root));
         mGridView.setNumColumns(GridView.AUTO_FIT);
         mGridView.setOnItemClickListener(this);
+        mGridView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+
+        // mGridView.setMultiChoiceModeListener(listener);
+
         mGridFooterView = inflater.inflate(R.layout.list_footer, null, false);
 
         if (savedInstanceState != null) {
@@ -171,6 +252,11 @@ public class ExtendedListFragment extends Fragment
 
         mCurrentListView = mListView;   // list as default
 
+        fabMain = (FloatingActionsMenu) v.findViewById(R.id.fab_main);
+        fabUpload = (FloatingActionButton) v.findViewById(R.id.fab_upload);
+        fabMkdir = (FloatingActionButton) v.findViewById(R.id.fab_mkdir);
+        fabUploadFromApp = (FloatingActionButton) v.findViewById(R.id.fab_upload_from_app);
+
         return v;
     }
 
@@ -320,6 +406,23 @@ public class ExtendedListFragment extends Fragment
     }
 
     /**
+     * Disables FAB.
+     *
+     * Sets the 'visibility' state of the FAB contained in the fragment.
+     *
+     * When 'false' is set, FAB visibility is set to View.GONE programatically,
+     *
+     * @param   enabled     Desired visibility for the FAB.
+     */
+    public void setFabEnabled(boolean enabled) {
+        if(enabled) {
+            fabMain.setVisibility(View.VISIBLE);
+        } else {
+            fabMain.setVisibility(View.GONE);
+        }
+    }
+
+    /**
      * Set message for empty list view
      */
     public void setMessageForEmptyList(String message) {
index 543378f..e9cd916 100644 (file)
@@ -217,6 +217,24 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
             item.setVisible(false);
             item.setEnabled(false);
         }
+
+        item = menu.findItem(R.id.action_switch_view);
+        if (item != null){
+            item.setVisible(false);
+            item.setEnabled(false);
+        }
+
+        item = menu.findItem(R.id.action_sync_account);
+        if (item != null) {
+            item.setVisible(false);
+            item.setEnabled(false);
+        }
+
+        item = menu.findItem(R.id.action_sort);
+        if (item != null) {
+            item.setVisible(false);
+            item.setEnabled(false);
+        }
     }
 
 
@@ -227,18 +245,9 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.action_share_file: {
-                mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
-                return true;
-            }
-            case R.id.action_share_with_users: {
                 mContainerActivity.getFileOperationsHelper().showShareFile(getFile());
                 return true;
             }
-            case R.id.action_unshare_file: {
-                mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
-                return true;
-            }
-
             case R.id.action_open_file_with: {
                 mContainerActivity.getFileOperationsHelper().openFile(getFile());
                 return true;
index df5b34a..c5f74a7 100644 (file)
@@ -37,6 +37,7 @@ import android.widget.ListView;
 import com.owncloud.android.R;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.adapter.LocalFileListAdapter;
+import com.owncloud.android.utils.FileStorageUtils;
 
 
 /**
@@ -54,7 +55,6 @@ public class LocalFileListFragment extends ExtendedListFragment {
     /** Adapter to connect the data from the directory with the View object */
     private LocalFileListAdapter mAdapter = null;
 
-    
     /**
      * {@inheritDoc}
      */
@@ -79,6 +79,7 @@ public class LocalFileListFragment extends ExtendedListFragment {
         View v = super.onCreateView(inflater, container, savedInstanceState);
         setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
         setSwipeEnabled(false); // Disable pull-to-refresh
+        setFabEnabled(false); // Disable FAB
         setMessageForEmptyList(getString(R.string.local_file_list_empty));
         Log_OC.i(TAG, "onCreateView() end");
         return v;
@@ -228,7 +229,19 @@ public class LocalFileListFragment extends ExtendedListFragment {
         return result.toArray(new String[result.size()]);
     }
 
-    
+    public void sortByName(boolean descending) {
+        mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
+    }
+
+    public void sortByDate(boolean descending) {
+        mAdapter.setSortOrder(FileStorageUtils.SORT_DATE, descending);
+    }
+
+    public void sortBySize(boolean descending) {
+        mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
+    }
+
+
     /**
      * Interface to implement by any Activity that includes some instance of LocalFileListFragment
      */
index 066ff0a..c606e67 100644 (file)
  */
 package com.owncloud.android.ui.fragment;
 
+import android.accounts.Account;
 import android.app.Activity;
+import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.net.Uri;
 import android.os.Bundle;
+import android.preference.PreferenceManager;
 import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.ActionMode;
+import android.support.v7.app.AlertDialog;
 import android.view.ContextMenu;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
+import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.PopupMenu;
+import android.widget.TextView;
+import android.widget.Toast;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -42,29 +55,37 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
+import com.owncloud.android.media.MediaService;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
 import com.owncloud.android.ui.activity.FolderPickerActivity;
 import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
+import com.owncloud.android.ui.activity.UploadFilesActivity;
 import com.owncloud.android.ui.adapter.FileListListAdapter;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
+import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.ui.dialog.FileActionsDialogFragment;
 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
+import com.owncloud.android.ui.dialog.RemoveFilesDialogFragment;
 import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
+import com.owncloud.android.ui.dialog.UploadSourceDialogFragment;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
+import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.ExceptionHandler;
+import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.ui.preview.PreviewTextFragment;
 import com.owncloud.android.utils.FileStorageUtils;
 
 import java.io.File;
+import java.util.ArrayList;
 
 /**
  * A Fragment that lists all files and folders in a given path.
  *
  * TODO refactor to get rid of direct dependency on FileDisplayActivity
  */
-public class OCFileListFragment extends ExtendedListFragment
-        implements FileActionsDialogFragment.FileActionsDialogFragmentListener {
+public class OCFileListFragment extends ExtendedListFragment {
     
     private static final String TAG = OCFileListFragment.class.getSimpleName();
 
@@ -73,8 +94,12 @@ public class OCFileListFragment extends ExtendedListFragment
 
     public final static String ARG_JUST_FOLDERS = MY_PACKAGE + ".JUST_FOLDERS";
     public final static String ARG_ALLOW_CONTEXTUAL_ACTIONS = MY_PACKAGE + ".ALLOW_CONTEXTUAL";
+    public final static String ARG_HIDE_FAB = MY_PACKAGE + ".HIDE_FAB";
 
     private static final String KEY_FILE = MY_PACKAGE + ".extra.FILE";
+    private static final String KEY_FAB_EVER_CLICKED = "FAB_EVER_CLICKED";
+
+    private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
 
     private FileFragment.ContainerActivity mContainerActivity;
 
@@ -83,8 +108,8 @@ public class OCFileListFragment extends ExtendedListFragment
     private boolean mJustFolders;
     
     private OCFile mTargetFile;
-    
-   
+
+    private boolean miniFabClicked = false;
     
     /**
      * {@inheritDoc}
@@ -145,15 +170,211 @@ public class OCFileListFragment extends ExtendedListFragment
         setListAdapter(mAdapter);
 
         registerLongClickListener();
+
+        boolean hideFab = (args != null) && args.getBoolean(ARG_HIDE_FAB, false);
+        if (hideFab) {
+            setFabEnabled(false);
+        } else {
+            setFabEnabled(true);
+            registerFabListeners();
+
+            // detect if a mini FAB has ever been clicked
+            final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+            if(prefs.getLong(KEY_FAB_EVER_CLICKED, 0) > 0) {
+                miniFabClicked = true;
+            }
+
+            // add labels to the min FABs when none of them has ever been clicked on
+            if(!miniFabClicked) {
+                setFabLabels();
+            } else {
+                removeFabLabels();
+            }
+        }
   }
 
+    /**
+     * adds labels to all mini FABs.
+     */
+    private void setFabLabels() {
+        getFabUpload().setTitle(getResources().getString(R.string.actionbar_upload));
+        getFabMkdir().setTitle(getResources().getString(R.string.actionbar_mkdir));
+        getFabUploadFromApp().setTitle(getResources().getString(R.string.actionbar_upload_from_apps));
+    }
+
+    /**
+     * registers all listeners on all mini FABs.
+     */
+    private void registerFabListeners() {
+        registerFabUploadListeners();
+        registerFabMkDirListeners();
+        registerFabUploadFromAppListeners();
+    }
+
+    /**
+     * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener}
+     * on the Upload mini FAB for the linked action and {@link Toast} showing the underlying action.
+     */
+    private void registerFabUploadListeners() {
+        getFabUpload().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent action = new Intent(getActivity(), UploadFilesActivity.class);
+                action.putExtra(
+                        UploadFilesActivity.EXTRA_ACCOUNT,
+                        ((FileActivity) getActivity()).getAccount()
+                );
+                getActivity().startActivityForResult(action, UploadSourceDialogFragment.ACTION_SELECT_MULTIPLE_FILES);
+                getFabMain().collapse();
+                recordMiniFabClick();
+            }
+        });
+
+        getFabUpload().setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                Toast.makeText(getActivity(), R.string.actionbar_upload, Toast.LENGTH_SHORT).show();
+                return true;
+            }
+        });
+    }
+
+    /**
+     * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener}
+     * on the 'Create Dir' mini FAB for the linked action and {@link Toast} showing the underlying action.
+     */
+    private void registerFabMkDirListeners() {
+        getFabMkdir().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                CreateFolderDialogFragment dialog =
+                        CreateFolderDialogFragment.newInstance(mFile);
+                dialog.show(getActivity().getSupportFragmentManager(), FileDisplayActivity.DIALOG_CREATE_FOLDER);
+                getFabMain().collapse();
+                recordMiniFabClick();
+            }
+        });
+
+        getFabMkdir().setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                Toast.makeText(getActivity(), R.string.actionbar_mkdir, Toast.LENGTH_SHORT).show();
+                return true;
+            }
+        });
+    }
+
+    /**
+     * registers {@link android.view.View.OnClickListener} and {@link android.view.View.OnLongClickListener}
+     * on the Upload from App mini FAB for the linked action and {@link Toast} showing the underlying action.
+     */
+    private void registerFabUploadFromAppListeners() {
+        getFabUploadFromApp().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent action = new Intent(Intent.ACTION_GET_CONTENT);
+                action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
+
+                //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
+                    action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+                }
+
+                getActivity().startActivityForResult(
+                        Intent.createChooser(action, getString(R.string.upload_chooser_title)),
+                        UploadSourceDialogFragment.ACTION_SELECT_CONTENT_FROM_APPS
+                );
+                getFabMain().collapse();
+                recordMiniFabClick();
+            }
+        });
+
+        getFabUploadFromApp().setOnLongClickListener(new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                Toast.makeText(getActivity(),
+                        R.string.actionbar_upload_from_apps,
+                        Toast.LENGTH_SHORT).show();
+                return true;
+            }
+        });
+    }
+
+    /**
+     * records a click on a mini FAB and thus:
+     * <ol>
+     *     <li>persists the click fact</li>
+     *     <li>removes the mini FAB labels</li>
+     * </ol>
+     */
+    private void recordMiniFabClick() {
+        // only record if it hasn't been done already at some other time
+        if(!miniFabClicked) {
+            final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
+            sp.edit().putLong(KEY_FAB_EVER_CLICKED, 1).commit();
+            miniFabClicked = true;
+        }
+    }
+
+    /**
+     * removes the labels on all known min FABs.
+     */
+    private void removeFabLabels() {
+        getFabUpload().setTitle(null);
+        getFabMkdir().setTitle(null);
+        getFabUploadFromApp().setTitle(null);
+        ((TextView) getFabUpload().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE);
+        ((TextView) getFabMkdir().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE);
+        ((TextView) getFabUploadFromApp().getTag(com.getbase.floatingactionbutton.R.id.fab_label)).setVisibility(View.GONE);
+    }
+
     private void registerLongClickListener() {
-        getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
-            public boolean onItemLongClick(AdapterView<?> arg0, View v,
-                                           int index, long arg3) {
-                showFileAction(index);
+        getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
+            private Menu menu;
+
+            @Override
+            public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
+                final int checkedCount = getListView().getCheckedItemCount();
+                // TODO Tobi extract to values
+                mode.setTitle(checkedCount + " selected");
+
+                if (checked) {
+                    mAdapter.setNewSelection(position, checked);
+                } else {
+                    mAdapter.removeSelection(position);
+                }
+
+                // TODO maybe change: only recreate menu if count changes
+                menu.clear();
+                if (checkedCount == 1) {
+                    createContextMenu(menu);
+                } else {
+                    // download, move, copy, delete
+                    getActivity().getMenuInflater().inflate(R.menu.multiple_file_actions_menu, menu);
+                }
+
+            }
+
+            @Override
+            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+                this.menu = menu;
                 return true;
             }
+
+            @Override
+            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+                return false;
+            }
+
+            @Override
+            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+                return onFileActionChosen(item.getItemId());
+            }
+
+            @Override
+            public void onDestroyActionMode(ActionMode mode) {
+                mAdapter.removeSelection();
+            }
         });
     }
 
@@ -212,11 +433,11 @@ public class OCFileListFragment extends ExtendedListFragment
 
     /**
      * Call this, when the user presses the up button.
-     *
-     * Tries to move up the current folder one level. If the parent folder was removed from the
-     * database, it continues browsing up until finding an existing folders.
-     * <p/>
-     * return       Count of folder levels browsed up.
+     * <p>
+     *     Tries to move up the current folder one level. If the parent folder was removed from the
+     *     database, it continues browsing up until finding an existing folders.
+     * </p>
+     * @return Count of folder levels browsed up.
      */
     public int onBrowseUp() {
         OCFile parentDir = null;
@@ -244,8 +465,7 @@ public class OCFileListFragment extends ExtendedListFragment
             }   // exit is granted because storageManager.getFileByPath("/") never returns null
             mFile = parentDir;
 
-            // TODO Enable when "On Device" is recovered ?
-            listDirectory(mFile /*, MainApp.getOnlyOnDevice()*/);
+            listDirectory(mFile, MainApp.getOnlyOnDevice());
 
             onRefresh(false);
 
@@ -263,8 +483,7 @@ public class OCFileListFragment extends ExtendedListFragment
         if (file != null) {
             if (file.isFolder()) {
                 // update state and view of this fragment
-                // TODO Enable when "On Device" is recovered ?
-                listDirectory(file/*, MainApp.getOnlyOnDevice()*/);
+                listDirectory(file, MainApp.getOnlyOnDevice());
                 // then, notify parent activity to let it update its state and view
                 mContainerActivity.onBrowsedDownTo(file);
                 // save index and top position
@@ -276,41 +495,36 @@ public class OCFileListFragment extends ExtendedListFragment
                     ((FileDisplayActivity)mContainerActivity).startImagePreview(file);
                 } else if (PreviewTextFragment.canBePreviewed(file)){
                     ((FileDisplayActivity)mContainerActivity).startTextPreview(file);
-                } else if (file.isDown()) {
-                    if (PreviewMediaFragment.canBePreviewed(file)) {
+                } else if (PreviewMediaFragment.canBePreviewed(file)) {
                         // media preview
                         ((FileDisplayActivity) mContainerActivity).startMediaPreview(file, 0, true);
-                    } else {
+                    } else if (file.isDown()) {
                         mContainerActivity.getFileOperationsHelper().openFile(file);
-                    }
-
                 } else {
                     // automatic download, preview on finish
                     ((FileDisplayActivity) mContainerActivity).startDownloadForPreview(file);
                 }
-
             }
-
         } else {
             Log_OC.d(TAG, "Null object in ListAdapter!!");
         }
-
     }
 
     /**
      * {@inheritDoc}
      */
-    @Override
-    public void onCreateContextMenu(
-            ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+    // TODO Tobi needed?
+    public void createContextMenu(Menu menu) {
         Bundle args = getArguments();
         boolean allowContextualActions =
                 (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
         if (allowContextualActions) {
             MenuInflater inflater = getActivity().getMenuInflater();
             inflater.inflate(R.menu.file_actions_menu, menu);
-            AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
-            OCFile targetFile = (OCFile) mAdapter.getItem(info.position);
+            OCFile targetFile = null;
+            if (mAdapter.getCheckedItems().size() == 1){
+                targetFile = mAdapter.getCheckedItems().get(0);
+            }
 
             if (mContainerActivity.getStorageManager() != null) {
                 FileMenuFilter mf = new FileMenuFilter(
@@ -333,91 +547,127 @@ public class OCFileListFragment extends ExtendedListFragment
                     item.setEnabled(false);
                 }
             }
+
+//            String.format(mContext.getString(R.string.subject_token),
+//                    getClient().getCredentials().getUsername(), file.getFileName()));
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean onFileActionChosen(int menuId, int filePosition) {
-        mTargetFile = (OCFile) mAdapter.getItem(filePosition);
-        switch (menuId) {
-            case R.id.action_share_file: {
-                mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
-                return true;
-            }
-            case R.id.action_share_with_users: {
-                mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile);
-                return true;
-            }
-            case R.id.action_open_file_with: {
-                mContainerActivity.getFileOperationsHelper().openFile(mTargetFile);
-                return true;
-            }
-            case R.id.action_unshare_file: {
-                mContainerActivity.getFileOperationsHelper().unshareFileWithLink(mTargetFile);
-                return true;
-            }
-            case R.id.action_rename_file: {
-                RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
-                dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
-                return true;
-            }
-            case R.id.action_remove_file: {
-                RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
-                dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
-                return true;
-            }
-            case R.id.action_download_file:
-            case R.id.action_sync_file: {
-                mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
-                return true;
-            }
-            case R.id.action_cancel_sync: {
-                ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
-                return true;
-            }
-            case R.id.action_see_details: {
-                mContainerActivity.showDetails(mTargetFile);
-                return true;
-            }
-            case R.id.action_send_file: {
-                // Obtain the file
-                if (!mTargetFile.isDown()) {  // Download the file
-                    Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
-                    ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
+    public boolean onFileActionChosen(int menuId) {
+        if (mAdapter.getCheckedItems().size() == 1){
+            OCFile mTargetFile = mAdapter.getCheckedItems().get(0);
 
-                } else {
-                    mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+            switch (menuId) {
+                case R.id.action_share_file: {
+                    mContainerActivity.getFileOperationsHelper().showShareFile(mTargetFile);
+                    return true;
                 }
-                return true;
+                case R.id.action_open_file_with: {
+                    mContainerActivity.getFileOperationsHelper().openFile(mTargetFile);
+                    return true;
+                }
+                case R.id.action_rename_file: {
+                    RenameFileDialogFragment dialog = RenameFileDialogFragment.newInstance(mTargetFile);
+                    dialog.show(getFragmentManager(), FileDetailFragment.FTAG_RENAME_FILE);
+                    return true;
+                }
+                case R.id.action_remove_file: {
+                    RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(mTargetFile);
+                    dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
+                    return true;
+                }
+                case R.id.action_download_file:
+                case R.id.action_sync_file: {
+                    mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
+                    return true;
+                }
+                case R.id.action_cancel_sync: {
+                    ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
+                    return true;
+                }
+                case R.id.action_see_details: {
+                    mContainerActivity.showDetails(mTargetFile);
+                    return true;
+                }
+                case R.id.action_send_file: {
+                    // Obtain the file
+                    if (!mTargetFile.isDown()) {  // Download the file
+                        Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
+                        ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
+                        return true;
+                    } else {
+                        mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+                    }
+                }
+                case R.id.action_stream_file: {
+                    Account account = ((FileActivity)mContainerActivity).getAccount();
+                    Context context = MainApp.getAppContext();
+                    String uri = PreviewMediaFragment.generateUrlWithCredentials(account, context, mTargetFile);
+                    MediaService.streamWithExternalApp(uri, getActivity()).show();
+                    return true;
+                }
+                case R.id.action_move: {
+                    Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+                    ArrayList files = new ArrayList();
+                    files.add(mTargetFile);
+                    action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, files);
+                    getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
+                    return true;
+                }
+                case R.id.action_favorite_file: {
+                    mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
+                    return true;
+                }
+                case R.id.action_unfavorite_file: {
+                    mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
+                    return true;
+                }
+                case R.id.action_copy:
+                    Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+                    ArrayList files = new ArrayList();
+                    files.add(mTargetFile);
+                    action.putExtra(FolderPickerActivity.EXTRA_FILES, files);
+                    getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES);
+                    return true;
+                default:
+                    return false;
             }
-            case R.id.action_move: {
-                Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+        } else {
+            ArrayList<OCFile> mTargetFiles = mAdapter.getCheckedItems();
 
-                // Pass mTargetFile that contains info of selected file/folder
-                action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
-                getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
-                return true;
-            }
-            case R.id.action_favorite_file: {
-                mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
-                return true;
-            }
-            case R.id.action_unfavorite_file: {
-                mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
-                return true;
+            switch (menuId) {
+                case R.id.action_remove_file: {
+                    RemoveFilesDialogFragment dialog = RemoveFilesDialogFragment.newInstance(mTargetFiles);
+                    dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
+                    return true;
+                }
+                case R.id.action_download_file:
+                case R.id.action_sync_file: {
+                    mContainerActivity.getFileOperationsHelper().syncFiles(mTargetFiles);
+                    return true;
+                }
+                case R.id.action_move: {
+                    Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+                    action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles);
+                    getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
+                    return true;
+                }
+                case R.id.action_favorite_file: {
+                    mContainerActivity.getFileOperationsHelper().toggleFavorites(mTargetFiles, true);
+                    return true;
+                }
+                case R.id.action_unfavorite_file: {
+                    mContainerActivity.getFileOperationsHelper().toggleFavorites(mTargetFiles, false);
+                    return true;
+                }
+                case R.id.action_copy:
+                    Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+                    action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, mTargetFiles);
+                    getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES);
+                    return true;
+                default:
+                    return false;
             }
-            case R.id.action_copy:
-                Intent action = new Intent(getActivity(), FolderPickerActivity.class);
-
-                // Pass mTargetFile that contains info of selected file/folder
-                action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
-                getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES);
-                return true;
-            default:
-                return false;
         }
     }
     
@@ -427,8 +677,7 @@ public class OCFileListFragment extends ExtendedListFragment
     @Override
     public boolean onContextItemSelected (MenuItem item) {
         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
-        boolean matched = onFileActionChosen(item.getItemId(),
-                ((AdapterContextMenuInfo) item.getMenuInfo()).position);
+        boolean matched = onFileActionChosen(item.getItemId())  ;
         if(!matched) {
             return super.onContextItemSelected(item);
         } else {
@@ -448,17 +697,14 @@ public class OCFileListFragment extends ExtendedListFragment
     }
 
     /**
-     * Calls {@link OCFileListFragment#listDirectory(OCFile)} with a null parameter
+     * Calls {@link OCFileListFragment#listDirectory(OCFile, boolean)} with a null parameter
      */
-    public void listDirectory(/*boolean onlyOnDevice*/){
-        listDirectory(null);
-        // TODO Enable when "On Device" is recovered ?
-        // listDirectory(null, onlyOnDevice);
+    public void listDirectory(boolean onlyOnDevice){
+        listDirectory(null, onlyOnDevice);
     }
     
     public void refreshDirectory(){
-        // TODO Enable when "On Device" is recovered ?
-        listDirectory(getCurrentFile()/*, MainApp.getOnlyOnDevice()*/);
+        listDirectory(getCurrentFile(), MainApp.getOnlyOnDevice());
     }
 
     /**
@@ -468,7 +714,7 @@ public class OCFileListFragment extends ExtendedListFragment
      *
      * @param directory File to be listed
      */
-    public void listDirectory(OCFile directory/*, boolean onlyOnDevice*/) {
+    public void listDirectory(OCFile directory, boolean onlyOnDevice) {
         FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
         if (storageManager != null) {
 
@@ -489,8 +735,7 @@ public class OCFileListFragment extends ExtendedListFragment
                 directory = storageManager.getFileById(directory.getParentId());
             }
 
-            // TODO Enable when "On Device" is recovered ?
-            mAdapter.swapDirectory(directory, storageManager/*, onlyOnDevice*/);
+            mAdapter.swapDirectory(directory, storageManager, onlyOnDevice);
             if (mFile == null || !mFile.equals(directory)) {
                 mCurrentListView.setSelection(0);
             }
@@ -514,7 +759,7 @@ public class OCFileListFragment extends ExtendedListFragment
                     if (!file.isHidden()) {
                         filesCount++;
 
-                        if (file.isImage()) {
+                        if (file.isImage() || file.isVideo()) {
                             imagesCount++;
                         }
                     }
@@ -527,11 +772,12 @@ public class OCFileListFragment extends ExtendedListFragment
             OwnCloudVersion version = AccountUtils.getServerVersion(
                     ((FileActivity)mContainerActivity).getAccount());
             if (version != null && version.supportsRemoteThumbnails() &&
-                imagesCount > 0 && imagesCount == filesCount) {
+                    DisplayUtils.isGridView(mFile, mContainerActivity.getStorageManager())) {
                 switchToGridView();
                 registerLongClickListener();
             } else {
                 switchToListView();
+//                switchToGridView();
             }
         }
     }
index a029653..46382a6 100644 (file)
@@ -26,12 +26,17 @@ import android.app.Activity;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
+import android.support.v7.widget.AppCompatButton;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.CompoundButton;
 import android.widget.ImageView;
+import android.widget.ListAdapter;
 import android.widget.ListView;
+import android.widget.ScrollView;
+import android.widget.Switch;
 import android.widget.TextView;
 import android.widget.Toast;
 
@@ -41,16 +46,22 @@ import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.shares.OCShare;
+import com.owncloud.android.lib.resources.shares.ShareType;
+import com.owncloud.android.lib.resources.status.OCCapability;
 import com.owncloud.android.ui.activity.FileActivity;
-import com.owncloud.android.ui.activity.ShareActivity;
 import com.owncloud.android.ui.adapter.ShareUserListAdapter;
+import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.MimetypeIconUtil;
 
+import java.text.SimpleDateFormat;
+
 import java.util.ArrayList;
+import java.util.Date;
 
 /**
- * Fragment for Sharing a file with sharees (users or groups)
+ * Fragment for Sharing a file with sharees (users or groups) or creating
+ * a public link.
  *
  * A simple {@link Fragment} subclass.
  *
@@ -66,19 +77,48 @@ public class ShareFileFragment extends Fragment
 
     private static final String TAG = ShareFileFragment.class.getSimpleName();
 
-    // the fragment initialization parameters
+    /** The fragment initialization parameters */
     private static final String ARG_FILE = "FILE";
     private static final String ARG_ACCOUNT = "ACCOUNT";
 
-    // Parameters
+//    /** Tag for dialog */
+//    private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG";
+
+    /** File to share, received as a parameter in construction time */
     private OCFile mFile;
+
+    /** OC account holding the file to share, received as a parameter in construction time */
     private Account mAccount;
 
-    // other members
-    private ArrayList<OCShare> mShares;
-    private ShareUserListAdapter mUserGroupsAdapter = null;
+    /** Reference to parent listener */
     private OnShareFragmentInteractionListener mListener;
 
+    /** List of private shares bound to the file */
+    private ArrayList<OCShare> mPrivateShares;
+
+    /** Capabilities of the server */
+    private OCCapability mCapabilities;
+
+    /** Adapter to show private shares */
+    private ShareUserListAdapter mUserGroupsAdapter = null;
+
+    /** Public share bound to the file */
+    private OCShare mPublicShare;
+
+    /** Listener for changes on switch to share / unshare publicly */
+    private CompoundButton.OnCheckedChangeListener mOnShareViaLinkSwitchCheckedChangeListener;
+
+    /**
+     * Listener for user actions to set, update or clear password on public link
+     */
+    private OnPasswordInteractionListener mOnPasswordInteractionListener = null;
+
+    /**
+     * Listener for user actions to set, update or clear expiration date on public link
+     */
+    private OnExpirationDateInteractionListener mOnExpirationDateInteractionListener = null;
+
+
     /**
      * Public factory method to create new ShareFileFragment instances.
      *
@@ -105,18 +145,22 @@ public class ShareFileFragment extends Fragment
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        Log_OC.d(TAG, "onCreate");
         if (getArguments() != null) {
             mFile = getArguments().getParcelable(ARG_FILE);
             mAccount = getArguments().getParcelable(ARG_ACCOUNT);
         }
     }
 
+
     /**
      * {@inheritDoc}
      */
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
+        Log_OC.d(TAG, "onCreateView");
+
         // Inflate the layout for this fragment
         View view = inflater.inflate(R.layout.share_file_layout, container, false);
 
@@ -149,7 +193,7 @@ public class ShareFileFragment extends Fragment
         addUserGroupButton.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
-                 boolean shareWithUsersEnable = AccountUtils.hasSearchUsersSupport(mAccount);
+                boolean shareWithUsersEnable = AccountUtils.hasSearchUsersSupport(mAccount);
                 if (shareWithUsersEnable) {
                     // Show Search Fragment
                     mListener.showSearchUsersAndGroups();
@@ -160,15 +204,253 @@ public class ShareFileFragment extends Fragment
             }
         });
 
+        // Switch to create public share
+        mOnShareViaLinkSwitchCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
+            }
+        };
+
+        // Set listener for user actions on switch for sharing/unsharing via link
+        initShareViaLinkListener(view);
+
+        // Set listener for user actions on expiration date
+        initExpirationListener(view);
+
+        // Set listener for user actions on password
+        initPasswordListener(view);
+
         return view;
     }
 
+
+    /**
+     * Binds listener for user actions to create or delete a public share
+     * to the views receiving the user events.
+     *
+     * @param shareView     Root view in the fragment.
+     */
+    private void initShareViaLinkListener(View shareView) {
+        mOnShareViaLinkSwitchCheckedChangeListener = new OnShareViaLinkListener();
+        Switch shareViaLinkSwitch = (Switch) shareView.findViewById(R.id.shareViaLinkSectionSwitch);
+        shareViaLinkSwitch.setOnCheckedChangeListener(mOnShareViaLinkSwitchCheckedChangeListener);
+    }
+
+    /**
+     * Listener for user actions that create or delete a public share.
+     */
+    private class OnShareViaLinkListener
+            implements CompoundButton.OnCheckedChangeListener {
+
+        /**
+         * Called by R.id.shareViaLinkSectionSwitch to create or delete a public link.
+         *
+         * @param switchView    {@link Switch} toggled by the user, R.id.shareViaLinkSectionSwitch
+         * @param isChecked     New switch state.
+         */
+        @Override
+        public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
+            if (!isResumed()) {
+                // very important, setCheched(...) is called automatically during
+                // Fragment recreation on device rotations
+                return;
+            }
+            if (isChecked) {
+                if (mCapabilities != null &&
+                        mCapabilities.getFilesSharingPublicPasswordEnforced().isTrue()) {
+                    // password enforced by server, request to the user before trying to create
+                    ((FileActivity) getActivity()).getFileOperationsHelper().
+                            requestPasswordForShareViaLink(mFile, true);
+
+                } else {
+                    // create without password if not enforced by server or we don't know if enforced;
+                    ((FileActivity) getActivity()).getFileOperationsHelper().
+                            shareFileViaLink(mFile, null);
+
+                    // FileActivtiy#onCreateShareViaLinkOperationFinish still handles the guess of enforcement
+                    // for server in versions previous to OwnCloudVersion#MINIMUM_VERSION_CAPABILITIES_API
+                }
+
+            } else {
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        unshareFileViaLink(mFile);
+            }
+
+            // undo the toggle to grant the view will be correct if any intermediate dialog is cancelled or
+            // the create/delete operation fails
+            switchView.setOnCheckedChangeListener(null);
+            switchView.toggle();
+            switchView.setOnCheckedChangeListener(mOnShareViaLinkSwitchCheckedChangeListener);
+        }
+    }
+
+
+    /**
+     * Binds listener for user actions that start any update on a expiration date
+     * for the public link to the views receiving the user events.
+     *
+     * @param shareView     Root view in the fragment.
+     */
+    private void initExpirationListener(View shareView) {
+        mOnExpirationDateInteractionListener = new OnExpirationDateInteractionListener();
+
+        ((Switch) shareView.findViewById(R.id.shareViaLinkExpirationSwitch)).
+                setOnCheckedChangeListener(mOnExpirationDateInteractionListener);
+
+        shareView.findViewById(R.id.shareViaLinkExpirationLabel).
+                setOnClickListener(mOnExpirationDateInteractionListener);
+
+        shareView.findViewById(R.id.shareViaLinkExpirationValue).
+                setOnClickListener(mOnExpirationDateInteractionListener);
+    }
+
+    /**
+     * Listener for user actions that start any update on the expiration date for the public link.
+     */
+    private class OnExpirationDateInteractionListener
+            implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
+
+        /**
+         * Called by R.id.shareViaLinkExpirationSwitch to set or clear the expiration date.
+         *
+         * @param switchView    {@link Switch} toggled by the user, R.id.shareViaLinkExpirationSwitch
+         * @param isChecked     New switch state.
+         */
+        @Override
+        public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
+            if (!isResumed()) {
+                // very important, setCheched(...) is called automatically during
+                // Fragment recreation on device rotations
+                return;
+            }
+            if (isChecked) {
+                ExpirationDatePickerDialogFragment dialog =
+                        ExpirationDatePickerDialogFragment.newInstance(mFile, -1);
+                dialog.show(
+                        getActivity().getSupportFragmentManager(),
+                        ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG
+                );
+
+            } else {
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        setExpirationDateToShareViaLink(mFile, -1);
+            }
+
+            // undo the toggle to grant the view will be correct if the dialog is cancelled
+            switchView.setOnCheckedChangeListener(null);
+            switchView.toggle();
+            switchView.setOnCheckedChangeListener(mOnExpirationDateInteractionListener);
+        }
+
+        /**
+         * Called by R.id.shareViaLinkExpirationLabel or R.id.shareViaLinkExpirationValue
+         * to change the current expiration date.
+         *
+         * @param expirationView      Label or value view touched by the user.
+         */
+        @Override
+        public void onClick(View expirationView) {
+            if (mPublicShare != null && mPublicShare.getExpirationDate() > 0) {
+                long chosenDateInMillis = -1;
+                if (mPublicShare != null) {
+                    chosenDateInMillis = mPublicShare.getExpirationDate();
+                }
+                ExpirationDatePickerDialogFragment dialog =
+                        ExpirationDatePickerDialogFragment.newInstance(
+                                mFile,
+                                chosenDateInMillis
+                        );
+                dialog.show(
+                        getActivity().getSupportFragmentManager(),
+                        ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG
+                );
+            }
+        }
+    }
+
+
+    /**
+     * Binds listener for user actions that start any update on a password for the public link
+     * to the views receiving the user events.
+     *
+     * @param shareView     Root view in the fragment.
+     */
+    private void initPasswordListener(View shareView) {
+        mOnPasswordInteractionListener = new OnPasswordInteractionListener();
+
+        ((Switch) shareView.findViewById(R.id.shareViaLinkPasswordSwitch)).
+                setOnCheckedChangeListener(mOnPasswordInteractionListener);
+
+        shareView.findViewById(R.id.shareViaLinkPasswordLabel).
+                setOnClickListener(mOnPasswordInteractionListener);
+
+        shareView.findViewById(R.id.shareViaLinkPasswordValue).
+                setOnClickListener(mOnPasswordInteractionListener);
+    }
+
+
+    /**
+     * Listener for user actions that start any update on a password for the public link.
+     */
+    private class OnPasswordInteractionListener
+            implements CompoundButton.OnCheckedChangeListener, View.OnClickListener {
+
+        /**
+         * Called by R.id.shareViaLinkPasswordSwitch to set or clear the password.
+         *
+         * @param switchView    {@link Switch} toggled by the user, R.id.shareViaLinkPasswordSwitch
+         * @param isChecked     New switch state.
+         */
+        @Override
+        public void onCheckedChanged(CompoundButton switchView, boolean isChecked) {
+            if (!isResumed()) {
+                // very important, setCheched(...) is called automatically during
+                // Fragment recreation on device rotations
+                return;
+            }
+            if (isChecked) {
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        requestPasswordForShareViaLink(mFile, false);
+            } else {
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        setPasswordToShareViaLink(mFile, "");   // "" clears
+            }
+
+            // undo the toggle to grant the view will be correct if the dialog is cancelled
+            switchView.setOnCheckedChangeListener(null);
+            switchView.toggle();
+            switchView.setOnCheckedChangeListener(mOnPasswordInteractionListener);
+        }
+
+        /**
+         * Called by R.id.shareViaLinkPasswordLabel or R.id.shareViaLinkPasswordValue
+         * to change the current password.
+         *
+         * @param passwordView      Label or value view touched by the user.
+         */
+        @Override
+        public void onClick(View passwordView) {
+            if (mPublicShare != null && mPublicShare.isPasswordProtected()) {
+                ((FileActivity) getActivity()).getFileOperationsHelper().
+                        requestPasswordForShareViaLink(mFile, false);
+            }
+        }
+    }
+
+
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
+        Log_OC.d(TAG, "onActivityCreated");
+
+        // Load known capabilities of the server from DB
+        refreshCapabilitiesFromDB();
 
-        // Load data into the list
+        // Load data into the list of private shares
         refreshUsersOrGroupsListFromDB();
+
+        // Load data of public share, if exists
+        refreshPublicShareFromDB();
     }
 
     @Override
@@ -188,8 +470,23 @@ public class ShareFileFragment extends Fragment
         mListener = null;
     }
 
+
+    /**
+     * Get known server capabilities from DB
+     *
+     * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
+     * instance ready to use. If not ready, does nothing.
+     */
+    public void refreshCapabilitiesFromDB() {
+        if (((FileActivity)mListener).getStorageManager() != null) {
+            mCapabilities = ((FileActivity)mListener).getStorageManager().
+                    getCapability(mAccount.name);
+        }
+    }
+
+
     /**
-     * Get users and groups from the DB to fill in the "share with" list
+     * Get users and groups from the DB to fill in the "share with" list.
      *
      * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
      * instance ready to use. If not ready, does nothing.
@@ -197,7 +494,7 @@ public class ShareFileFragment extends Fragment
     public void refreshUsersOrGroupsListFromDB (){
         if (((FileActivity) mListener).getStorageManager() != null) {
             // Get Users and Groups
-            mShares = ((FileActivity) mListener).getStorageManager().getSharesWithForAFile(
+            mPrivateShares = ((FileActivity) mListener).getStorageManager().getSharesWithForAFile(
                     mFile.getRemotePath(),
                     mAccount.name
             );
@@ -213,7 +510,7 @@ public class ShareFileFragment extends Fragment
         mUserGroupsAdapter = new ShareUserListAdapter(
                 getActivity(),
                 R.layout.share_user_item,
-                mShares,
+                mPrivateShares,
                 this
         );
 
@@ -221,15 +518,19 @@ public class ShareFileFragment extends Fragment
         TextView noShares = (TextView) getView().findViewById(R.id.shareNoUsers);
         ListView usersList = (ListView) getView().findViewById(R.id.shareUsersList);
 
-        if (mShares.size() > 0) {
+        if (mPrivateShares.size() > 0) {
             noShares.setVisibility(View.GONE);
             usersList.setVisibility(View.VISIBLE);
             usersList.setAdapter(mUserGroupsAdapter);
-
+            setListViewHeightBasedOnChildren(usersList);
         } else {
             noShares.setVisibility(View.VISIBLE);
             usersList.setVisibility(View.GONE);
         }
+
+        // Set Scroll to initial position
+        ScrollView scrollView = (ScrollView) getView().findViewById(R.id.shareScroll);
+        scrollView.scrollTo(0, 0);
     }
 
     @Override
@@ -240,6 +541,201 @@ public class ShareFileFragment extends Fragment
     }
 
 
+
+    /**
+     * Get public link from the DB to fill in the "Share link" section in the UI.
+     *
+     * Takes into account server capabilities before reading database.
+     *
+     * Depends on the parent Activity provides a {@link com.owncloud.android.datamodel.FileDataStorageManager}
+     * instance ready to use. If not ready, does nothing.
+     */
+    public void refreshPublicShareFromDB() {
+        if (isPublicShareDisabled()) {
+            hidePublicShare();
+
+        } else if (((FileActivity) mListener).getStorageManager() != null) {
+            // Get public share
+            mPublicShare = ((FileActivity) mListener).getStorageManager().getFirstShareByPathAndType(
+                    mFile.getRemotePath(),
+                    ShareType.PUBLIC_LINK,
+                    ""
+            );
+
+            // Update public share section
+            updatePublicShareSection();
+        }
+    }
+
+    /**
+     * @return  'True' when public share is disabled in the server
+     */
+    private boolean isPublicShareDisabled() {
+        return (mCapabilities != null &&
+                mCapabilities.getFilesSharingPublicEnabled().isFalse()
+        );
+    }
+
+    /**
+     * Updates in the UI the section about public share with the information in the current
+     * public share bound to mFile, if any
+     */
+    private void updatePublicShareSection() {
+        if (mPublicShare != null && ShareType.PUBLIC_LINK.equals(mPublicShare.getShareType())) {
+            /// public share bound -> expand section
+            Switch shareViaLinkSwitch = getShareViaLinkSwitch();
+            if (!shareViaLinkSwitch.isChecked()) {
+                // set null listener before setChecked() to prevent infinite loop of calls
+                shareViaLinkSwitch.setOnCheckedChangeListener(null);
+                shareViaLinkSwitch.setChecked(true);
+                shareViaLinkSwitch.setOnCheckedChangeListener(
+                        mOnShareViaLinkSwitchCheckedChangeListener
+                );
+            }
+            getExpirationDateSection().setVisibility(View.VISIBLE);
+            getPasswordSection().setVisibility(View.VISIBLE);
+            // GetLink button
+            AppCompatButton getLinkButton = getGetLinkButton();
+            getLinkButton.setVisibility(View.VISIBLE);
+            getLinkButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    //GetLink from the server and show ShareLinkToDialog
+                    ((FileActivity) getActivity()).getFileOperationsHelper().
+                            getFileWithLink(mFile);
+
+                }
+            });
+
+            /// update state of expiration date switch and message depending on expiration date
+            Switch expirationDateSwitch = getExpirationDateSwitch();
+            // set null listener before setChecked() to prevent infinite loop of calls
+            expirationDateSwitch.setOnCheckedChangeListener(null);
+            long expirationDate = mPublicShare.getExpirationDate();
+            if (expirationDate > 0) {
+                if (!expirationDateSwitch.isChecked()) {
+                    expirationDateSwitch.toggle();
+                }
+                String formattedDate =
+                        SimpleDateFormat.getDateInstance().format(
+                                new Date(expirationDate)
+                        );
+                getExpirationDateValue().setText(formattedDate);
+            } else {
+                if (expirationDateSwitch.isChecked()) {
+                    expirationDateSwitch.toggle();
+                }
+                getExpirationDateValue().setText(R.string.empty);
+            }
+            // recover listener
+            expirationDateSwitch.setOnCheckedChangeListener(
+                    mOnExpirationDateInteractionListener
+            );
+
+            /// update state of password switch and message depending on password protection
+            Switch passwordSwitch = getPasswordSwitch();
+            // set null listener before setChecked() to prevent infinite loop of calls
+            passwordSwitch.setOnCheckedChangeListener(null);
+            if (mPublicShare.isPasswordProtected()) {
+                if (!passwordSwitch.isChecked()) {
+                    passwordSwitch.toggle();
+                }
+                getPasswordValue().setVisibility(View.VISIBLE);
+            } else {
+                if (passwordSwitch.isChecked()) {
+                    passwordSwitch.toggle();
+                }
+                getPasswordValue().setVisibility(View.INVISIBLE);
+            }
+            // recover listener
+            passwordSwitch.setOnCheckedChangeListener(
+                    mOnPasswordInteractionListener
+            );
+
+
+        } else {
+            /// no public share -> collapse section
+            Switch shareViaLinkSwitch = getShareViaLinkSwitch();
+            if (shareViaLinkSwitch.isChecked()) {
+                shareViaLinkSwitch.setOnCheckedChangeListener(null);
+                getShareViaLinkSwitch().setChecked(false);
+                shareViaLinkSwitch.setOnCheckedChangeListener(
+                        mOnShareViaLinkSwitchCheckedChangeListener
+                );
+            }
+            getExpirationDateSection().setVisibility(View.GONE);
+            getPasswordSection().setVisibility(View.GONE);
+            getGetLinkButton().setVisibility(View.GONE);
+        }
+    }
+
+
+    /// BEWARE: next methods will failed with NullPointerException if called before onCreateView() finishes
+
+    private Switch getShareViaLinkSwitch() {
+        return (Switch) getView().findViewById(R.id.shareViaLinkSectionSwitch);
+    }
+
+    private View getExpirationDateSection() {
+        return getView().findViewById(R.id.shareViaLinkExpirationSection);
+    }
+
+    private Switch getExpirationDateSwitch() {
+        return (Switch) getView().findViewById(R.id.shareViaLinkExpirationSwitch);
+    }
+
+    private TextView getExpirationDateValue() {
+        return (TextView) getView().findViewById(R.id.shareViaLinkExpirationValue);
+    }
+
+    private View getPasswordSection() {
+        return getView().findViewById(R.id.shareViaLinkPasswordSection);
+    }
+
+    private Switch getPasswordSwitch() {
+        return (Switch) getView().findViewById(R.id.shareViaLinkPasswordSwitch);
+    }
+
+    private TextView getPasswordValue() {
+        return (TextView) getView().findViewById(R.id.shareViaLinkPasswordValue);
+    }
+
+    private AppCompatButton getGetLinkButton() {
+        return (AppCompatButton) getView().findViewById(R.id.shareViaLinkGetLinkButton);
+    }
+
+    /**
+     * Hides all the UI elements related to public share
+     */
+    private void hidePublicShare() {
+        getShareViaLinkSwitch().setVisibility(View.GONE);
+        getExpirationDateSection().setVisibility(View.GONE);
+        getPasswordSection().setVisibility(View.GONE);
+        getGetLinkButton().setVisibility(View.GONE);
+    }
+
+    public static void setListViewHeightBasedOnChildren(ListView listView) {
+        ListAdapter listAdapter = listView.getAdapter();
+        if (listAdapter == null) {
+            return;
+        }
+        int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.AT_MOST);
+        int totalHeight = 0;
+        View view = null;
+        for (int i = 0; i < listAdapter.getCount(); i++) {
+            view = listAdapter.getView(i, view, listView);
+            if (i == 0) {
+                view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, ViewGroup.LayoutParams.WRAP_CONTENT));
+            }
+            view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
+            totalHeight += view.getMeasuredHeight();
+        }
+        ViewGroup.LayoutParams params = listView.getLayoutParams();
+        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
+        listView.setLayoutParams(params);
+        listView.requestLayout();
+    }
+
     /**
      * This interface must be implemented by activities that contain this
      * fragment to allow an interaction in this fragment to be communicated
index 69182d6..5bb24e7 100644 (file)
@@ -4,12 +4,16 @@ import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Movie;
 import android.os.Build;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.ImageView;
 
-import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.datamodel.OCFile;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
 
 public class ImageViewCustom extends ImageView {
 
@@ -23,7 +27,12 @@ public class ImageViewCustom extends ImageView {
     private int mBitmapHeight;
     private int mBitmapWidth;
 
-    
+    private Movie mGifMovie;
+    private int mMovieWidth, mMovieHeight;
+    private long mMovieDuration;
+    private long mMovieRunDuration;
+    private long mLastTick;
+
     public ImageViewCustom(Context context) {
         super(context);
     }
@@ -39,18 +48,58 @@ public class ImageViewCustom extends ImageView {
     @SuppressLint("NewApi")
        @Override
     protected void onDraw(Canvas canvas) {
-
         if(IS_ICS_OR_HIGHER && checkIfMaximumBitmapExceed(canvas) || IS_VERSION_BUGGY_ON_RECYCLES ) {
             // Software type is set with two targets:
             // 1. prevent that bitmaps larger than maximum textures allowed are shown as black views in devices
             //  with LAYER_TYPE_HARDWARE enabled by default;
-            // 2. grant that bitmaps are correctly dellocated from memory in versions suffering the bug fixed in
+            // 2. grant that bitmaps are correctly de-allocated from memory in versions suffering the bug fixed in
             //  https://android.googlesource.com/platform/frameworks/base/+/034de6b1ec561797a2422314e6ef03e3cd3e08e0;
             //
             setLayerType(View.LAYER_TYPE_SOFTWARE, null);
         }
 
-        super.onDraw(canvas);
+        if(mGifMovie == null){
+            super.onDraw(canvas);
+        } else {
+            long nowTick = android.os.SystemClock.uptimeMillis();
+            if (mLastTick == 0) {
+                mMovieRunDuration = 0;
+            } else {
+                mMovieRunDuration += nowTick - mLastTick;
+                if(mMovieRunDuration > mMovieDuration){
+                        mMovieRunDuration = 0;
+                }
+            }
+
+            mGifMovie.setTime((int) mMovieRunDuration);
+
+            float scale;
+            if(mGifMovie.height() > getHeight() || mGifMovie.width() > getWidth()) {
+                scale = (1f / Math.min(canvas.getHeight() / mGifMovie.height(),
+                        canvas.getWidth() / mGifMovie.width())) + 0.25f;
+            } else {
+                scale = Math.min(canvas.getHeight() / mGifMovie.height(),
+                                 canvas.getWidth() / mGifMovie.width());
+            }
+
+            canvas.scale(scale, scale);
+            canvas.translate(((float) getWidth() / scale - (float) mGifMovie.width()) / 2f,
+                    ((float) getHeight() / scale - (float) mGifMovie.height()) /2f);
+
+            mGifMovie.draw(canvas, 0, 0);
+
+            mLastTick = nowTick;
+            invalidate();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (mGifMovie == null){
+            setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
+        } else {
+            setMeasuredDimension(mMovieWidth, mMovieHeight);
+        }
     }
 
     /**
@@ -60,13 +109,9 @@ public class ImageViewCustom extends ImageView {
      */
     @SuppressLint("NewApi")
        private boolean checkIfMaximumBitmapExceed(Canvas canvas) {
-        Log_OC.v(TAG, "Canvas maximum: " + canvas.getMaximumBitmapWidth() + " - " + canvas.getMaximumBitmapHeight());
-        if (mBitmapWidth > canvas.getMaximumBitmapWidth()
-                || mBitmapHeight > canvas.getMaximumBitmapHeight()) {
-            return true;
-        }
-        
-        return false;
+        return mBitmapWidth > canvas.getMaximumBitmapWidth()
+                || mBitmapHeight > canvas.getMaximumBitmapHeight();
+
     }
     
     @Override
@@ -74,10 +119,25 @@ public class ImageViewCustom extends ImageView {
      * Keeps the size of the bitmap cached in member variables for faster access in {@link #onDraw(Canvas)} ,
      * but without keeping another reference to the {@link Bitmap}
      */
-    public void setImageBitmap (Bitmap bm) {
+    public void setImageBitmap(Bitmap bm) {
         mBitmapWidth = bm.getWidth();
         mBitmapHeight = bm.getHeight();
         super.setImageBitmap(bm);
     }
 
+    public void setGifImage(OCFile file){
+      try {
+          InputStream gifInputStream = new FileInputStream(file.getStoragePath());
+          setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+          setFocusable(true);
+
+          mGifMovie = Movie.decodeStream(gifInputStream);
+          mMovieWidth = mGifMovie.width();
+          mMovieHeight = mGifMovie.height();
+          mMovieDuration = mGifMovie.duration();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
 }
index 20b8de1..6a260dd 100644 (file)
@@ -40,6 +40,7 @@ import android.view.View;
 import android.view.Window;
 
 import com.ortiz.touch.ExtendedViewPager;
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -51,16 +52,11 @@ import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
 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.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.common.utils.Log_OC;
-import com.owncloud.android.operations.CreateShareViaLinkOperation;
-import com.owncloud.android.operations.CreateShareWithShareeOperation;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
-import com.owncloud.android.operations.UnshareOperation;
 import com.owncloud.android.ui.activity.FileActivity;
 import com.owncloud.android.ui.activity.FileDisplayActivity;
-import com.owncloud.android.ui.activity.ShareActivity;
 import com.owncloud.android.ui.fragment.FileFragment;
 
 
@@ -156,9 +152,8 @@ public class PreviewImageActivity extends FileActivity implements
             parentFolder = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
         }
 
-        // TODO Enable when "On Device" is recovered ?
         mPreviewImagePagerAdapter = new PreviewImagePagerAdapter(getSupportFragmentManager(),
-                parentFolder, getAccount(), getStorageManager()/*, MainApp.getOnlyOnDevice()*/);
+                parentFolder, getAccount(), getStorageManager(), MainApp.getOnlyOnDevice());
 
         mViewPager = (ExtendedViewPager) findViewById(R.id.fragmentPager);
         int position = mHasSavedPosition ? mSavedPosition :
@@ -230,14 +225,7 @@ public class PreviewImageActivity extends FileActivity implements
     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
         super.onRemoteOperationFinish(operation, result);
         
-        if (operation instanceof CreateShareViaLinkOperation ||
-                operation instanceof CreateShareWithShareeOperation) {
-            onCreateShareOperationFinish(result);
-
-        } else if (operation instanceof UnshareOperation) {
-            onUnshareLinkOperationFinish((UnshareOperation) operation, result);
-            
-        } else if (operation instanceof RemoveFileOperation) {
+        if (operation instanceof RemoveFileOperation) {
             finish();
         } else if (operation instanceof SynchronizeFileOperation) {
             onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result);
@@ -245,31 +233,6 @@ public class PreviewImageActivity extends FileActivity implements
         }
     }
     
-    
-    private void onUnshareLinkOperationFinish(UnshareOperation operation,
-                                              RemoteOperationResult result) {
-        if (result.isSuccess()) {
-            OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath());
-            if (file != null) {
-                setFile(file);
-            }
-            invalidateOptionsMenu();
-        } else if  (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
-            backToDisplayActivity();
-        }
-            
-    }
-    
-    private void onCreateShareOperationFinish(RemoteOperationResult result) {
-        if (result.isSuccess()) {
-            OCFile file = getStorageManager().getFileByPath(getFile().getRemotePath());
-            if (file != null) {
-                setFile(file);
-            }
-            invalidateOptionsMenu();
-        }
-    }
-
     private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation,
                                                   RemoteOperationResult result) {
         if (result.isSuccess()) {
@@ -429,12 +392,7 @@ public class PreviewImageActivity extends FileActivity implements
             OCFile currentFile = mPreviewImagePagerAdapter.getFileAt(position); 
             getSupportActionBar().setTitle(currentFile.getFileName());
             mDrawerToggle.setDrawerIndicatorEnabled(false);
-            if (!currentFile.isDown()) {
-                if (!mPreviewImagePagerAdapter.pendingErrorAt(position)) {
-                    requestForDownload(currentFile);
-                }
-            }
-
+            
             // Call to reset image zoom to initial state
             ((PreviewImagePagerAdapter) mViewPager.getAdapter()).resetZoom();
         }
index a114fab..1ef0377 100644 (file)
@@ -41,8 +41,10 @@ import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.FileMenuFilter;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
@@ -69,11 +71,14 @@ public class PreviewImageFragment extends FileFragment {
 
     private static final String ARG_FILE = "FILE";
     private static final String ARG_IGNORE_FIRST = "IGNORE_FIRST";
+    private static final String ARG_SHOW_RESIZED_IMAGE = "SHOW_RESIZED_IMAGE";
 
     private TouchImageViewCustom mImageView;
     private TextView mMessageView;
     private ProgressBar mProgressWheel;
 
+    private Boolean mShowResizedImage = false;
+
     public Bitmap mBitmap = null;
 
     private static final String TAG = PreviewImageFragment.class.getSimpleName();
@@ -97,11 +102,14 @@ public class PreviewImageFragment extends FileFragment {
      *                                  {@link FragmentStatePagerAdapter}
      *                                  ; TODO better solution
      */
-    public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState){
+    public static PreviewImageFragment newInstance(OCFile imageFile, boolean ignoreFirstSavedState,
+            boolean showResizedImage){
         PreviewImageFragment frag = new PreviewImageFragment();
+        frag.mShowResizedImage = showResizedImage;
         Bundle args = new Bundle();
         args.putParcelable(ARG_FILE, imageFile);
         args.putBoolean(ARG_IGNORE_FIRST, ignoreFirstSavedState);
+        args.putBoolean(ARG_SHOW_RESIZED_IMAGE, showResizedImage);
         frag.setArguments(args);
         return frag;
     }
@@ -134,6 +142,7 @@ public class PreviewImageFragment extends FileFragment {
             // not right now
 
         mIgnoreFirstSavedState = args.getBoolean(ARG_IGNORE_FIRST);
+        mShowResizedImage = args.getBoolean(ARG_SHOW_RESIZED_IMAGE);
         setHasOptionsMenu(true);
     }
 
@@ -179,9 +188,6 @@ public class PreviewImageFragment extends FileFragment {
         if (getFile() == null) {
             throw new IllegalStateException("Instanced with a NULL OCFile");
         }
-        if (!getFile().isDown()) {
-            throw new IllegalStateException("There is no local file to preview");
-        }
     }
 
 
@@ -199,10 +205,56 @@ public class PreviewImageFragment extends FileFragment {
     public void onStart() {
         super.onStart();
         if (getFile() != null) {
-            mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
-            //mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()});
-//            mLoadBitmapTask.execute(getFile().getStoragePath());
-            mLoadBitmapTask.execute(getFile());
+            mImageView.setTag(getFile().getFileId());
+
+            if (mShowResizedImage){
+                Bitmap resizedImage = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                        String.valueOf("r" + getFile().getRemoteId()));
+
+                if (resizedImage != null && !getFile().needsUpdateThumbnail()){
+                    mProgressWheel.setVisibility(View.GONE);
+                    mImageView.setImageBitmap(resizedImage);
+                    mImageView.setVisibility(View.VISIBLE);
+                    mBitmap  = resizedImage;
+                } else {
+                    // show thumbnail while loading resized image
+                    Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                            String.valueOf("t" + getFile().getRemoteId()));
+
+                    if (thumbnail != null){
+                        mImageView.setImageBitmap(thumbnail);
+                        mProgressWheel.setVisibility(View.VISIBLE);
+                        mImageView.setVisibility(View.VISIBLE);
+                        mBitmap = thumbnail;
+                    } else {
+                        thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                    }
+
+                    // generate new resized image
+                    if (ThumbnailsCacheManager.cancelPotentialWork(getFile(), mImageView) &&
+                        mContainerActivity.getStorageManager() != null) {
+                        final ThumbnailsCacheManager.ThumbnailGenerationTask task =
+                                new ThumbnailsCacheManager.ThumbnailGenerationTask(
+                                        mImageView, mContainerActivity.getStorageManager(),
+                                        mContainerActivity.getStorageManager().getAccount(),
+                                        mProgressWheel);
+                        if (resizedImage == null) {
+                            resizedImage = thumbnail;
+                        }
+                        final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
+                                new ThumbnailsCacheManager.AsyncDrawable(
+                                        MainApp.getAppContext().getResources(),
+                                        resizedImage,
+                                        task
+                                );
+                        mImageView.setImageDrawable(asyncDrawable);
+                        task.execute(getFile(), false);
+                    }
+            }
+            } else {
+                mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
+                mLoadBitmapTask.execute(getFile());
+            }
         }
     }
 
@@ -224,6 +276,9 @@ public class PreviewImageFragment extends FileFragment {
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         super.onCreateOptionsMenu(menu, inflater);
         inflater.inflate(R.menu.file_actions_menu, menu);
+
+//        MenuItem item = menu.findItem(R.id.action_set_as_wallpaper);
+//        item.setVisible(getFile().isDown());
     }
 
     /**
@@ -286,17 +341,9 @@ public class PreviewImageFragment extends FileFragment {
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.action_share_file: {
-                mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
-                return true;
-            }
-            case R.id.action_share_with_users: {
                 mContainerActivity.getFileOperationsHelper().showShareFile(getFile());
                 return true;
             }
-            case R.id.action_unshare_file: {
-                mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
-                return true;
-            }
             case R.id.action_open_file_with: {
                 openFile();
                 return true;
@@ -311,9 +358,15 @@ public class PreviewImageFragment extends FileFragment {
                 return true;
             }
             case R.id.action_send_file: {
-                mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
-                return true;
+                if (getFile().isImage() && !getFile().isDown()){
+                    mContainerActivity.getFileOperationsHelper().sendCachedImage(getFile());
+                    return true;
+                } else {
+                    mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
+                    return true;
+                }
             }
+            case R.id.action_download_file:
             case R.id.action_sync_file: {
                 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
                 return true;
@@ -326,6 +379,10 @@ public class PreviewImageFragment extends FileFragment {
                 mContainerActivity.getFileOperationsHelper().toggleFavorite(getFile(), false);
                 return true;
             }
+            case R.id.action_set_as_wallpaper:{
+                mContainerActivity.getFileOperationsHelper().setPictureAs(getFile());
+                return true;
+            }
             default:
                 return false;
         }
@@ -512,7 +569,12 @@ public class PreviewImageFragment extends FileFragment {
                     imageView.setBackground(backrepeat);
                 }
 
-                imageView.setImageBitmap(bitmap);
+                if (result.ocFile.getMimetype().equalsIgnoreCase("image/gif")){
+                    imageView.setGifImage(result.ocFile);
+                } else {
+                    imageView.setImageBitmap(bitmap);
+                }
+
                 imageView.setVisibility(View.VISIBLE);
                 mBitmap  = bitmap;  // needs to be kept for recycling when not useful
             }
index dda7dda..5ca2e98 100644 (file)
@@ -27,6 +27,7 @@ import java.util.Set;
 import java.util.Vector;
 
 import android.accounts.Account;
+import android.graphics.Bitmap;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentStatePagerAdapter;
@@ -34,6 +35,8 @@ import android.view.ViewGroup;
 
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
+import com.owncloud.android.ui.adapter.FileListListAdapter;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.utils.FileStorageUtils;
 
@@ -61,8 +64,8 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
      * @param storageManager    Bridge to database.
      */
     public PreviewImagePagerAdapter(FragmentManager fragmentManager, OCFile parentFolder,
-                                    Account account, FileDataStorageManager storageManager /*,
-                                    boolean onlyOnDevice*/) {
+                                    Account account, FileDataStorageManager storageManager,
+                                    boolean onlyOnDevice) {
         super(fragmentManager);
         
         if (fragmentManager == null) {
@@ -77,10 +80,9 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
 
         mAccount = account;
         mStorageManager = storageManager;
-        // TODO Enable when "On Device" is recovered ?
-        mImageFiles = mStorageManager.getFolderImages(parentFolder/*, false*/);
+        mImageFiles = mStorageManager.getFolderImages(parentFolder, onlyOnDevice);
         
-        mImageFiles = FileStorageUtils.sortFolder(mImageFiles);
+        mImageFiles = FileStorageUtils.sortOcFolder(mImageFiles);
         
         mObsoleteFragments = new HashSet<Object>();
         mObsoletePositions = new HashSet<Integer>();
@@ -104,17 +106,15 @@ public class PreviewImagePagerAdapter extends FragmentStatePagerAdapter {
         Fragment fragment = null;
         if (file.isDown()) {
             fragment = PreviewImageFragment.newInstance(file,
-                    mObsoletePositions.contains(Integer.valueOf(i)));
+                    mObsoletePositions.contains(Integer.valueOf(i)), false);
             
         } else if (mDownloadErrors.contains(Integer.valueOf(i))) {
             fragment = FileDownloadFragment.newInstance(file, mAccount, true);
             ((FileDownloadFragment)fragment).setError(true);
             mDownloadErrors.remove(Integer.valueOf(i));
-            
         } else {
-            fragment = FileDownloadFragment.newInstance(
-                    file, mAccount, mObsoletePositions.contains(Integer.valueOf(i))
-            );
+            fragment = PreviewImageFragment.newInstance(file,
+                    mObsoletePositions.contains(Integer.valueOf(i)), true);
         }
         mObsoletePositions.remove(Integer.valueOf(i));
         return fragment;
index 8f813b8..b6ee12b 100644 (file)
 package com.owncloud.android.ui.preview;
 
 import android.accounts.Account;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
 import android.app.Activity;
+import android.content.ActivityNotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.media.MediaMetadataRetriever;
+import android.net.Uri;
+import android.os.AsyncTask;
 import android.support.v7.app.AlertDialog;
 import android.content.ComponentName;
 import android.content.Context;
@@ -50,9 +55,16 @@ import android.widget.ImageView;
 import android.widget.Toast;
 import android.widget.VideoView;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.FileMenuFilter;
+import com.owncloud.android.lib.common.OwnCloudAccount;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.media.MediaControlView;
 import com.owncloud.android.media.MediaService;
@@ -62,6 +74,9 @@ import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
 
 /**
  * This fragment shows a preview of a downloaded media file (audio or video).
@@ -85,6 +100,7 @@ public class PreviewMediaFragment extends FileFragment implements
     private ImageView mImagePreview;
     private VideoView mVideoPreview;
     private int mSavedPlaybackPosition;
+    private String mUri;
 
     private MediaServiceBinder mMediaServiceBinder = null;
     private MediaControlView mMediaController = null;
@@ -182,10 +198,6 @@ public class PreviewMediaFragment extends FileFragment implements
             if (mAccount == null) {
                 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
             }
-            if (!file.isDown()) {
-                throw new IllegalStateException("There is no local file to preview");
-            }
-
         }
         else {
             file = (OCFile) savedInstanceState.getParcelable(PreviewMediaFragment.EXTRA_FILE);
@@ -196,7 +208,7 @@ public class PreviewMediaFragment extends FileFragment implements
             mAutoplay = savedInstanceState.getBoolean(PreviewMediaFragment.EXTRA_PLAYING);
 
         }
-        if (file != null && file.isDown()) {
+        if (file != null) {
             if (file.isVideo()) {
                 mVideoPreview.setVisibility(View.VISIBLE);
                 mImagePreview.setVisibility(View.GONE);
@@ -269,7 +281,7 @@ public class PreviewMediaFragment extends FileFragment implements
         Log_OC.v(TAG, "onStart");
 
         OCFile file = getFile();
-        if (file != null && file.isDown()) {
+        if (file != null) {
             if (file.isAudio()) {
                 bindMediaService();
 
@@ -349,19 +361,9 @@ public class PreviewMediaFragment extends FileFragment implements
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.action_share_file: {
-                stopPreview(false);
-                mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
-                return true;
-            }
-            case R.id.action_share_with_users: {
                 seeShareFile();
                 return true;
             }
-            case R.id.action_unshare_file: {
-                stopPreview(false);
-                mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
-                return true;
-            }
             case R.id.action_open_file_with: {
                 openFile();
                 return true;
@@ -437,9 +439,67 @@ public class PreviewMediaFragment extends FileFragment implements
 
         // load the video file in the video player ; 
         // when done, VideoHelper#onPrepared() will be called
+        if (getFile().isDown()) {
+            mUri = getFile().getStoragePath();
+        } else {
+            Context context = MainApp.getAppContext();
+            Account account = mContainerActivity.getStorageManager().getAccount();
+
+            mUri = generateUrlWithCredentials(account, context, getFile());
+        }
+
         mVideoPreview.setVideoURI(getFile().getStorageUri());
     }
 
+    public static String generateUrlWithCredentials(Account account, Context context, OCFile file){
+        OwnCloudAccount ocAccount = null;
+        try {
+            ocAccount = new OwnCloudAccount(account, context);
+
+            final ClientGenerationTask task = new ClientGenerationTask();
+            task.execute(ocAccount);
+
+            OwnCloudClient mClient = task.get();
+            String url = AccountUtils.constructFullURLForAccount(context, account) + Uri.encode(file.getRemotePath(), "/");
+            OwnCloudCredentials credentials = mClient.getCredentials();
+
+            return url.replace("//", "//" + credentials.getUsername() + ":" + credentials.getAuthToken() + "@");
+
+        } catch (AccountUtils.AccountNotFoundException e) {
+            e.printStackTrace();
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    public static class ClientGenerationTask extends AsyncTask<Object, Void, OwnCloudClient> {
+        @Override
+        protected OwnCloudClient doInBackground(Object... params) {
+            Object account = params[0];
+            if (account instanceof OwnCloudAccount){
+                try {
+                    OwnCloudAccount ocAccount = (OwnCloudAccount) account;
+                    return OwnCloudClientManagerFactory.getDefaultSingleton().
+                            getClientFor(ocAccount, MainApp.getAppContext());
+                } catch (AccountUtils.AccountNotFoundException e) {
+                    e.printStackTrace();
+                } catch (OperationCanceledException e) {
+                    e.printStackTrace();
+                } catch (AuthenticatorException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            return null;
+        }
+    }
+
 
     private class VideoHelper implements OnCompletionListener, OnPreparedListener, OnErrorListener {
 
@@ -489,28 +549,11 @@ public class PreviewMediaFragment extends FileFragment implements
          */
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
-            Log_OC.e(TAG, "Error in video playback, what = " + what + ", extra = " + extra);
-            if (mVideoPreview.getWindowToken() != null) {
-                String message = MediaService.getMessageForMediaError(
-                        getActivity(), what, extra);
-                new AlertDialog.Builder(getActivity())
-                        .setMessage(message)
-                        .setPositiveButton(android.R.string.VideoView_error_button,
-                                new DialogInterface.OnClickListener() {
-                                    public void onClick(DialogInterface dialog, int whichButton) {
-                                        dialog.dismiss();
-                                        VideoHelper.this.onCompletion(null);
-                                    }
-                                })
-                        .setCancelable(false)
-                        .show();
-            }
+            MediaService.streamWithExternalApp(mUri, getActivity()).show();
             return true;
         }
-
     }
 
-
     @Override
     public void onPause() {
         Log_OC.v(TAG, "onPause");
index a07d3df..f071469 100644 (file)
@@ -290,6 +290,18 @@ public class PreviewTextFragment extends FileFragment {
             item.setVisible(false);
             item.setEnabled(false);
         }
+
+        item = menu.findItem(R.id.action_switch_view);
+        if (item != null){
+            item.setVisible(false);
+            item.setEnabled(false);
+        }
+
+        item = menu.findItem(R.id.action_sort);
+        if (item != null) {
+            item.setVisible(false);
+            item.setEnabled(false);
+        }
     }
 
     /**
@@ -299,17 +311,9 @@ public class PreviewTextFragment extends FileFragment {
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.action_share_file: {
-                mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
-                return true;
-            }
-            case R.id.action_share_with_users: {
                 mContainerActivity.getFileOperationsHelper().showShareFile(getFile());
                 return true;
             }
-            case R.id.action_unshare_file: {
-                mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
-                return true;
-            }
             case R.id.action_open_file_with: {
                 openFile();
                 return true;
index 8972f3c..c1b4125 100644 (file)
@@ -206,14 +206,9 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
                     mVideoPlayer.setVideoURI(file.getStorageUri());
 
                 } else {
-                    // not working yet
                     String url;
-                    try {
-                        url = AccountUtils.constructFullURLForAccount(this, getAccount()) + file.getRemotePath();
-                        mVideoPlayer.setVideoURI(Uri.parse(url));
-                    } catch (AccountNotFoundException e) {
-                        onError(null, MediaService.OC_MEDIA_ERROR, R.string.media_err_no_account);
-                    }
+                    url = PreviewMediaFragment.generateUrlWithCredentials(getAccount(), getApplicationContext(), getFile());
+                    mVideoPlayer.setVideoURI(Uri.parse(url));
                 }
 
                 // create and prepare control panel for the user
index 43e5708..e3c94f2 100644 (file)
 \r
 package com.owncloud.android.utils;\r
 \r
+import java.io.File;\r
+import java.net.IDN;\r
+import java.text.DateFormat;\r
+import java.util.Arrays;\r
+import java.util.Calendar;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+import java.util.Vector;\r
+\r
 import android.annotation.TargetApi;\r
 import android.app.Activity;\r
 import android.content.Context;\r
+import android.content.SharedPreferences;\r
 import android.graphics.Point;\r
 import android.graphics.PorterDuff;\r
 import android.os.Build;\r
@@ -35,6 +47,7 @@ import android.widget.SeekBar;
 \r
 import com.owncloud.android.MainApp;\r
 import com.owncloud.android.R;\r
+import com.owncloud.android.datamodel.FileDataStorageManager;\r
 import com.owncloud.android.datamodel.OCFile;\r
 \r
 import java.math.BigDecimal;\r
@@ -185,8 +198,13 @@ public class DisplayUtils {
         return fileExtension;\r
     }\r
 \r
+    public static CharSequence getRelativeTimestamp(Context context, OCFile file) {\r
+        return getRelativeDateTimeString(context, file.getModificationTimestamp(),\r
+                DateUtils.SECOND_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0);\r
+    }\r
+\r
     @SuppressWarnings("deprecation")\r
-    public static CharSequence getRelativeDateTimeString (\r
+    private static CharSequence getRelativeDateTimeString (\r
             Context c, long time, long minResolution, long transitionResolution, int flags\r
             ){\r
         \r
@@ -249,6 +267,67 @@ public class DisplayUtils {
     }\r
 \r
     /**\r
+     * Determines if user set folder to grid or list view. If folder is not set itself,\r
+     * it finds a parent that is set (at least root is set).\r
+     * @param file\r
+     * @param storageManager\r
+     * @return\r
+     */\r
+    public static boolean isGridView(OCFile file, FileDataStorageManager storageManager){\r
+        if (file != null) {\r
+            OCFile fileToTest = file;\r
+            OCFile parentDir = null;\r
+            String parentPath = null;\r
+\r
+            SharedPreferences setting = MainApp.getAppContext().getSharedPreferences(\r
+                    "viewMode", Context.MODE_PRIVATE);\r
+\r
+            if (setting.contains(fileToTest.getRemoteId())) {\r
+                return setting.getBoolean(fileToTest.getRemoteId(), false);\r
+            } else {\r
+                do {\r
+                    if (fileToTest.getParentId() != FileDataStorageManager.ROOT_PARENT_ID) {\r
+                        parentPath = new File(fileToTest.getRemotePath()).getParent();\r
+                        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :\r
+                                parentPath + OCFile.PATH_SEPARATOR;\r
+                        parentDir = storageManager.getFileByPath(parentPath);\r
+                    } else {\r
+                        parentDir = storageManager.getFileByPath(OCFile.ROOT_PATH);\r
+                    }\r
+\r
+                    while (parentDir == null) {\r
+                        parentPath = new File(parentPath).getParent();\r
+                        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath :\r
+                                parentPath + OCFile.PATH_SEPARATOR;\r
+                        parentDir = storageManager.getFileByPath(parentPath);\r
+                    }\r
+                    fileToTest = parentDir;\r
+                } while (endWhile(parentDir, setting));\r
+                return setting.getBoolean(fileToTest.getRemoteId(), false);\r
+            }\r
+        } else {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    private static boolean endWhile(OCFile parentDir, SharedPreferences setting) {\r
+        if (parentDir.getRemotePath().compareToIgnoreCase(OCFile.ROOT_PATH) == 0) {\r
+            return false;\r
+        } else {\r
+            return !setting.contains(parentDir.getRemoteId());\r
+        }\r
+    }\r
+\r
+    public static void setViewMode(OCFile file, boolean setGrid){\r
+        SharedPreferences setting = MainApp.getAppContext().getSharedPreferences(\r
+                "viewMode", Context.MODE_PRIVATE);\r
+\r
+        SharedPreferences.Editor editor = setting.edit();\r
+        editor.putBoolean(file.getRemoteId(), setGrid);\r
+        editor.commit();\r
+    }\r
+\r
+    /**\r
      * sets the coloring of the given progress bar to color_accent.\r
      *\r
      * @param progressBar the progress bar to be colored\r
index 37b2fba..be74386 100644 (file)
@@ -27,6 +27,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.lib.resources.shares.UpdateRemoteShareOperation;
 import com.owncloud.android.operations.CopyFileOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.CreateShareViaLinkOperation;
@@ -38,6 +39,7 @@ import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
 import com.owncloud.android.operations.SynchronizeFolderOperation;
 import com.owncloud.android.operations.UnshareOperation;
+import com.owncloud.android.operations.UpdateShareViaLinkOperation;
 import com.owncloud.android.operations.UploadFileOperation;
 
 import org.apache.commons.httpclient.ConnectTimeoutException;
@@ -189,7 +191,7 @@ public class ErrorMessageAdapter {
             if (result.getData() != null && result.getData().size() > 0) {
                 message = (String) result.getData().get(0);     // share API sends its own error messages
 
-            } else  if (result.getCode() == ResultCode.SHARE_NOT_FOUND)  {
+            } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
                 message = res.getString(R.string.unshare_link_file_no_exist);
 
             } else if (result.getCode() == ResultCode.SHARE_FORBIDDEN) {
@@ -201,6 +203,25 @@ public class ErrorMessageAdapter {
                 // Show a Message, operation finished without success
                 message = res.getString(R.string.unshare_link_file_error);
             }
+
+        } else if (operation instanceof UpdateShareViaLinkOperation) {
+
+            if (result.getData() != null && result.getData().size() > 0) {
+                message = (String) result.getData().get(0);     // share API sends its own error messages
+
+            } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
+                message = res.getString(R.string.update_link_file_no_exist);
+
+            } else if (result.getCode() == ResultCode.SHARE_FORBIDDEN) {
+                // Error --> No permissions
+                message = String.format(res.getString(R.string.forbidden_permissions),
+                        res.getString(R.string.update_link_forbidden_permissions));
+
+            } else {    // Generic error
+                // Show a Message, operation finished without success
+                message = res.getString(R.string.update_link_file_error);
+            }
+
         } else if (operation instanceof MoveFileOperation) {
 
             if (result.getCode() == ResultCode.FILE_NOT_FOUND) {
diff --git a/src/com/owncloud/android/utils/ExceptionHandler.java b/src/com/owncloud/android/utils/ExceptionHandler.java
new file mode 100644 (file)
index 0000000..b06ec70
--- /dev/null
@@ -0,0 +1,102 @@
+package com.owncloud.android.utils;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.ui.activity.ErrorReportActivity;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+// from https://stackoverflow.com/questions/23486627/catching-error-and-user-information#answer-23486834
+public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
+
+    Context context;
+    private final String LINE_SEPARATOR = "\n";
+
+    public ExceptionHandler() {
+        // TODO Auto-generated constructor stub
+        context = MainApp.getAppContext();
+    }
+
+    @Override
+    public void uncaughtException(Thread arg0, Throwable arg1) {
+        // TODO Auto-generated method stub
+
+        StringWriter stackTrace = new StringWriter();
+        arg1.printStackTrace(new PrintWriter(stackTrace));
+        final StringBuilder errorReport = new StringBuilder();
+        errorReport.append("************ CAUSE OF ERROR ************\n\n");
+        errorReport.append(stackTrace.toString());
+
+        errorReport.append("\n************ DEVICE INFORMATION ***********\n");
+        errorReport.append("Brand: ");
+        errorReport.append(Build.BRAND);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Device: ");
+        errorReport.append(Build.DEVICE);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Model: ");
+        errorReport.append(Build.MODEL);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Id: ");
+        errorReport.append(Build.ID);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Product: ");
+        errorReport.append(Build.PRODUCT);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("\n************ FIRMWARE ************\n");
+        errorReport.append("SDK: ");
+        errorReport.append(Build.VERSION.SDK);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Release: ");
+        errorReport.append(Build.VERSION.RELEASE);
+        errorReport.append(LINE_SEPARATOR);
+        errorReport.append("Incremental: ");
+        errorReport.append(Build.VERSION.INCREMENTAL);
+        errorReport.append(LINE_SEPARATOR);
+
+
+        //after this you can do whatever you want , like i start an activity and show error log there
+
+        if (isUIThread()) {
+            invokeLogActivity(errorReport);
+        } else {  //handle non UI thread throw uncaught exception
+
+            new Handler(Looper.getMainLooper()).post(new Runnable() {
+                @Override
+                public void run() {
+                    invokeLogActivity(errorReport);
+                }
+            });
+        }
+    }
+    private void invokeLogActivity(StringBuilder errorReport){
+//        Intent sendIntent = new Intent();
+//        sendIntent.setAction(Intent.ACTION_SEND);
+//        sendIntent.putExtra(Intent.EXTRA_TEXT, errorReport.toString());
+//        sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+//        sendIntent.setType("text/plain");
+//        context.startActivity(sendIntent);
+
+        Intent sendIntent = new Intent(context, ErrorReportActivity.class);
+        sendIntent.putExtra(Intent.EXTRA_TEXT, errorReport.toString());
+        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        sendIntent.setType("text/plain");
+        context.startActivity(sendIntent);
+
+
+        System.exit(1);
+//        android.os.Process.killProcess(android.os.Process.myPid());
+
+        }
+
+    private boolean isUIThread(){
+        return Looper.getMainLooper().getThread() == Thread.currentThread();
+    }
+}
\ No newline at end of file
index 1740ca5..e300a5e 100644 (file)
 package com.owncloud.android.utils;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 import java.util.Vector;
 
 import third_parties.daveKoeller.AlphanumComparator;
@@ -38,7 +46,6 @@ import android.content.Context;
 import android.content.SharedPreferences;
 import android.preference.PreferenceManager;
 import android.net.Uri;
-import android.os.Environment;
 import android.os.StatFs;
 import android.webkit.MimeTypeMap;
 
@@ -55,8 +62,9 @@ public class FileStorageUtils {
 
     
     public static final String getSavePath(String accountName) {
-        File sdCard = Environment.getExternalStorageDirectory();
-        return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/" + Uri.encode(accountName, "@");
+//        File sdCard = Environment.getExternalStorageDirectory();
+
+        return MainApp.getStoragePath() + File.separator + MainApp.getDataFolder() + File.separator + Uri.encode(accountName, "@");
         // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
     }
 
@@ -65,14 +73,13 @@ public class FileStorageUtils {
     }
 
     public static final String getTemporalPath(String accountName) {
-        File sdCard = Environment.getExternalStorageDirectory();
-        return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/tmp/" + Uri.encode(accountName, "@");
+        return MainApp.getStoragePath() + File.separator + MainApp.getDataFolder() + File.separator + "tmp" + File.separator + Uri.encode(accountName, "@");
             // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B
     }
 
     @SuppressLint("NewApi")
     public static final long getUsableSpace(String accountName) {
-        File savePath = Environment.getExternalStorageDirectory();
+        File savePath = new File(MainApp.getStoragePath());
         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
             return savePath.getUsableSpace();
 
@@ -84,7 +91,7 @@ public class FileStorageUtils {
     }
     
     public static final String getLogPath()  {
-        return Environment.getExternalStorageDirectory() + File.separator + MainApp.getDataFolder() + File.separator + "log";
+        return MainApp.getStoragePath() + File.separator + MainApp.getDataFolder() + File.separator + "log";
     }
 
     public static String getInstantUploadFilePath(Context context, String fileName) {
@@ -154,13 +161,13 @@ public class FileStorageUtils {
     /**
      * Sorts all filenames, regarding last user decision 
      */
-    public static Vector<OCFile> sortFolder(Vector<OCFile> files){
+    public static Vector<OCFile> sortOcFolder(Vector<OCFile> files){
         switch (mSortOrder){
         case 0:
-            files = FileStorageUtils.sortByName(files);
+            files = FileStorageUtils.sortOCFilesByName(files);
             break;
         case 1:
-            files = FileStorageUtils.sortByDate(files);
+            files = FileStorageUtils.sortOCFilesByDate(files);
             break;
         case 2: 
            // mFiles = FileStorageUtils.sortBySize(mSortAscending);
@@ -169,12 +176,31 @@ public class FileStorageUtils {
        
         return files;
     }
+
+    /**
+     * Sorts all filenames, regarding last user decision
+     */
+    public static File[] sortLocalFolder(File[] files){
+        switch (mSortOrder){
+            case 0:
+                files = FileStorageUtils.sortLocalFilesByName(files);
+                break;
+            case 1:
+                files = FileStorageUtils.sortLocalFilesByDate(files);
+                break;
+            case 2:
+                // mFiles = FileStorageUtils.sortBySize(mSortAscending);
+                break;
+        }
+
+        return files;
+    }
     
     /**
      * Sorts list by Date
      * @param files
      */
-    public static Vector<OCFile> sortByDate(Vector<OCFile> files){
+    public static Vector<OCFile> sortOCFilesByDate(Vector<OCFile> files){
         final Integer val;
         if (mSortAscending){
             val = 1;
@@ -204,6 +230,43 @@ public class FileStorageUtils {
         return files;
     }
 
+    /**
+     * Sorts list by Date
+     * @param filesArray
+     */
+    public static File[] sortLocalFilesByDate(File[] filesArray){
+        final Integer val;
+        if (mSortAscending){
+            val = 1;
+        } else {
+            val = -1;
+        }
+
+        List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
+
+        Collections.sort(files, new Comparator<File>() {
+            public int compare(File o1, File o2) {
+                if (o1.isDirectory() && o2.isDirectory()) {
+                    Long obj1 = o1.lastModified();
+                    return val * obj1.compareTo(o2.lastModified());
+                }
+                else if (o1.isDirectory()) {
+                    return -1;
+                } else if (o2.isDirectory()) {
+                    return 1;
+                } else if (o1.lastModified() == 0 || o2.lastModified() == 0){
+                    return 0;
+                } else {
+                    Long obj1 = o1.lastModified();
+                    return val * obj1.compareTo(o2.lastModified());
+                }
+            }
+        });
+
+        File[] returnArray = new File[1];
+        return files.toArray(returnArray);
+    }
+
 //    /**
 //     * Sorts list by Size
 //     * @param sortAscending true: ascending, false: descending
@@ -242,7 +305,7 @@ public class FileStorageUtils {
      * Sorts list by Name
      * @param files     files to sort
      */
-    public static Vector<OCFile> sortByName(Vector<OCFile> files){
+    public static Vector<OCFile> sortOCFilesByName(Vector<OCFile> files){
         final Integer val;
         if (mSortAscending){
             val = 1;
@@ -265,6 +328,38 @@ public class FileStorageUtils {
         
         return files;
     }
+
+    /**
+     * Sorts list by Name
+     * @param filesArray    files to sort
+     */
+    public static File[] sortLocalFilesByName(File[] filesArray){
+        final Integer val;
+        if (mSortAscending){
+            val = 1;
+        } else {
+            val = -1;
+        }
+
+        List<File> files = new ArrayList<File>(Arrays.asList(filesArray));
+
+        Collections.sort(files, new Comparator<File>() {
+            public int compare(File o1, File o2) {
+                if (o1.isDirectory() && o2.isDirectory()) {
+                    return val * o1.getPath().toLowerCase().compareTo(o2.getPath().toLowerCase());
+                } else if (o1.isDirectory()) {
+                    return -1;
+                } else if (o2.isDirectory()) {
+                    return 1;
+                }
+                return val * new AlphanumComparator().compare(o1.getPath().toLowerCase(),
+                                                              o2.getPath().toLowerCase());
+            }
+        });
+
+        File[] returnArray = new File[1];
+        return files.toArray(returnArray);
+    }
     
     /**
      * Local Folder size
@@ -274,13 +369,11 @@ public class FileStorageUtils {
     public static long getFolderSize(File dir) {
         if (dir.exists()) {
             long result = 0;
-            File[] fileList = dir.listFiles();
-            for(int i = 0; i < fileList.length; i++) {
-                if(fileList[i].isDirectory()) {
-                    result += getFolderSize(fileList[i]);
-                } else {
-                    result += fileList[i].length();
-                }
+            for (File f : dir.listFiles()) {
+                if (f.isDirectory())
+                    result += getFolderSize(f);
+                else
+                    result += f.length();
             }
             return result;
         }
@@ -330,4 +423,36 @@ public class FileStorageUtils {
         }
     }
 
+    public static boolean copyFile(File src, File target) {
+        boolean ret = true;
+
+        InputStream in = null;
+        OutputStream out = null;
+
+        try {
+            in = new FileInputStream(src);
+            out = new FileOutputStream(target);
+            byte[] buf = new byte[1024];
+            int len;
+            while ((len = in.read(buf)) > 0) {
+                out.write(buf, 0, len);
+            }
+        } catch (IOException ex) {
+            ret = false;
+        } finally {
+            if (in != null) try {
+                in.close();
+            } catch (IOException e) {
+                e.printStackTrace(System.err);
+            }
+            if (out != null) try {
+                out.close();
+            } catch (IOException e) {
+                e.printStackTrace(System.err);
+            }
+        }
+
+        return ret;
+    }
+
 }
index 47cf143..0324493 100644 (file)
@@ -24,6 +24,7 @@
 \r
 package third_parties.daveKoeller;\r
 import java.text.Collator;\r
+import java.io.File;\r
 import java.util.Comparator;\r
 \r
 import com.owncloud.android.datamodel.OCFile;\r
@@ -77,9 +78,20 @@ public class AlphanumComparator implements Comparator<OCFile>
     }\r
 \r
     public int compare(OCFile o1, OCFile o2){\r
-        String s1 = (String)o1.getRemotePath().toLowerCase();\r
-        String s2 = (String)o2.getRemotePath().toLowerCase();\r
+        String s1 = o1.getRemotePath().toLowerCase();\r
+        String s2 = o2.getRemotePath().toLowerCase();\r
 \r
+        return compare(s1, s2);\r
+    }\r
+\r
+    public int compare(File f1, File f2){\r
+        String s1 = f1.getPath().toLowerCase();\r
+        String s2 = f2.getPath().toLowerCase();\r
+\r
+        return compare(s1, s2);\r
+    }\r
+\r
+    public int compare(String s1, String s2) {\r
         int thisMarker = 0;\r
         int thatMarker = 0;\r
         int s1Length = s1.length();\r