Merge branch '1193_uploader_layout' of https://github.com/owncloud/android into beta
authorAndy Scherzinger <info@andy-scherzinger.de>
Tue, 10 Nov 2015 10:27:23 +0000 (11:27 +0100)
committerAndy Scherzinger <info@andy-scherzinger.de>
Tue, 10 Nov 2015 10:27:23 +0000 (11:27 +0100)
Conflicts:
res/layout/uploader_layout.xml
res/layout/uploader_list_item_layout.xml
src/com/owncloud/android/ui/activity/Uploader.java

220 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]
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 [new file with mode: 0644]
res/drawable-hdpi/ic_checkbox_marked.png [new file with mode: 0644]
res/drawable-hdpi/ic_import.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_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_checkbox_blank_outline.png [new file with mode: 0644]
res/drawable-xhdpi/ic_checkbox_marked.png [new file with mode: 0644]
res/drawable-xhdpi/ic_import.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_checkbox_blank_outline.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_checkbox_marked.png [new file with mode: 0644]
res/drawable-xxhdpi/ic_import.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-v14/generic_explanation.xml
res/layout/account_setup.xml
res/layout/drawer.xml
res/layout/drawer_list_item.xml
res/layout/drawer_radiobutton.xml
res/layout/error_send.xml [new file with mode: 0644]
res/layout/file_details_fragment.xml
res/layout/file_preview.xml
res/layout/files_folder_picker.xml
res/layout/generic_explanation.xml
res/layout/grid_image.xml
res/layout/grid_item.xml
res/layout/list_footer.xml
res/layout/list_fragment.xml
res/layout/list_item.xml
res/layout/listrow_details.xml
res/layout/listrow_group.xml
res/layout/loading_dialog.xml
res/layout/log_item.xml
res/layout/log_send_file.xml
res/layout/passcodelock.xml
res/layout/ssl_untrusted_cert_layout.xml
res/layout/ssl_validator_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-ar/strings.xml
res/values-az/strings.xml
res/values-bg-rBG/strings.xml
res/values-bn-rBD/strings.xml
res/values-ca/strings.xml
res/values-cs-rCZ/strings.xml
res/values-da/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/strings.xml
res/values-et-rEE/strings.xml
res/values-eu/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-hu-rHU/strings.xml
res/values-id/strings.xml
res/values-it/strings.xml
res/values-ja-rJP/strings.xml
res/values-ko/strings.xml
res/values-lb/strings.xml
res/values-lt-rLT/strings.xml
res/values-mk/strings.xml
res/values-nb-rNO/strings.xml
res/values-nl/strings.xml
res/values-oc/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-sk-rSK/strings.xml
res/values-sl/strings.xml
res/values-sr/strings.xml
res/values-sv/strings.xml
res/values-th-rTH/strings.xml
res/values-tr/strings.xml
res/values-tzl/strings.xml [deleted file]
res/values-uk/strings.xml
res/values-v11/versioned_styles.xml
res/values-zh-rCN/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/values/versioned_styles.xml
res/xml/preferences.xml
setup_env.bat
setup_env.sh
src/com/owncloud/android/MainApp.java
src/com/owncloud/android/authentication/AuthenticatorActivity.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/RefreshFolderOperation.java
src/com/owncloud/android/operations/SynchronizeFolderOperation.java
src/com/owncloud/android/operations/UploadFileOperation.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/PassCodeActivity.java
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/UploadFilesActivity.java
src/com/owncloud/android/ui/activity/UploadPathActivity.java
src/com/owncloud/android/ui/activity/Uploader.java
src/com/owncloud/android/ui/adapter/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/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/fragment/ExtendedListFragment.java
src/com/owncloud/android/ui/fragment/LocalFileListFragment.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.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/PreviewVideoActivity.java
src/com/owncloud/android/utils/DisplayUtils.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 b4c483a..0353894 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:versionName="ownCloud beta" xmlns:android="http://schemas.android.com/apk/res/android">
 
     <uses-sdk
         android:minSdkVersion="14"
             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..22f32de 100644 (file)
@@ -1,60 +1,44 @@
-## 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-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..d8808f1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,11 +1,17 @@
-#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 comment in the corresponding pull request or create a new issue with the label "Beta".
+
+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 +20,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..563100e
--- /dev/null
@@ -0,0 +1 @@
+20151109
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
index d96997a..8480720 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,18 @@ 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 computeVersionCode()
+    }
+
     sourceSets {
         main {
             manifest.srcFile 'AndroidManifest.xml'
@@ -71,4 +77,8 @@ android {
 
 
 
-
+def computeVersionCode() {
+    def date = new Date()
+    def formattedDate = date.format('yyyyMMdd').toInteger()
+    return formattedDate
+}
\ 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 32ab89f..b06021b 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 32ab89fc308af2a51b9b7ded7fb40fc786dfd8a6
+Subproject commit b06021b059d532a268a59da3943d11fb0bb880e8
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
diff --git a/res/drawable-hdpi/ic_checkbox_blank_outline.png b/res/drawable-hdpi/ic_checkbox_blank_outline.png
new file mode 100644 (file)
index 0000000..164dcb5
Binary files /dev/null and b/res/drawable-hdpi/ic_checkbox_blank_outline.png differ
diff --git a/res/drawable-hdpi/ic_checkbox_marked.png b/res/drawable-hdpi/ic_checkbox_marked.png
new file mode 100644 (file)
index 0000000..330d7b9
Binary files /dev/null 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_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_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_checkbox_blank_outline.png b/res/drawable-xhdpi/ic_checkbox_blank_outline.png
new file mode 100644 (file)
index 0000000..05024eb
Binary files /dev/null and b/res/drawable-xhdpi/ic_checkbox_blank_outline.png differ
diff --git a/res/drawable-xhdpi/ic_checkbox_marked.png b/res/drawable-xhdpi/ic_checkbox_marked.png
new file mode 100644 (file)
index 0000000..3a2ca10
Binary files /dev/null and b/res/drawable-xhdpi/ic_checkbox_marked.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_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_checkbox_blank_outline.png b/res/drawable-xxhdpi/ic_checkbox_blank_outline.png
new file mode 100644 (file)
index 0000000..ffb1ea8
Binary files /dev/null and b/res/drawable-xxhdpi/ic_checkbox_blank_outline.png differ
diff --git a/res/drawable-xxhdpi/ic_checkbox_marked.png b/res/drawable-xxhdpi/ic_checkbox_marked.png
new file mode 100644 (file)
index 0000000..fba7e0c
Binary files /dev/null and b/res/drawable-xxhdpi/ic_checkbox_marked.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_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
index bd4b0b6..d90fb8a 100644 (file)
         android:orientation="horizontal" >
 
         <!-- 'OK' / 'CANCEL' BUTTONS CHANGE THEIR ORDER FROM ANDROID 4.0 ; THANKS, GOOGLE -->
-        <Button
+        <android.support.v7.widget.AppCompatButton
             android:id="@+id/cancel"
+            android:theme="@style/Button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:text="@string/common_cancel" />
 
-               <Button
+        <android.support.v7.widget.AppCompatButton
                    android:id="@+id/ok"
+            android:theme="@style/Button.Primary"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
index 3a8655f..a555e2f 100644 (file)
@@ -96,7 +96,6 @@
                            android:padding="0dp"\r
                            android:scaleType="fitCenter"\r
                            android:src="@drawable/ic_action_refresh_grey"\r
-               android:onClick="onRefreshClick"\r
                                android:visibility="gone"\r
                                android:background="@android:color/transparent"\r
                 android:contentDescription="@string/auth_refresh_button"\r
index aacb1c6..485ff52 100644 (file)
             android:layout_width="fill_parent"
             android:layout_height="match_parent"
             android:background="@color/background_color"
-            android:divider="#eee"
+            android:divider="@color/list_divider_background"
             android:dividerHeight="1dp"
             android:paddingTop="100dp" />
 
         <LinearLayout
             android:layout_width="fill_parent"
             android:layout_height="100dp"
-            android:paddingTop="16dp"
-            android:paddingBottom="16dp"
+            android:paddingTop="@dimen/standard_padding"
+            android:paddingBottom="@dimen/standard_padding"
             android:background="@color/owncloud_blue_accent">
 
             <ImageView
                 android:id="@+id/itemIcon"
                 android:layout_width="24sp"
                 android:layout_height="24sp"
-                android:layout_marginLeft="16sp"
+                android:layout_marginLeft="@dimen/standard_padding"
                 android:layout_marginBottom="3dp"
                 android:layout_gravity="bottom"
                 android:src="@drawable/ic_account_circle"
@@ -93,7 +93,7 @@
                 android:text="@string/app_name"
                 android:textColor="#FFF"
                 android:paddingLeft="22dp"
-                android:paddingRight="16dp"
+                android:paddingRight="@dimen/standard_padding"
                 android:textSize="24sp"
                 android:ellipsize="end"
                 android:singleLine="true"
index 8c10610..25415ac 100644 (file)
     android:layout_alignParentLeft="true"
     android:orientation="horizontal"
     android:background="@color/background_color"
-    android:layout_marginTop="16dp"
-    android:layout_marginBottom="16dp"
+    android:layout_marginTop="@dimen/standard_margin"
+    android:layout_marginBottom="@dimen/standard_margin"
     android:minHeight="?android:attr/listPreferredItemHeight">
 
     <ImageView
         android:id="@+id/itemIcon"
         android:layout_width="24sp"
         android:layout_height="24sp"
-        android:layout_marginLeft="16sp"
+        android:layout_marginLeft="@dimen/standard_margin"
         android:layout_gravity="center_vertical"
         />
 
@@ -41,7 +41,7 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:paddingLeft="22dp"
-        android:paddingRight="16dp"
+        android:paddingRight="@dimen/standard_margin"
         android:textColor="@color/drawerMenuTextColor"
         android:text="@string/app_name"
         android:textStyle="normal"
index 726d057..3c4bbdb 100644 (file)
@@ -21,7 +21,7 @@
     android:layout_width="fill_parent"
     android:layout_height="56dp"
     android:gravity="center_vertical"
-    android:paddingLeft="16dp"
-    android:paddingRight="16dp"
-    android:textColor="#000"
+    android:paddingLeft="@dimen/standard_padding"
+    android:paddingRight="@dimen/standard_padding"
+    android:textColor="@color/black"
     android:textSize="18dp" />
\ 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 0ad98e3..7a241b3 100644 (file)
@@ -32,9 +32,9 @@
                        android:id="@+id/fdFileHeaderContainer"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
-                       android:layout_marginLeft="16dp"
-                       android:layout_marginRight="16dp"
-                       android:layout_marginTop="4dp" >
+                       android:layout_marginLeft="@dimen/standard_margin"
+                       android:layout_marginRight="@dimen/standard_margin"
+                       android:layout_marginTop="@dimen/standard_margin">
        
                        <ImageView
                                android:id="@+id/fdIcon"
@@ -57,8 +57,9 @@
                        android:id="@+id/fdDetailsContainer"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
-                       android:layout_marginLeft="16dp"
-                       android:layout_marginRight="16dp"
+                       android:layout_marginLeft="@dimen/standard_margin"
+                       android:layout_marginRight="@dimen/standard_margin"
+                       android:layout_marginTop="@dimen/standard_margin"
                        android:layout_below="@id/fdFileHeaderContainer" >
                
                        <RelativeLayout
@@ -72,7 +73,6 @@
                                        android:id="@+id/fdTypeLabel"
                                        android:layout_width="wrap_content"
                                        android:layout_height="wrap_content"
-                                       android:layout_marginTop="24dp"
                                        android:text="@string/filedetails_type"
                                        android:textAppearance="?android:attr/textAppearanceMedium" />
                                        
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_alignParentTop="true"
-                               android:layout_marginLeft="12dp"
+                               android:layout_marginLeft="@dimen/standard_margin"
                                android:layout_toRightOf="@+id/fdLabelContainer" >
                                
                                <TextView
                                        android:id="@+id/fdType"
                                        android:layout_width="wrap_content"
                                        android:layout_height="wrap_content"
-                                       android:layout_marginTop="24dp"
                                        android:text="@string/placeholder_filetype"
                                        android:textAppearance="?android:attr/textAppearanceMedium" />
                                        
                        android:layout_height="wrap_content"
                        android:layout_below="@+id/fdDetailsContainer"
                        android:gravity="center_horizontal" 
-                       android:layout_margin="16dp"
+                       android:layout_margin="@dimen/standard_margin"
                        >
                        
-                       <CheckBox
+                       <android.support.v7.widget.AppCompatCheckBox
                                android:id="@+id/fdFavorite"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_centerHorizontal="true"
-                               android:text="@string/favorite" />
+                               android:text="@string/favorite"
+                               android:checked="false" />
 
                        <LinearLayout
                                android:layout_width="match_parent"
index f7a697a..685f2b5 100644 (file)
@@ -39,7 +39,7 @@
                android:id="@+id/image_preview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
-               android:layout_margin="16dp"
+               android:layout_margin="@dimen/standard_margin"
                android:layout_gravity="center"
                android:contentDescription="@string/preview_image_description"
                android:src="@drawable/logo" />
index 4fbec4a..0e334fd 100644 (file)
@@ -48,7 +48,7 @@
 
         <android.support.v7.widget.AppCompatButton
             android:id="@+id/folder_picker_btn_cancel"
-            style="@style/ownCloud.Button"
+            android:theme="@style/Button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="1"
@@ -56,7 +56,7 @@
 
         <android.support.v7.widget.AppCompatButton
                    android:id="@+id/folder_picker_btn_choose"
-            style="@style/ownCloud.Button"
+            android:theme="@style/Button.Primary"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
index f20c5f3..64c9ed0 100644 (file)
@@ -50,7 +50,7 @@
 
         <android.support.v7.widget.AppCompatButton
                    android:id="@+id/ok"
-            style="@style/ownCloud.Button"
+            android:theme="@style/Button.Primary"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
@@ -58,7 +58,7 @@
 
         <android.support.v7.widget.AppCompatButton
             android:id="@+id/cancel"
-            style="@style/ownCloud.Button"
+            android:theme="@style/Button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="1"
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 a8e8cc3..964b845 100644 (file)
     <TextView
         android:id="@+id/footerText"
         android:layout_width="match_parent"
-        android:layout_height="56dp"
+        android:layout_height="wrap_content"
+        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 81b5210..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" >
         
@@ -35,6 +39,8 @@
             android:id="@+id/list_root"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:divider="@color/list_divider_background"
+            android:dividerHeight="1px"
             android:visibility="visible" />
 
     </android.support.v4.widget.SwipeRefreshLayout>
             </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>
index 076ed7b..cf09502 100644 (file)
@@ -22,7 +22,7 @@
     android:layout_width="match_parent"\r
     android:background="@drawable/list_selector"\r
     android:orientation="vertical"\r
-    android:layout_height="56dp">\r
+    android:layout_height="72dp">\r
 \r
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:orientation="horizontal">\r
 \r
         <FrameLayout\r
-            android:layout_width="56dp"\r
-            android:layout_height="56dp"\r
+            android:layout_width="60dp"\r
+            android:layout_height="72dp"\r
+            android:paddingLeft="12dp"\r
+            android:paddingBottom="@dimen/standard_padding"\r
+            android:paddingTop="@dimen/standard_padding"\r
+            android:paddingRight="4dp"\r
             android:focusable="false"\r
             android:focusableInTouchMode="false">\r
 \r
                 android:id="@+id/localFileIndicator"\r
                 android:layout_width="@dimen/file_icon_size"\r
                 android:layout_height="@dimen/file_icon_size"\r
-                android:layout_gravity="center_vertical"\r
-                android:layout_marginLeft="22dp"\r
+                android:layout_gravity="top|right"\r
+                android:layout_marginRight="4dp"\r
                 android:src="@drawable/local_file_indicator" />\r
 \r
             <ImageView\r
                 android:id="@+id/thumbnail"\r
                 android:layout_width="@dimen/file_icon_size"\r
                 android:layout_height="@dimen/file_icon_size"\r
-                android:layout_gravity="center_vertical"\r
-                android:layout_marginLeft="12dp"\r
+                android:layout_gravity="left|center_vertical"\r
                 android:src="@drawable/ic_menu_archive" />\r
 \r
             <ImageView\r
@@ -56,8 +59,7 @@
                 android:layout_width="wrap_content"\r
                 android:layout_height="wrap_content"\r
                 android:layout_gravity="bottom|right"\r
-                android:layout_marginBottom="10dp"\r
-                android:layout_marginRight="2dp"\r
+                android:layout_marginRight="4dp"\r
                 android:src="@drawable/ic_favorite" />\r
         </FrameLayout>\r
 \r
@@ -65,7 +67,8 @@
             android:layout_width="0dp"\r
             android:layout_height="match_parent"\r
             android:layout_weight="1"\r
-            android:gravity="center_vertical"\r
+            android:gravity="top"\r
+            android:paddingTop="@dimen/standard_padding"\r
             android:orientation="vertical" >\r
 \r
             <TextView\r
                 android:layout_width="wrap_content"\r
                 android:layout_height="wrap_content"\r
                 android:layout_gravity="center_vertical"\r
-                android:layout_marginLeft="4dp"\r
+                android:layout_marginLeft="0dp"\r
                 android:layout_marginRight="4dp"\r
                 android:ellipsize="middle"\r
                 android:singleLine="true"\r
                 android:text="TextView"\r
                 android:textColor="@color/textColor"\r
-                android:textSize="16dip" />\r
+                android:textSize="@dimen/two_line_primary_text_size" />\r
 \r
             <LinearLayout\r
                 android:layout_width="match_parent"\r
                 android:layout_height="wrap_content"\r
-                android:layout_marginLeft="4dp"\r
+                android:layout_marginLeft="0dp"\r
                 android:layout_marginRight="4dp"\r
-                android:weightSum="1">\r
+                android:orientation="horizontal">\r
 \r
                 <TextView\r
-                    android:id="@+id/last_mod"\r
+                    android:id="@+id/file_size"\r
                     android:layout_width="wrap_content"\r
                     android:layout_height="wrap_content"\r
-                    android:text="TextView"\r
-                    android:layout_weight=".5"\r
+                    android:text="Size MB"\r
                     android:textColor="@color/list_item_lastmod_and_filesize_text"\r
-                    android:textSize="12dip"/>\r
+                    android:textSize="@dimen/two_line_secondary_text_size"/>\r
 \r
                 <TextView\r
-                    android:id="@+id/file_size"\r
+                    android:id="@+id/file_separator"\r
                     android:layout_width="wrap_content"\r
                     android:layout_height="wrap_content"\r
                     android:gravity="right"\r
-                    android:text="TextView"\r
+                    android:text=""\r
                     android:textColor="@color/list_item_lastmod_and_filesize_text"\r
-                    android:layout_weight=".5"\r
-                    android:textSize="12dip"/>\r
+                    android:textSize="@dimen/two_line_secondary_text_size"/>\r
+\r
+                <TextView\r
+                    android:id="@+id/last_mod"\r
+                    android:layout_width="wrap_content"\r
+                    android:layout_height="wrap_content"\r
+                    android:gravity="right"\r
+                    android:text="Mod Date"\r
+                    android:textColor="@color/list_item_lastmod_and_filesize_text"\r
+                    android:textSize="@dimen/two_line_secondary_text_size"/>\r
 \r
             </LinearLayout>\r
 \r
             android:layout_height="wrap_content"\r
             android:layout_gravity="center_vertical"\r
             android:layout_marginLeft="4dp"\r
-            android:layout_marginRight="4dp"\r
+            android:layout_marginRight="@dimen/standard_margin"\r
             android:gravity=""\r
-            android:src="@android:drawable/checkbox_off_background" />\r
+            android:src="@drawable/ic_checkbox_blank_outline" />\r
     </LinearLayout>\r
 \r
     <View\r
index 7d7a377..2bc5d66 100644 (file)
@@ -23,7 +23,7 @@
     android:clickable="true"
     android:orientation="vertical"
     android:background="#fff"
-    android:paddingLeft="16dp"
+    android:paddingLeft="@dimen/standard_padding"
     tools:context=".MainActivity" >
 
     <TextView
@@ -32,7 +32,7 @@
         android:layout_height="wrap_content"
         android:drawablePadding="5dp"
         android:gravity="center_vertical"
-        android:paddingLeft="16dp"
+        android:paddingLeft="@dimen/standard_padding"
         android:textSize="16dp" >
 
     </TextView>
index 753d738..ac71114 100644 (file)
@@ -24,7 +24,7 @@
     android:layout_height="56dp"
     android:layout_marginLeft="8dp"
     android:gravity="left"
-    android:paddingLeft="16dp"
+    android:paddingLeft="@dimen/standard_padding"
     android:paddingTop="8dp"
     android:textSize="16dp"
     android:groupIndicator="@android:color/transparent"
index 0dbb9ef..aeea08b 100644 (file)
     android:id="@+id/loadingLayout"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:orientation="horizontal" >
+    android:orientation="horizontal"
+    android:padding="@dimen/standard_padding">
 
     <ProgressBar
         android:id="@+id/loadingBar"
+        style="?android:attr/progressBarStyle"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
-        android:layout_marginBottom="10dp"
-        android:layout_marginLeft="10dp"
-        android:layout_marginRight="5dp"
-        android:layout_marginTop="10dp" />
+        android:indeterminate="true"
+        android:indeterminateOnly="false"/>
 
     <TextView
         android:id="@+id/loadingText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
-        android:layout_marginRight="20dp"
+        android:layout_marginLeft="@dimen/standard_margin"
         android:text="TextView" />
 
 </LinearLayout>
index 2353b19..70169e5 100644 (file)
@@ -30,7 +30,6 @@
         android:textStyle="bold"
         android:textSize="22dp"
         android:textColor="#000000"
-        android:layout_marginTop="5dp"
-        android:layout_marginBottom="5dp" />
+        android:layout_marginBottom="@dimen/standard_margin" />
 
 </LinearLayout>
\ No newline at end of file
index 4f90772..921528e 100644 (file)
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:padding="10dp"
-    android:paddingLeft="8dp"
-    android:paddingRight="8dp"
     android:weightSum="1" >
 
     <ScrollView
         android:id="@+id/scrollView1"
         android:layout_width="match_parent"
         android:layout_height="0dp"
-        android:layout_marginBottom="15dp"
-        android:layout_weight="1" >
+        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: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:text="@string/empty"
+                android:typeface="monospace"/>
         </LinearLayout>
     </ScrollView>
 
         android:id="@+id/historyButtonBar"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal" >
+        android:orientation="horizontal"
+        android:layout_marginBottom="@dimen/standard_margin"
+        android:layout_marginLeft="@dimen/standard_margin"
+        android:layout_marginRight="@dimen/standard_margin">
 
-    <android.support.v7.widget.AppCompatButton
+    <Button
         android:id="@+id/deleteLogHistoryButton"
-        style="@style/ownCloud.Button"
+        android:theme="@style/Button"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="bottom"
@@ -62,7 +65,7 @@
 
     <android.support.v7.widget.AppCompatButton
         android:id="@+id/sendLogHistoryButton"
-        style="@style/ownCloud.Button"
+        android:theme="@style/Button.Primary"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="bottom"
index f3a0d01..14c3cf6 100644 (file)
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:oc="http://schemas.android.com/apk/res/com.owncloud.android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:gravity="center_horizontal"
     android:orientation="vertical"
-    android:padding="20dp" >
+    android:padding="@dimen/standard_padding" >
 
 
     <TextView
@@ -33,6 +32,7 @@
         android:text="@string/pass_code_enter_pass_code"
         android:textColor="@android:color/black"
         android:gravity="center_horizontal"
+        android:textSize="16sp"
          />
 
     <TextView
@@ -42,6 +42,7 @@
         android:text="@string/pass_code_configure_your_pass_code_explanation"
         android:textAppearance="@android:style/TextAppearance.Small"
         android:gravity="center_horizontal"
+        android:textSize="14sp"
          />
     
     <LinearLayout
@@ -81,7 +82,7 @@
 
     <android.support.v7.widget.AppCompatButton
         android:id="@+id/cancel"
-        style="@style/ownCloud.Button"
+        android:theme="@style/Button.Primary"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/common_cancel" />
index 2f359f8..8b6d502 100644 (file)
@@ -21,7 +21,7 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center"
-       android:padding="16dp"
+       android:padding="@dimen/standard_padding"
     android:orientation="vertical" >
 
        <TextView
@@ -29,7 +29,7 @@
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0"
-               android:paddingBottom="16dp"
+               android:paddingBottom="@dimen/standard_padding"
                android:text="@string/ssl_validator_header"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/black"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
                android:layout_weight="0"
-               android:paddingTop="16dp"
+               android:paddingTop="@dimen/standard_padding"
         android:text="@string/ssl_validator_question"
         android:textAppearance="?android:attr/textAppearanceMedium"
         >
index 4cbd46a..df14a35 100644 (file)
     android:layout_height="wrap_content"
     android:gravity="center"
     android:orientation="vertical"
-       android:padding="16dp">
+       android:padding="@dimen/standard_padding">
 
        <TextView
                android:id="@+id/header"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/ssl_validator_header"
-               android:paddingBottom="16dp"
+               android:paddingBottom="@dimen/standard_padding"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@color/black"
                 />
         android:id="@+id/question"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-               android:paddingTop="16dp"
+               android:paddingTop="@dimen/standard_padding"
         android:text="@string/ssl_validator_question"
         android:textAppearance="?android:attr/textAppearanceMedium"
         >
index 95a3fb2..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
-            style="@style/ownCloud.Button"\r
+            android:theme="@style/Button"\r
             android:layout_width="wrap_content"\r
             android:layout_height="wrap_content"\r
             android:layout_weight="1"\r
@@ -46,7 +94,7 @@
 \r
         <android.support.v7.widget.AppCompatButton\r
                    android:id="@+id/upload_files_btn_upload"\r
-            style="@style/ownCloud.Button"\r
+            android:theme="@style/Button.Primary"\r
                    android:layout_width="wrap_content"\r
                    android:layout_height="wrap_content"\r
                    android:layout_weight="1"\r
index 601ac60..e313c09 100644 (file)
@@ -33,7 +33,7 @@
                        android:id="@android:id/list"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
-                       android:divider="#eee"
+                       android:divider="@color/list_divider_background"
                        android:dividerHeight="1dp">
                </ListView>
 
@@ -47,6 +47,7 @@
            android:orientation="horizontal" >
 
                <android.support.v7.widget.AppCompatButton
+                       android:theme="@style/Button"
                    android:id="@+id/uploader_cancel"
                        style="@style/ownCloud.Button"
                    android:layout_width="fill_parent"
@@ -57,7 +58,7 @@
 
                <android.support.v7.widget.AppCompatButton
                    android:id="@+id/uploader_choose_folder"
-                       style="@style/ownCloud.Button"
+                       android:theme="@style/Button.Primary"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
index 988c6e9..9f6f5ba 100644 (file)
  -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
-    android:layout_height="56dp"
+    android:layout_height="72dp"
     android:background="@drawable/list_selector"
     android:orientation="horizontal">
 
     <LinearLayout
-        android:layout_width="56dp"
-        android:layout_height="56dp"
+        android:layout_width="60dp"
+        android:layout_height="72dp"
         android:orientation="horizontal">
 
         <ImageView
@@ -42,7 +42,8 @@
         android:layout_width="0dp"
         android:layout_height="match_parent"
         android:layout_weight="1"
-        android:gravity="center_vertical"
+        android:gravity="top"
+        android:paddingTop="@dimen/standard_padding"
         android:orientation="vertical">
 
         <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
-            android:layout_marginLeft="4dp"
             android:layout_marginRight="4dp"
             android:ellipsize="middle"
             android:singleLine="true"
             android:text="TextView"
             android:textColor="@color/textColor"
-            android:textSize="16dip" />
+            android:textSize="16sp" />
 
         <TextView
             android:id="@+id/last_mod"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="4dp"
             android:layout_marginRight="4dp"
             android:text="TextView"
             android:textColor="@color/list_item_lastmod_and_filesize_text"
-            android:textSize="12dip" />
+            android:textSize="14sp" />
 
     </LinearLayout>
 
index 586ec4a..4d24759 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
         android:icon="@android:drawable/ic_menu_share"
         android:orderInCategory="1" />
     <item
+        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_unshare_file"
         android:title="@string/action_unshare_file"
         android:icon="@android:drawable/ic_menu_share"
         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 d4c9e6f..81613ea 100644 (file)
   <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>
index daa55fa..d3cd832 100644 (file)
@@ -181,7 +181,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>
index 1500f25..eea53c9 100644 (file)
   <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>
index 637cad4..49df5a6 100644 (file)
   <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>
index 289848d..b860271 100644 (file)
   <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>
index 4453c48..5941be1 100644 (file)
   <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>
index 6f719c0..be4c942 100644 (file)
   <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>
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..45e371e 100644 (file)
   <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>
index 134e8a4..c84258d 100644 (file)
   <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>
index 0f258a6..66df5fd 100644 (file)
   <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>
index ddcc145..5fc8dfd 100644 (file)
   <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>
index fb94653..4d98b49 100644 (file)
   <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>
index db21c45..6165582 100644 (file)
   <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>
index ed6cbbd..441831c 100644 (file)
   <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 cd766c0..0f77b14 100644 (file)
   <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>
index 9691363..7167dc5 100644 (file)
@@ -199,11 +199,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>
index c4ff565..7cb8302 100644 (file)
@@ -174,7 +174,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>
index ef76270..7db8066 100644 (file)
   <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>
index 8dde313..260ffbd 100644 (file)
@@ -204,11 +204,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>
index 5a02fbb..68ad0a4 100644 (file)
@@ -200,7 +200,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>
index 92c2ac1..14c8156 100644 (file)
   <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>
index 7a295a0..aea6f62 100644 (file)
   <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>
index 3fbb3b7..f1f7d9f 100644 (file)
   <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>
index 98e444c..3a2e02c 100644 (file)
   <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>
index 0740784..d17876a 100644 (file)
   <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>
index 0e3c31a..6aec3ba 100644 (file)
   <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>
index 5595d5c..1c958f3 100644 (file)
   <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>
index a01b92c..1459761 100644 (file)
   <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>
index 204e3f1..a2708d3 100644 (file)
   <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>
index ea48e25..95ad2e5 100644 (file)
   <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>
index 3cf1764..9a3fa84 100644 (file)
@@ -202,11 +202,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>
index ce487e8..5ba832c 100644 (file)
@@ -204,11 +204,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>
index dbe2bd4..f6a6f45 100644 (file)
   <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>
index d243dad..93ce1a1 100644 (file)
   <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>
index 152a02c..a1adba9 100644 (file)
   <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>
index a316005..b997bc9 100644 (file)
   <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>
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..5f12453 100644 (file)
   <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>
index 3e253c3..deb4af0 100644 (file)
   <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>
index 54c8ef1..0b5a4a6 100644 (file)
   <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>
index 74f0bf0..f38facb 100644 (file)
   <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>
index 1a00e96..6766749 100644 (file)
   <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>
index bd57cad..9160879 100644 (file)
   <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>
index 0eaaba1..918e5e3 100644 (file)
   <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>
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 eecba28..fed88ce 100644 (file)
   <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>
index 00fe7ca..4fdc212 100644 (file)
@@ -1,10 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-       
-       <style name="Theme.ownCloud.ButtonStyle" parent="@android:style/Widget.Holo.Light.Button">
-               <item name="android:background">@android:drawable/btn_default</item>
-               <item name="android:textColor">@color/button_text_color</item>
-       </style>
 
        <!-- Notifications -->
        <style  name="Theme.ownCloud.NotificationText.Title" 
index 85a30ce..39d4ea9 100644 (file)
   <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>
index 819568b..c783957 100644 (file)
   <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>
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 dab9b3f..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">#fff0f0f0</color>
+    <color name="list_divider_background">#eee</color>
     <color name="filelist_icon_backgorund">#DDDDDD</color>
     <color name="dark_background_text_color">#EEEEEE</color>
     <color name="login_text_color">#757575</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 76bdd9f..0d156b2 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 -->
@@ -30,7 +31,7 @@
     <!-- Colors -->
     <color name="login_background_color">#FFFFFF</color>
     <color name="login_logo_background_color">#FFFFFF</color>
-    <color name="background_color">#F7F7F7</color>
+    <color name="background_color">#FFFFFF</color>
     <color name="actionbar_start_color">#1D2D44</color>
     <color name="actionbar_end_color">#1D2D44</color>
     
@@ -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 abe7282..4e8f180 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>
     <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="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="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="share_dialog_title">Sharing</string>
     <string name="share_with_user_section_title">Share with 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 b7a6484..934b755 100644 (file)
        <style name="Theme.ownCloud" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
        <item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
-       <item name="android:buttonStyle">@style/Theme.ownCloud.ButtonStyle</item>
                <item name="colorPrimary">@color/primary</item>
                <item name="colorPrimaryDark">@color/primary_dark</item>
                <item name="colorAccent">@color/color_accent</item>
                <item name="android:alertDialogTheme">@style/Theme.ownCloud.Dialog</item>
                <item name="alertDialogTheme">@style/ownCloud.AlertDialog</item>
-               <item name="colorButtonNormal">@color/background_color</item>
-               <item name="colorControlActivated">@color/primary_dark</item>
-               <item name="colorControlHighlight">@color/color_accent</item>
        </style>
 
        <!-- seperate action bar style for activities without an action bar -->
        <style name="Theme.ownCloud.noActionBar" parent="Theme.AppCompat.Light.DarkActionBar">
-               <item name="android:buttonStyle">@style/Theme.ownCloud.ButtonStyle</item>
                <item name="windowNoTitle">true</item>
                <item name="windowActionBar">false</item>
                <item name="colorPrimary">@color/primary</item>
@@ -45,9 +40,6 @@
                <item name="colorAccent">@color/color_accent</item>
                <item name="android:alertDialogTheme">@style/Theme.ownCloud.Dialog</item>
                <item name="alertDialogTheme">@style/ownCloud.AlertDialog</item>
-               <item name="colorButtonNormal">@color/background_color</item>
-               <item name="colorControlActivated">@color/primary_dark</item>
-               <item name="colorControlHighlight">@color/color_accent</item>
     </style>
 
        <style name="Theme.ownCloud.noActionBar.Login" parent="Theme.ownCloud.noActionBar">
@@ -59,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 fc5c292..660e0fd 100644 (file)
@@ -1,12 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
-       
-    <!-- Buttons -->
-       <style name="Theme.ownCloud.ButtonStyle" parent="@android:style/Widget.Button">
-               <item name="android:background">@android:drawable/btn_default</item>
-               <item name="android:textColor">@color/button_text_color</item>
-       </style>
-       
+
        <!-- DropDown -->
        <style name="Theme.ownCloud.DropDownStyle"
                parent="style/Widget.AppCompat.Spinner.DropDown.ActionBar">
index 4823a83..b4f46f9 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_accounts" android:key="accounts_category">
+    <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..6bf385c 100644 (file)
@@ -23,6 +23,7 @@ package com.owncloud.android;
 import android.app.Activity;
 import android.app.Application;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Build;
@@ -33,6 +34,7 @@ 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,14 +56,15 @@ 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 boolean mOnlyOnDevice = false;
 
     
     public void onCreate(){
         super.onCreate();
         MainApp.mContext = getApplicationContext();
+
+        // Setup handler for uncaught exceptions.
+        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
         
         boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
 
@@ -176,14 +179,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 02ab3c7..4173ca4 100644 (file)
@@ -176,7 +176,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     private EditText mUsernameInput;\r
     private EditText mPasswordInput;\r
     private View mOkButton;\r
-    private View mCenteredRefreshButton;\r
     private TextView mAuthStatusView;\r
 \r
     private int mAuthStatusText = 0, mAuthStatusIcon = 0;\r
@@ -261,16 +260,22 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             }\r
         });\r
 \r
-        mCenteredRefreshButton = findViewById(R.id.centeredRefreshButton);\r
-        mCenteredRefreshButton.setOnClickListener(new View.OnClickListener() {\r
+        findViewById(R.id.centeredRefreshButton).setOnClickListener(new View.OnClickListener() {\r
 \r
             @Override\r
             public void onClick(View v) {\r
                 checkOcServer();\r
             }\r
         });\r
-        \r
-        mOkButton = findViewById(R.id.buttonOK);\r
+\r
+        findViewById(R.id.embeddedRefreshButton).setOnClickListener(new View.OnClickListener() {\r
+\r
+            @Override\r
+            public void onClick(View v) {\r
+                checkOcServer();\r
+            }\r
+        });\r
+\r
 \r
         /// initialize block to be moved to single Fragment to check server and get info about it \r
         initServerPreFragment(savedInstanceState);\r
@@ -702,7 +707,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
         \r
         mHostUrlInput.removeTextChangedListener(mHostUrlInputWatcher);\r
         mHostUrlInput.setOnFocusChangeListener(null);\r
-        \r
+\r
         super.onPause();\r
     }\r
     \r
@@ -811,8 +816,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
             Intent getServerInfoIntent = new Intent();\r
             getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);\r
             getServerInfoIntent.putExtra(\r
-                OperationsService.EXTRA_SERVER_URL,\r
-                normalizeUrlSuffix(uri)\r
+                    OperationsService.EXTRA_SERVER_URL,\r
+                    normalizeUrlSuffix(uri)\r
             );\r
             if (mOperationsServiceBinder != null) {\r
                 mWaitingForOpId = mOperationsServiceBinder.queueNewOperation(getServerInfoIntent);\r
@@ -1625,18 +1630,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
     }\r
 \r
     /**\r
-     * Called when the refresh button in the input field for ownCloud host is clicked.\r
-     * \r
-     * Performs a new check on the URL in the input field.\r
-     * \r
-     * @param view      Refresh 'button'\r
-     */\r
-    public void onRefreshClick(View view) {\r
-        checkOcServer();\r
-    }\r
-\r
-\r
-    /**\r
      * Called when the eye icon in the password field is clicked.\r
      * \r
      * Toggles the visibility of the password in the field. \r
index 2d353d2..f3dd3e5 100644 (file)
@@ -142,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>();
@@ -153,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()) {
@@ -513,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()) {
@@ -750,8 +747,8 @@ public class FileDataStorageManager {
         return ret;
     }
 
-
-    private Vector<OCFile> getFolderContent(long parentId/*, boolean onlyOnDevice*/) {
+    
+    private Vector<OCFile> getFolderContent(long parentId, boolean onlyOnDevice) {
 
         Vector<OCFile> ret = new Vector<OCFile>();
 
@@ -778,10 +775,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());
         }
 
@@ -1482,9 +1478,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(
@@ -1555,7 +1550,7 @@ public class FileDataStorageManager {
         return shares;
     }
 
-    public void triggerMediaScan(String path) {
+    public static 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);
index a6da654..4fcd439 100644 (file)
@@ -31,13 +31,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];
         }
@@ -76,6 +74,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..10dfbd7 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,36 @@ 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;
+        }
+    }
+
+    public static long getMaxSize(){
+        if (mThumbnailCache != null) {
+            return mThumbnailCache.getMaxSize();
+        } 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 +192,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 +216,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 +260,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 +278,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 +305,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 +366,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 +438,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 +508,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 66ada1c..e6638ba 100644 (file)
@@ -237,6 +237,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..362cada 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 org.apache.http.protocol.HTTP;
 
+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;
 
 /**
@@ -324,6 +341,64 @@ 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, "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 +425,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 +530,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));
     }
 
     /**
index 47f7127..676a12c 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,6 +126,25 @@ 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
+        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");
+        }
+
         context.startService(i);
     }
 
@@ -155,8 +178,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,19 +198,42 @@ 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
+        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");
+        }
+
         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 (!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()) {
@@ -207,6 +261,25 @@ 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
+                        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");
+                        }
+
                         context.startService(i);
 
                     } else {
@@ -217,7 +290,6 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
             c.close();
             db.close();
         }
-
     }
 
     public static boolean isOnline(Context context) {
@@ -231,6 +303,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 +331,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..df4dccd 100644 (file)
@@ -101,6 +101,7 @@ public class FileUploader extends Service
     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;
index e53c635..7bd9c0c 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.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;
@@ -210,6 +215,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;
+    }
+
 
     
     /**
@@ -430,12 +454,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 +463,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 +505,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();
         }
     }
 
index adb4ac4..c61446e 100644 (file)
@@ -196,7 +196,7 @@ public class RefreshFolderOperation extends RemoteOperation {
                 result = fetchAndSyncRemoteFolder(client);
             } else {
                 fetchFavoritesToSyncFromLocalData();
-                mChildren = mStorageManager.getFolderContent(mLocalFolder/*, false*/);
+                mChildren = mStorageManager.getFolderContent(mLocalFolder, false);
             }
 
             if (result.isSuccess()) {
@@ -346,8 +346,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);
@@ -510,7 +509,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 ee9f7c8..e7b5ba3 100644 (file)
@@ -39,6 +39,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;
@@ -358,6 +359,8 @@ public class UploadFileOperation extends RemoteOperation {
                             // return result;
                         }
                     }
+                    FileDataStorageManager.triggerMediaScan(originalFile.getAbsolutePath());
+                    FileDataStorageManager.triggerMediaScan(expectedFile.getAbsolutePath());
                 }
 
             } else if (result.getHttpCode() == HttpStatus.SC_PRECONDITION_FAILED ) {
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 249ae8d..275f5d6 100644 (file)
@@ -367,12 +367,7 @@ public class FileActivity extends AppCompatActivity
 //        }
 
         // Display username in drawer
-        Account account = AccountUtils.getCurrentOwnCloudAccount(getApplicationContext());
-        if (account != null) {
-            TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username);
-            int lastAtPos = account.name.lastIndexOf("@");
-            username.setText(account.name.substring(0, lastAtPos));
-        }
+        setUsernameInDrawer(navigationDrawerLayout, AccountUtils.getCurrentOwnCloudAccount(getApplicationContext()));
 
         // load slide menu items
         mDrawerTitles = getResources().getStringArray(R.array.drawer_items);
@@ -392,18 +387,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
@@ -439,6 +433,21 @@ public class FileActivity extends AppCompatActivity
     }
 
     /**
+     * sets the given account name in the drawer in case the drawer is available. The account name
+     * is shortened beginning from the @-sign in the username.
+     *
+     * @param navigationDrawerLayout the drawer layout to be used
+     * @param account                the account to be set in the drawer
+     */
+    protected void setUsernameInDrawer(RelativeLayout navigationDrawerLayout, Account account) {
+        if (navigationDrawerLayout != null && getAccount() != null) {
+            TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username);
+            int lastAtPos = account.name.lastIndexOf("@");
+            username.setText(account.name.substring(0, lastAtPos));
+        }
+    }
+
+    /**
      * Updates title bar and home buttons (state and icon).
      *
      * Assumes that navigation drawer is NOT visible.
@@ -859,6 +868,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();
         }
@@ -928,6 +938,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();
@@ -937,6 +953,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) {
@@ -953,24 +973,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 e814c2d..c19fb4a 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;
@@ -108,6 +109,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 +151,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");
@@ -271,12 +275,7 @@ public class FileDisplayActivity extends HookActivity
             setFile(file);
 
             if (mAccountWasSet) {
-                RelativeLayout navigationDrawerLayout = (RelativeLayout) findViewById(R.id.left_drawer);
-                if (navigationDrawerLayout != null && getAccount() != null) {
-                    TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username);
-                    int lastAtPos = getAccount().name.lastIndexOf("@");
-                    username.setText(getAccount().name.substring(0, lastAtPos));
-                }
+                setUsernameInDrawer((RelativeLayout) findViewById(R.id.left_drawer), getAccount());
             }
 
             if (!stateWasRecovered) {
@@ -305,10 +304,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 >(");
             }
@@ -327,6 +323,12 @@ public class FileDisplayActivity extends HookActivity
                     startTextPreview(file);
             }
 
+            if (DisplayUtils.isGridView(getFile(), getStorageManager())){
+                switchToGridView();
+            } else {
+                switchToListView();
+            }
+
         } else {
             Log_OC.wtf(TAG, "initFragments() called with invalid NULLs!");
             if (getAccount() == null) {
@@ -437,9 +439,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());
         }
     }
 
@@ -491,10 +491,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);
     }
@@ -503,6 +502,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;
     }
     
@@ -511,23 +517,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();
@@ -570,12 +563,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) {
@@ -770,8 +808,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);
+        }
     }
 
     /**
@@ -782,13 +824,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();
@@ -804,8 +869,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));
         }
     }
 
@@ -884,6 +961,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 {
 
@@ -939,10 +1024,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);
@@ -1198,9 +1281,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);
         }
@@ -1219,6 +1300,15 @@ public class FileDisplayActivity extends HookActivity
         cleanSecondFragment();
         // Sync Folder
         startSyncFolderOperation(directory, false);
+
+        MenuItem menuItem = mOptionsMenu.findItem(R.id.action_switch_view);
+
+        changeGridIcon();
+        if (DisplayUtils.isGridView(directory, getStorageManager())){
+            switchToGridView();
+        } else {
+            switchToListView();
+        }
     }
 
     /**
@@ -1285,9 +1375,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) {
@@ -1837,8 +1925,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);
index e1c5c10..7b85fe6 100644 (file)
@@ -34,6 +34,7 @@ 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.Handler;
 import android.os.IBinder;
@@ -62,6 +63,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,6 +72,7 @@ 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;
@@ -79,6 +82,13 @@ import com.owncloud.android.services.OperationsService;
 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;
+
 
 /**
  * An Activity that allows the user to change the application's settings.
@@ -237,6 +247,27 @@ public class Preferences extends PreferenceActivity
             
         }
 
+        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);
@@ -432,7 +463,7 @@ public class Preferences extends PreferenceActivity
        pAboutApp = (Preference) 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.setSummary(String.format(getString(R.string.about_version), BuildConfig.VERSION_CODE));
        }
 
        loadInstantUploadPath();
@@ -450,6 +481,58 @@ 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 currentVersion = BuildConfig.VERSION_CODE;
+                    LoadingVersionNumberTask loadTask = new LoadingVersionNumberTask();
+                    loadTask.execute();
+                    Integer latestVersion = -1;
+                    try {
+                        latestVersion = loadTask.get();
+                    } catch (InterruptedException | ExecutionException e) {
+                        e.printStackTrace();
+                    }
+                    if (latestVersion == -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 +540,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 +550,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);
         }
     }
 
@@ -603,6 +686,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);
@@ -879,4 +963,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 9a3ce17..f93af1f 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;
@@ -73,8 +81,10 @@ public class UploadFilesActivity extends FileActivity implements
     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");
@@ -112,6 +122,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 +157,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 +175,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 +402,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 99ca54e..daa136d 100644 (file)
@@ -335,7 +335,7 @@ 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;
@@ -423,7 +423,7 @@ 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>>();
@@ -460,7 +460,7 @@ public class Uploader extends FileActivity
         FileStorageUtils.mSortOrder = sharedPreferences.getInt("sortOrder", 0);
         FileStorageUtils.mSortAscending = sharedPreferences.getBoolean("sortAscending", true);
 
-        files = FileStorageUtils.sortFolder(files);
+        files = FileStorageUtils.sortOcFolder(files);
         return files;
     }
 
@@ -675,7 +675,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 975095b..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
@@ -193,36 +202,38 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
             switch (viewType){\r
                 case LIST_ITEM:\r
                     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(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
-                                            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
-                    } else { //Folder\r
-                        fileSizeV.setVisibility(View.INVISIBLE);\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
 \r
                 case GRID_ITEM:\r
@@ -301,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
@@ -314,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
@@ -338,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
@@ -364,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
@@ -390,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
@@ -409,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
@@ -442,7 +482,7 @@ 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
@@ -450,4 +490,45 @@ public class FileListListAdapter extends BaseAdapter implements ListAdapter {
     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 a339ed7..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);
     }
 
@@ -121,9 +133,11 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
             fileIcon.setTag(file.hashCode());
 
             TextView fileSizeV = (TextView) view.findViewById(R.id.file_size);
+            TextView fileSizeSeparatorV = (TextView) view.findViewById(R.id.file_separator);
             TextView lastModV = (TextView) view.findViewById(R.id.last_mod);
             ImageView checkBoxV = (ImageView) view.findViewById(R.id.custom_checkbox);
             if (!file.isDirectory()) {
+                fileSizeSeparatorV.setVisibility(View.VISIBLE);
                 fileSizeV.setVisibility(View.VISIBLE);
                 fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.length()));
 
@@ -134,9 +148,9 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
                     checkBoxV.setVisibility(View.GONE);
                 } else {
                     if (parentList.isItemChecked(position)) {
-                        checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
+                        checkBoxV.setImageResource(R.drawable.ic_checkbox_marked);
                     } else {
-                        checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
+                        checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
                     }
                     checkBoxV.setVisibility(View.VISIBLE);
                 }
@@ -175,6 +189,7 @@ public class LocalFileListAdapter extends BaseAdapter implements ListAdapter {
                 }  
 
             } else {
+                fileSizeSeparatorV.setVisibility(View.GONE);
                 fileSizeV.setVisibility(View.GONE);
                 lastModV.setVisibility(View.GONE);
                 checkBoxV.setVisibility(View.GONE);
@@ -229,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/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 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 8a268b7..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;
@@ -120,9 +121,9 @@ public class LocalFileListFragment extends ExtendedListFragment {
                 ImageView checkBoxV = (ImageView) v.findViewById(R.id.custom_checkbox);
                 if (checkBoxV != null) {
                     if (((ListView)getListView()).isItemChecked(position)) {
-                        checkBoxV.setImageResource(android.R.drawable.checkbox_on_background);
+                        checkBoxV.setImageResource(R.drawable.ic_checkbox_marked);
                     } else {
-                        checkBoxV.setImageResource(android.R.drawable.checkbox_off_background);
+                        checkBoxV.setImageResource(R.drawable.ic_checkbox_blank_outline);
                     }
                 }
                 // notify the change to the container Activity
@@ -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..8bda463 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,135 @@ 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().shareFileWithLink(mTargetFile);
+                    return true;
                 }
-                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);
+                        return true;
+                    } else {
+                        mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
+                    }
+                }
+                case R.id.action_stream_file: {
+                    Account account = ((FileActivity)mContainerActivity).getAccount();
+                    Context context = MainApp.getAppContext();
+                    String uri = PreviewMediaFragment.generateUrlWithCredentials(account, context, mTargetFile);
+                    MediaService.streamWithExternalApp(uri, getActivity()).show();
+                    return true;
+                }
+                case R.id.action_move: {
+                    Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+                    ArrayList files = new ArrayList();
+                    files.add(mTargetFile);
+                    action.putParcelableArrayListExtra(FolderPickerActivity.EXTRA_FILES, files);
+                    getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
+                    return true;
+                }
+                case R.id.action_favorite_file: {
+                    mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
+                    return true;
+                }
+                case R.id.action_unfavorite_file: {
+                    mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
+                    return true;
+                }
+                case R.id.action_copy:
+                    Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+
+                    // Pass mTargetFile that contains info of selected file/folder
+                    action.putExtra(FolderPickerActivity.EXTRA_FILE, mTargetFile);
+                    getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_COPY_FILES);
+                    return true;
+                default:
+                    return false;
             }
-            case R.id.action_move: {
-                Intent action = new Intent(getActivity(), FolderPickerActivity.class);
+        } else {
+            ArrayList<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 +685,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 +705,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 +722,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 +743,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 +767,7 @@ public class OCFileListFragment extends ExtendedListFragment
                     if (!file.isHidden()) {
                         filesCount++;
 
-                        if (file.isImage()) {
+                        if (file.isImage() || file.isVideo()) {
                             imagesCount++;
                         }
                     }
@@ -527,11 +780,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 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..f797fe2 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;
@@ -156,9 +157,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 :
@@ -429,12 +429,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..b3aab45 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,44 @@ 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 thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
+                        String.valueOf("r" + getFile().getRemoteId())
+                );
+
+                if (thumbnail != null && !getFile().needsUpdateThumbnail()){
+                    mProgressWheel.setVisibility(View.GONE);
+                    mImageView.setImageBitmap(thumbnail);
+                    mImageView.setVisibility(View.VISIBLE);
+                    mBitmap  = thumbnail;
+                } else {
+                    // generate new Thumbnail
+                    if (ThumbnailsCacheManager.cancelPotentialWork(getFile(), mImageView) &&
+                        mContainerActivity.getStorageManager() != null) {
+                        final ThumbnailsCacheManager.ThumbnailGenerationTask task =
+                                new ThumbnailsCacheManager.ThumbnailGenerationTask(
+                                        mImageView, mContainerActivity.getStorageManager(),
+                                        mContainerActivity.getStorageManager().getAccount(),
+                                        mProgressWheel);
+                        if (thumbnail == null) {
+                            thumbnail = ThumbnailsCacheManager.mDefaultImg;
+                        }
+                        final ThumbnailsCacheManager.AsyncDrawable asyncDrawable =
+                                new ThumbnailsCacheManager.AsyncDrawable(
+                                        MainApp.getAppContext().getResources(),
+                                        thumbnail,
+                                        task
+                                );
+                        mImageView.setImageDrawable(asyncDrawable);
+                        task.execute(getFile(), false);
+                    }
+            }
+            } else {
+                mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
+                mLoadBitmapTask.execute(getFile());
+            }
         }
     }
 
@@ -224,6 +264,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());
     }
 
     /**
@@ -311,9 +354,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 +375,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 +565,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..42cbf09 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, false);
         
-        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 2c5527c..a749b5c 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.os.AsyncTask;
 import android.support.v7.app.AlertDialog;
 import android.content.ComponentName;
 import android.content.Context;
@@ -52,9 +56,16 @@ import android.widget.ImageView;
 import android.widget.Toast;
 import android.widget.VideoView;
 
+import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.files.FileMenuFilter;
+import com.owncloud.android.lib.common.OwnCloudAccount;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.OwnCloudCredentials;
+import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.media.MediaControlView;
 import com.owncloud.android.media.MediaService;
@@ -64,6 +75,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).
@@ -87,6 +101,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;
@@ -184,10 +199,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);
@@ -198,7 +209,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);
@@ -271,7 +282,7 @@ public class PreviewMediaFragment extends FileFragment implements
         Log_OC.e(TAG, "onStart");
 
         OCFile file = getFile();
-        if (file != null && file.isDown()) {
+        if (file != null) {
             if (file.isAudio()) {
                 bindMediaService();
 
@@ -439,8 +450,65 @@ public class PreviewMediaFragment extends FileFragment implements
 
         // load the video file in the video player ; 
         // when done, VideoHelper#onPrepared() will be called
-        Uri uri = Uri.parse(getFile().getStoragePath());
-        mVideoPreview.setVideoPath(uri.encode(getFile().getStoragePath()));
+        if (getFile().isDown()) {
+            mUri = getFile().getStoragePath();
+        } else {
+            Context context = MainApp.getAppContext();
+            Account account = mContainerActivity.getStorageManager().getAccount();
+
+            mUri = generateUrlWithCredentials(account, context, getFile());
+        }
+
+        mVideoPreview.setVideoPath(mUri);
+    }
+
+    public static String generateUrlWithCredentials(Account account, Context context, OCFile file){
+        OwnCloudAccount ocAccount = null;
+        try {
+            ocAccount = new OwnCloudAccount(account, context);
+
+            final ClientGenerationTask task = new ClientGenerationTask();
+            task.execute(ocAccount);
+
+            OwnCloudClient mClient = task.get();
+            String url = AccountUtils.constructFullURLForAccount(context, account) + Uri.encode(file.getRemotePath(), "/");
+            OwnCloudCredentials credentials = mClient.getCredentials();
+
+            return url.replace("//", "//" + credentials.getUsername() + ":" + credentials.getAuthToken() + "@");
+
+        } catch (AccountUtils.AccountNotFoundException e) {
+            e.printStackTrace();
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    public static class ClientGenerationTask extends AsyncTask<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;
+        }
     }
 
 
@@ -508,27 +576,11 @@ public class PreviewMediaFragment extends FileFragment implements
          */
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
-            if (mVideoPreview.getWindowToken() != null) {
-                String message = MediaService.getMessageForMediaError(
-                        getActivity(), what, extra);
-                new AlertDialog.Builder(getActivity())
-                        .setMessage(message)
-                        .setPositiveButton(android.R.string.VideoView_error_button,
-                                new DialogInterface.OnClickListener() {
-                                    public void onClick(DialogInterface dialog, int whichButton) {
-                                        dialog.dismiss();
-                                        VideoHelper.this.onCompletion(null);
-                                    }
-                                })
-                        .setCancelable(false)
-                        .show();
-            }
+            MediaService.streamWithExternalApp(mUri, getActivity()).show();
             return true;
         }
-
     }
 
-
     @Override
     public void onPause() {
         Log_OC.e(TAG, "onPause");
index 42b7fb2..383b082 100644 (file)
@@ -207,14 +207,9 @@ public class PreviewVideoActivity extends FileActivity implements OnCompletionLi
                     mVideoPlayer.setVideoPath(file.getStoragePath());
                     
                 } 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 b6eaa89..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,8 +47,10 @@ 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
 import java.net.IDN;\r
 import java.text.DateFormat;\r
 import java.util.Calendar;\r
@@ -52,6 +66,7 @@ public class DisplayUtils {
     private static final String OWNCLOUD_APP_NAME = "ownCloud";\r
     \r
     private static final String[] sizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };\r
+    private static final int[] sizeScales = { 0, 0, 0, 1, 1, 2, 2, 2, 2 };\r
 \r
     private static Map<String, String> mimeType2HumanReadable;\r
 \r
@@ -72,19 +87,24 @@ public class DisplayUtils {
 \r
     /**\r
      * Converts the file size in bytes to human readable output.\r
-     * \r
+     * <ul>\r
+     *     <li>appends a size suffix, e.g. B, KB, MB etc.</li>\r
+     *     <li>rounds the size based on the suffix to 0,1 or 2 decimals</li>\r
+     * </ul>\r
+     *\r
      * @param bytes Input file size\r
      * @return Like something readable like "12 MB"\r
      */\r
     public static String bytesToHumanReadable(long bytes) {\r
         double result = bytes;\r
-        int attachedsuff = 0;\r
-        while (result > 1024 && attachedsuff < sizeSuffixes.length) {\r
+        int attachedSuff = 0;\r
+        while (result > 1024 && attachedSuff < sizeSuffixes.length) {\r
             result /= 1024.;\r
-            attachedsuff++;\r
+            attachedSuff++;\r
         }\r
-        result = ((int) (result * 100)) / 100.;\r
-        return result + " " + sizeSuffixes[attachedsuff];\r
+\r
+        return new BigDecimal(result).setScale(\r
+                sizeScales[attachedSuff], BigDecimal.ROUND_HALF_UP) + " " + sizeSuffixes[attachedSuff];\r
     }\r
 \r
     /**\r
@@ -247,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
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..47a46d2 100644 (file)
 package com.owncloud.android.utils;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 import java.util.Vector;
 
 import third_parties.daveKoeller.AlphanumComparator;
@@ -154,13 +157,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 +172,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 +226,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 +301,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 +324,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
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