Prechádzať zdrojové kódy

- extend existing FileUpload, so we can handel failed instand upload
later
- new Activity to handle failed instant uploads
- new Activity InstantUploadActivity can be started at two ways,
-touch to the 'Faild Upload Notifivation'
-submenue underneath the upload menue
- merges from head
- add lazy loading for the images list with failed uploads

Matthias Baumann 12 rokov pred
rodič
commit
f764980474

+ 13 - 11
AndroidManifest.xml

@@ -57,6 +57,8 @@
             </intent-filter>
         </activity>
         <activity android:name=".ui.activity.UploadFilesActivity">
+        </activity>
+ 		<activity android:name=".ui.activity.InstantUploadActivity">
         </activity>
         <activity android:name=".Uploader" >
             <intent-filter>
@@ -132,25 +134,25 @@
         <service android:name=".files.services.FileDownloader" >
         </service>
 
-        <activity android:name=".ui.activity.FileDetailActivity" />
+        <activity android:name=".ui.activity.FileDetailActivity" />
         <activity android:name=".ui.activity.PinCodeActivity" />
-        <activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
+        <activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
         <activity android:name=".extensions.ExtensionsListActivity"></activity>
         <activity android:name=".ui.activity.AccountSelectActivity" android:uiOptions="none" android:label="@string/prefs_accounts"></activity>
-        <activity android:name=".ui.activity.ConflictsResolveActivity"/>
+        <activity android:name=".ui.activity.ConflictsResolveActivity"/>
         <activity android:name=".ui.activity.GenericExplanationActivity"/>
         <activity android:name=".ui.activity.ErrorsWhileCopyingHandlerActivity"/>
-        
+        
         <service android:name=".files.services.FileUploader" >
-        </service>
-        <service android:name=".files.services.InstantUploadService" />
+        </service>
+        <service android:name=".files.services.InstantUploadService" />
         <receiver android:name=".files.InstantUploadBroadcastReceiver">
             <intent-filter>
                 <action android:name="com.android.camera.NEW_PICTURE" />
                 <data android:mimeType="image/*" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
             </intent-filter>
         </receiver>
         <receiver android:name=".files.BootupBroadcastReceiver">
@@ -158,7 +160,7 @@
                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
             </intent-filter>
         </receiver>
-        <service android:name=".files.services.FileObserverService"/>
+        <service android:name=".files.services.FileObserverService"/>
     </application>
 
-</manifest>
+</manifest>

+ 104 - 0
res/layout/failed_upload_files.xml

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  ownCloud Android client application
+
+  Copyright (C) 2012  Bartek Przybylski
+  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 as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  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="fill_parent"
+    android:layout_height="fill_parent"
+    android:background="@color/owncloud_white"
+    android:orientation="vertical"
+    android:id="@+id/failed_files_list_view">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right"
+        android:orientation="horizontal" >
+
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" >
+
+            <TextView
+                android:id="@+id/failed_upload_headline_textview"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0.93"
+                android:hint="@string/failed_upload_headline_hint"
+                android:text="@string/failed_upload_headline_text" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|right" >
+
+            <CheckBox
+                android:id="@+id/failed_upload_headline_cb"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/failed_upload_all_cb"
+                android:textSize="8sp" />
+
+            <Button
+                android:id="@+id/failed_upload_retry_all_btn"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:minHeight="30dp"
+                android:minWidth="90dp"
+                android:text="@string/failed_upload_headline_retryall_btn"
+                android:textSize="8sp" />
+
+            <Button
+                android:id="@+id/failed_upload_delete_all_btn"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:minHeight="30dp"
+                android:minWidth="90dp"
+                android:text="@string/failed_upload_headline_delete_all_btn"
+                android:textSize="8sp" />
+
+        </LinearLayout>
+
+    </LinearLayout>
+ 
+      <ScrollView
+          android:id="@+id/failedUploadScrollView"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"
+          android:overScrollMode="ifContentScrolls" >
+
+         <LinearLayout
+             android:id="@+id/failed_upload_scrollviewlayout"
+             android:layout_width="match_parent"
+             android:layout_height="wrap_content"
+             android:orientation="vertical">
+
+           
+         </LinearLayout>
+     </ScrollView>
+
+</LinearLayout>

+ 2 - 1
res/layout/file_activity_details.xml

@@ -16,7 +16,8 @@
   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/>.

+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"

+ 10 - 0
res/values-de-rDE/strings.xml

@@ -216,4 +216,14 @@
   <string name="conflict_keep_both">Beide behalten</string>
   <string name="conflict_overwrite">Überschreiben</string>
   <string name="conflict_dont_upload">Nicht hochladen</string>
+  
+  <string name="actionbar_failed_instant_upload">Fehlgeschlagene Sofortuploads</string>  
+  <string name="failed_upload_headline_text">Fehlgeschlagene Sofortuploads</string>
+  <string name="failed_upload_headline_hint">Auflistung aller fehlgeschlagenen Softuploads</string>
+  <string name="failed_upload_all_cb">Alle auswählen</string>
+  <string name="failed_upload_headline_retryall_btn">Ausgewählte wiederholen</string>
+  <string name="failed_upload_headline_delete_all_btn">Ausgewählte löschen </string>
+  <string name="failed_upload_retry_text">Versuche ausgewählte erneut hochzuladen</string>
+  <string name="failed_upload_load_more_images">Load more Picrures</string>
+  <string name="failed_upload_retry_do_nothing_text">do nothing you are not online for instant upload</string>
 </resources>

+ 10 - 0
res/values-de/strings.xml

@@ -216,4 +216,14 @@
   <string name="conflict_keep_both">Beide behalten</string>
   <string name="conflict_overwrite">Überschreiben</string>
   <string name="conflict_dont_upload">Nicht hochladen</string>
+  
+  <string name="actionbar_failed_instant_upload">Fehlgeschlagene Sofortuploads</string>  
+  <string name="failed_upload_headline_text">Fehlgeschlagene Sofortuploads</string>
+  <string name="failed_upload_headline_hint">Auflistung aller fehlgeschlagenen Softuploads</string>
+  <string name="failed_upload_all_cb">Alle auswählen</string>
+  <string name="failed_upload_headline_retryall_btn">Ausgewählte wiederholen</string>
+  <string name="failed_upload_headline_delete_all_btn">Ausgewählte löschen </string>
+  <string name="failed_upload_retry_text">Versuche ausgewählte erneut hochzuladen</string>
+  <string name="failed_upload_load_more_images">Weitere Bilder laden</string>
+<string name="failed_upload_retry_do_nothing_text">Upload nicht gestarted, Sie sind nicht online für ein Softupload</string>
 </resources>

+ 64 - 77
res/values/strings.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
+
     <string name="app_name">ownCloud</string>
     <string name="whats_new">What\'s new</string>
     <string name="main_password">Password:</string>
@@ -14,9 +15,7 @@
     <string name="main_settings">Settings</string>
     <string name="main_tit_accsetup">Setup Account</string>
     <string name="main_wrn_accsetup">There is no account set up on your device. In order to use this App, you need to create one.</string>
-    
     <string name="about_message">%1$s Android App\n\nversion: %2$s</string>
-    
     <string name="actionbar_sync">Refresh</string>
     <string name="actionbar_upload">Upload</string>
     <string name="actionbar_upload_from_apps">Content from other apps</string>
@@ -24,7 +23,6 @@
     <string name="actionbar_mkdir">Create directory</string>
     <string name="actionbar_search">Search</string>
     <string name="actionbar_settings">Settings</string>
-    
     <string name="prefs_category_general">General</string>
     <string name="prefs_category_trackmydevice">Device tracking</string>
     <string name="prefs_add_session">Add new session</string>
@@ -42,7 +40,6 @@
     <string name="prefs_pincode_summary">Protect your client</string>
     <string name="prefs_instant_upload">Enable instant uploads</string>
     <string name="prefs_instant_upload_summary">Instantly upload photos taken by camera</string>
-    
     <string name="auth_host_url">URL</string>
     <string name="auth_username">Username</string>
     <string name="auth_password">Password</string>
@@ -62,12 +59,12 @@
     <string name="uploader_wrn_no_account_text">There are no %1$s accounts on your device. Please setup an account first.</string>
     <string name="uploader_wrn_no_account_setup_btn_text">Setup</string>
     <string name="uploader_wrn_no_account_quit_btn_text">Quit</string>
-	<string name="uploader_wrn_no_content_title">No content to upload</string>
-	<string name="uploader_wrn_no_content_text">No content was received. Nothing to upload.</string>
+    <string name="uploader_wrn_no_content_title">No content to upload</string>
+    <string name="uploader_wrn_no_content_text">No content was received. Nothing to upload.</string>
     <string name="uploader_error_forbidden_content">%1$s is not allowed to access the shared content</string>
     <string name="uploader_info_uploading">Uploading</string>
     <string name="uploader_btn_create_dir_text">Create directory for upload</string>
-	<string name="file_list_empty">There are no files in this folder.\nNew files can be added with the \"Upload\" menu option.</string>
+    <string name="file_list_empty">There are no files in this folder.\nNew files can be added with the \"Upload\" menu option.</string>
     <string name="filedetails_select_file">Tap on a file to display additional information.</string>
     <string name="filedetails_size">Size:</string>
     <string name="filedetails_type">Type:</string>
@@ -75,7 +72,7 @@
     <string name="filedetails_modified">Modified:</string>
     <string name="filedetails_download">Download</string>
     <string name="filedetails_sync_file">Refresh</string>
-	<string name="filedetails_redownload">Redownload</string>
+    <string name="filedetails_redownload">Redownload</string>
     <string name="filedetails_open">Open</string>
     <string name="filedetails_renamed_in_upload_msg">File was renamed to %1$s during upload</string>
     <string name="common_yes">Yes</string>
@@ -83,20 +80,18 @@
     <string name="common_ok">OK</string>
     <string name="common_cancel_download">Cancel download</string>
     <string name="common_cancel_upload">Cancel upload</string>
-	<string name="common_cancel">Cancel</string>
+    <string name="common_cancel">Cancel</string>
     <string name="common_save_exit">Save &amp; Exit</string>
     <string name="common_exit">Leave %1$s</string>
     <string name="common_error">Error</string>
     <string name="about_title">About</string>
-    
     <string name="delete_account">Delete account</string>
     <string name="create_account">Create account</string>
-    
     <string name="upload_chooser_title">Upload from &#8230;</string>
     <string name="uploader_info_dirname">Directory name</string>
-	<string name="uploader_upload_in_progress_ticker">Uploading &#8230;</string>    
-	<string name="uploader_upload_in_progress_content">%1$d%% Uploading %2$s</string>    
-	<string name="uploader_upload_succeeded_ticker">Upload succeeded</string>
+    <string name="uploader_upload_in_progress_ticker">Uploading &#8230;</string>
+    <string name="uploader_upload_in_progress_content">%1$d%% Uploading %2$s</string>
+    <string name="uploader_upload_succeeded_ticker">Upload succeeded</string>
     <string name="uploader_upload_succeeded_content_single">%1$s was successfully uploaded</string>
     <string name="uploader_upload_succeeded_content_multiple">%1$d files were successfully uploaded</string>
     <string name="uploader_upload_failed_ticker">Upload failed</string>
@@ -110,49 +105,45 @@
     <string name="downloader_download_failed_content">Download of %1$s could not be completed</string>
     <string name="common_choose_account">Choose account</string>
     <string name="sync_string_contacts">Contacts</string>
-	<string name="sync_fail_ticker">Synchronization failed</string>
+    <string name="sync_fail_ticker">Synchronization failed</string>
     <string name="sync_fail_content">Synchronization of %1$s could not be completed</string>
-	<string name="sync_conflicts_in_favourites_ticker">Conflicts found</string>
-	<string name="sync_conflicts_in_favourites_content">%1$d kept-in-sync files could not be sync\'ed</string>
+    <string name="sync_conflicts_in_favourites_ticker">Conflicts found</string>
+    <string name="sync_conflicts_in_favourites_content">%1$d kept-in-sync files could not be sync\'ed</string>
     <string name="sync_fail_in_favourites_ticker">Kept-in-sync files failed</string>
-	<string name="sync_fail_in_favourites_content">Contents of %1$d files could not be sync\'ed (%2$d conflicts)</string>
-	<string name="sync_foreign_files_forgotten_ticker">Some local files were forgotten</string>
-	<string name="sync_foreign_files_forgotten_content">%1$d files out of the %2$s directory could not be copied into</string>
-	<string name="sync_foreign_files_forgotten_explanation">"As of version 1.3.16, files uploaded from this device are copied into the local %1$s folder to prevent data loss when a single file is synced with multiple accounts.\n\nDue to this change, all files uploaded in previous versions of this app were copied into the %2$s folder. However, an error prevented the completion of this operation during account synchronization. You may either leave the file(s) as is and remove the link to %3$s, or move the file(s) into the %1$s directory and retain the link to %4$s.\n\nListed below are the local file(s), and the the remote file(s) in %5$s they were linked to.</string>
-    
+    <string name="sync_fail_in_favourites_content">Contents of %1$d files could not be sync\'ed (%2$d conflicts)</string>
+    <string name="sync_foreign_files_forgotten_ticker">Some local files were forgotten</string>
+    <string name="sync_foreign_files_forgotten_content">%1$d files out of the %2$s directory could not be copied into</string>
+    <string name="sync_foreign_files_forgotten_explanation">"As of version 1.3.16, files uploaded from this device are copied into the local %1$s folder to prevent data loss when a single file is synced with multiple accounts.\n\nDue to this change, all files uploaded in previous versions of this app were copied into the %2$s folder. However, an error prevented the completion of this operation during account synchronization. You may either leave the file(s) as is and remove the link to %3$s, or move the file(s) into the %1$s directory and retain the link to %4$s.\n\nListed below are the local file(s), and the the remote file(s) in %5$s they were linked to.</string>
     <string name="foreign_files_move">"Move all"</string>
     <string name="foreign_files_success">"All files were moved"</string>
     <string name="foreign_files_fail">"Some files could not be moved"</string>
     <string name="foreign_files_local_text">"Local: %1$s"</string>
-	<string name="foreign_files_remote_text">"Remote: %1$s"</string>
-
-	<string name="upload_query_move_foreign_files">There is not space enough to copy the selected files into the %1$s folder. Would like to move them into instead? </string>	
-    	
-	<string name="use_ssl">Use Secure Connection</string>
+    <string name="foreign_files_remote_text">"Remote: %1$s"</string>
+    <string name="upload_query_move_foreign_files">There is not space enough to copy the selected files into the %1$s folder. Would like to move them into instead? </string>
+    <string name="use_ssl">Use Secure Connection</string>
     <string name="location_no_provider">%1$s cannot track your device. Please check your location settings</string>
-    
     <string name="pincode_enter_pin_code">Please, insert your App PIN</string>
     <string name="pincode_enter_new_pin_code">Please, insert your new App PIN</string>
     <string name="pincode_configure_your_pin">Enter your App PIN</string>
-    <string name="pincode_configure_your_pin_explanation">The PIN will be requested every time the app is started</string> 
+    <string name="pincode_configure_your_pin_explanation">The PIN will be requested every time the app is started</string>
     <string name="pincode_reenter_your_pincode">Please, reenter your App PIN</string>
     <string name="pincode_remove_your_pincode">Remove your App PIN</string>
-    <string name="pincode_mismatch">The App PINs are not the same</string> 
+    <string name="pincode_mismatch">The App PINs are not the same</string>
     <string name="pincode_wrong">Incorrect App PIN</string>
     <string name="pincode_removed">App PIN removed</string>
     <string name="pincode_stored">App PIN stored</string>
-    
+
     <string-array name="prefs_trackmydevice_intervall_keys">
-    	<item>15 Minutes</item>
-    	<item>30 Minutes</item>
-    	<item>60 Minutes</item>
-	</string-array>
-	
+        <item>15 Minutes</item>
+        <item>30 Minutes</item>
+        <item>60 Minutes</item>
+    </string-array>
     <string-array name="prefs_trackmydevice_intervall_values">
-    	<item>15</item>
-    	<item>30</item>
-    	<item>60</item>
-	</string-array>
+        <item>15</item>
+        <item>30</item>
+        <item>60</item>
+    </string-array>
+
     <string name="auth_trying_to_login">Trying to login…</string>
     <string name="auth_no_net_conn_title">No network connection</string>
     <string name="auth_no_net_conn_message">No network connection has been detected, check your Internet connection and try again.</string>
@@ -171,51 +162,41 @@
     <string name="auth_incorrect_path_message">Application couldn\'t find a server instance at the given path. Please check your path and try again.</string>
     <string name="auth_timeout_title">The server took too long to respond</string>
     <string name="auth_incorrect_address_title">Malformed URL</string>
-	<string name="auth_ssl_general_error_title">SSL initialization failed</string>
-	<string name="auth_ssl_unverified_server_title">Unverified SSL server\'s identity</string>
-	<string name="auth_bad_oc_version_title">Unrecognized server version</string>
-	<string name="auth_wrong_connection_title">Couldn\'t establish connection</string>
-	<string name="auth_secure_connection">Secure connection established</string>
+    <string name="auth_ssl_general_error_title">SSL initialization failed</string>
+    <string name="auth_ssl_unverified_server_title">Unverified SSL server\'s identity</string>
+    <string name="auth_bad_oc_version_title">Unrecognized server version</string>
+    <string name="auth_wrong_connection_title">Couldn\'t establish connection</string>
+    <string name="auth_secure_connection">Secure connection established</string>
     <string name="auth_login_details">Login details</string>
     <string name="auth_unauthorized">Invalid login / password</string>
     <string name="auth_not_found">Wrong path given</string>
     <string name="auth_internal">Internal server error, code %1$d</string>
-    
     <string name="crashlog_message">Application terminated unexpectedly. Would you like to submit a crash report?</string>
     <string name="crashlog_send_report">Send report</string>
     <string name="crashlog_dont_send_report">Don\'t send report</string>
-    
     <string name="extensions_avail_title">Extensions available!</string>
     <string name="extensions_avail_message">Looks like your server instance is supporting advanced extensions. Would you like to see extensions available for android ?</string>
     <string name="fd_keep_in_sync">Keep file up to date</string>
     <string name="common_share">Share</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_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 contents only</string>
-	  <string name="confirmation_remove_remote">Remove from server</string>
-	  <string name="confirmation_remove_remote_and_local">Remote and local</string>
-
+    <string name="confirmation_remove_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 contents only</string>
+    <string name="confirmation_remove_remote">Remove from server</string>
+    <string name="confirmation_remove_remote_and_local">Remote and local</string>
     <string name="remove_success_msg">"Removal succeeded"</string>
     <string name="remove_fail_msg">"Removal failed"</string>
-    
     <string name="rename_dialog_title">Enter a new name</string>
     <string name="rename_local_fail_msg">"Local copy could not be renamed; try a different name"</string>
     <string name="rename_server_fail_msg">"Rename could not be completed"</string>
-        
-    <string name="sync_file_fail_msg">Remote file could not be checked</string> 
-    <string name="sync_file_nothing_to_do_msg">File contents already synchronized</string> 
-    
+    <string name="sync_file_fail_msg">Remote file could not be checked</string>
+    <string name="sync_file_nothing_to_do_msg">File contents already synchronized</string>
     <string name="create_dir_fail_msg">Directory could not be created</string>
-    
     <string name="wait_a_moment">Wait a moment</string>
-	
     <string name="filedisplay_unexpected_bad_get_content">"Unexpected problem ; please select the file from a different app"</string>
     <string name="filedisplay_no_file_selected">No file was selected</string>
-    
     <string name="ssl_validator_title">Warning</string>
     <string name="ssl_validator_header">The identity of the site could not be verified</string>
     <string name="ssl_validator_reason_cert_not_trusted">- The server certificate is not trusted</string>
@@ -231,28 +212,34 @@
     <string name="ssl_validator_label_issuer">Issued by:</string>
     <string name="ssl_validator_label_CN">Common name:</string>
     <string name="ssl_validator_label_O">Organization:</string>
-	<string name="ssl_validator_label_OU">Organizational unit:</string>
-	<string name="ssl_validator_label_C">Country:</string>
-	<string name="ssl_validator_label_ST">State:</string>
-	<string name="ssl_validator_label_L">Location:</string>
+    <string name="ssl_validator_label_OU">Organizational unit:</string>
+    <string name="ssl_validator_label_C">Country:</string>
+    <string name="ssl_validator_label_ST">State:</string>
+    <string name="ssl_validator_label_L">Location:</string>
     <string name="ssl_validator_label_validity">Validity:</string>
     <string name="ssl_validator_label_validity_from">From:</string>
-	<string name="ssl_validator_label_validity_to">To:</string>
-	<string name="ssl_validator_label_signature">Signature:</string>
-	<string name="ssl_validator_label_signature_algorithm">Algorithm:</string>
-			
+    <string name="ssl_validator_label_validity_to">To:</string>
+    <string name="ssl_validator_label_signature">Signature:</string>
+    <string name="ssl_validator_label_signature_algorithm">Algorithm:</string>
     <string name="text_placeholder">This is a placeholder</string>
-    
     <string name="instant_upload_on_wifi">Upload pictures via WiFi only</string>
-	<string name="instant_upload_path">/InstantUpload</string>
-    
+    <string name="instant_upload_path">/InstantUpload</string>
     <string name="conflict_title">Update conflict</string>
     <string name="conflict_message">Remote file %s is not synchronized with local file. Continuing will replace content of file on server.</string>
     <string name="conflict_keep_both">Keep both</string>
     <string name="conflict_overwrite">Overwrite</string>
     <string name="conflict_dont_upload">Don\'t upload</string>
-    
+
     <!-- we need to improve the communication of errors to the user -->
     <string name="error__upload__local_file_not_copied">%1$s could not be copied to %2$s local directory</string>
-    
-</resources>
+    <string name="actionbar_failed_instant_upload">Failed InstantUpload"</string>
+    <string name="failed_upload_headline_text">Failed instant uploads</string>
+    <string name="failed_upload_headline_hint">Summary of all failed instant uploads</string>
+    <string name="failed_upload_all_cb">select all</string>
+    <string name="failed_upload_headline_retryall_btn">retry all selected</string>
+    <string name="failed_upload_headline_delete_all_btn">delete all  selected from uploadqueue</string>
+    <string name="failed_upload_retry_text">retry to upload the image: </string>
+    <string name="failed_upload_load_more_images">Load more Picrures</string>
+    <string name="failed_upload_retry_do_nothing_text">do nothing you are not online for instant upload</string>
+
+</resources>

+ 112 - 94
src/com/owncloud/android/db/DbHandler.java

@@ -1,94 +1,112 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011-2012  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   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.db;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-
-/**
- * Custom database helper for ownCloud
- * 
- * @author Bartek Przybylski
- * 
- */
-public class DbHandler {
-    private SQLiteDatabase mDB;
-    private OpenerHelper mHelper;
-    private final String mDatabaseName = "ownCloud";
-    private final int mDatabaseVersion = 1;
-    
-    private final String TABLE_INSTANT_UPLOAD = "instant_upload";
-
-    public DbHandler(Context context) {
-        mHelper = new OpenerHelper(context);
-        mDB = mHelper.getWritableDatabase();
-    }
-
-    public void close() {
-        mDB.close();
-    }
-
-    public boolean putFileForLater(String filepath, String account) {
-        ContentValues cv = new ContentValues();
-        cv.put("path", filepath);
-        cv.put("account", account);
-        return mDB.insert(TABLE_INSTANT_UPLOAD, null, cv) != -1;
-    }
-    
-    public Cursor getAwaitingFiles() {
-        return mDB.query(TABLE_INSTANT_UPLOAD, null, null, null, null, null, null);
-    }
-    
-    public void clearFiles() {
-        mDB.delete(TABLE_INSTANT_UPLOAD, null, null);
-    }
-    
-    /**
-     * 
-     * @param localPath
-     * @param accountName
-     * @return true when one or more pendin files was removed
-     */
-    public boolean removeIUPendingFile(String localPath, String accountName) {
-        return mDB.delete(TABLE_INSTANT_UPLOAD,
-                          "path = ?",
-                          new String[]{ localPath }) != 0;
-        
-    }
-    
-    private class OpenerHelper extends SQLiteOpenHelper {
-        public OpenerHelper(Context context) {
-            super(context, mDatabaseName, null, mDatabaseVersion);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE_INSTANT_UPLOAD + " ("
-            		+ " _id INTEGER PRIMARY KEY, "
-            		+ " path TEXT,"
-            		+ " account TEXT);");
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-        }
-    }
-}
+/* ownCloud Android client application
+ *   Copyright (C) 2011-2012  Bartek Przybylski
+ *
+ *   This program is free software: you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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.db;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+/**
+ * Custom database helper for ownCloud
+ * 
+ * @author Bartek Przybylski
+ * 
+ */
+public class DbHandler {
+    private SQLiteDatabase mDB;
+    private OpenerHelper mHelper;
+    private final String mDatabaseName = "ownCloud";
+    private final int mDatabaseVersion = 2;
+
+    private final String TABLE_INSTANT_UPLOAD = "instant_upload";
+
+    public static final int UPLOAD_STATUS_UPLOAD_LATER = 0;
+    public static final int UPLOAD_STATUS_UPLOAD_FAILED = 1;
+
+    public DbHandler(Context context) {
+        mHelper = new OpenerHelper(context);
+        mDB = mHelper.getWritableDatabase();
+    }
+
+    public void close() {
+        mDB.close();
+    }
+
+    public boolean putFileForLater(String filepath, String account) {
+        ContentValues cv = new ContentValues();
+        cv.put("path", filepath);
+        cv.put("account", account);
+        cv.put("attempt", UPLOAD_STATUS_UPLOAD_LATER);
+        long result = mDB.insert(TABLE_INSTANT_UPLOAD, null, cv);
+        Log.d(TABLE_INSTANT_UPLOAD, "putFileForLater returns with: " + result + " for file: " + filepath);
+        return result != -1;
+    }
+
+    public int updateFileState(String filepath, Integer status) {
+        ContentValues cv = new ContentValues();
+        cv.put("attempt", status);
+        int result = mDB.update(TABLE_INSTANT_UPLOAD, cv, "path=?", new String[] { filepath });
+        Log.d(TABLE_INSTANT_UPLOAD, "updateFileState returns with: " + result + " for file: " + filepath);
+        return result;
+    }
+
+    public Cursor getAwaitingFiles() {
+        return mDB.query(TABLE_INSTANT_UPLOAD, null, "attempt=" + UPLOAD_STATUS_UPLOAD_LATER, null, null, null, null);
+    }
+
+    public Cursor getFailedFiles() {
+        return mDB.query(TABLE_INSTANT_UPLOAD, null, "attempt>" + UPLOAD_STATUS_UPLOAD_LATER, null, null, null, null);
+    }
+
+    public void clearFiles() {
+        mDB.delete(TABLE_INSTANT_UPLOAD, null, null);
+    }
+
+    /**
+     * 
+     * @param localPath
+     * @return true when one or more pending files was removed
+     */
+    public boolean removeIUPendingFile(String localPath) {
+        long result = mDB.delete(TABLE_INSTANT_UPLOAD, "path = ?", new String[] { localPath });
+        Log.d(TABLE_INSTANT_UPLOAD, "delete returns with: " + result + " for file: " + localPath);
+        return result != 0;
+
+    }
+
+    private class OpenerHelper extends SQLiteOpenHelper {
+        public OpenerHelper(Context context) {
+            super(context, mDatabaseName, null, mDatabaseVersion);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE " + TABLE_INSTANT_UPLOAD + " (" + " _id INTEGER PRIMARY KEY, " + " path TEXT,"
+                    + " account TEXT,attempt INTEGER);");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            db.execSQL("ALTER TABLE " + TABLE_INSTANT_UPLOAD + " ADD COLUMN attempt;");
+
+        }
+    }
+}

+ 45 - 50
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java

@@ -21,11 +21,6 @@ package com.owncloud.android.files;
 
 import java.io.File;
 
-import com.owncloud.android.AccountUtils;
-import com.owncloud.android.authenticator.AccountAuthenticator;
-import com.owncloud.android.db.DbHandler;
-import com.owncloud.android.files.services.FileUploader;
-
 import android.accounts.Account;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -39,16 +34,18 @@ import android.provider.MediaStore.Images.Media;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.DbHandler;
+import com.owncloud.android.files.services.FileUploader;
+
 public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
 
     public static String INSTANT_UPLOAD_DIR = "/InstantUpload/";
     private static String TAG = "PhotoTakenBroadcastReceiver";
-    private static final String[] CONTENT_PROJECTION = { Media.DATA,
-                                                         Media.DISPLAY_NAME,
-                                                         Media.MIME_TYPE,
-                                                         Media.SIZE };
+    private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };
     private static String NEW_PHOTO_ACTION = "com.android.camera.NEW_PICTURE";
-    
+
     @Override
     public void onReceive(Context context, Intent intent) {
         Log.d(TAG, "Received: " + intent.getAction());
@@ -68,8 +65,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         if (intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false)) {
             DbHandler db = new DbHandler(context);
             String localPath = intent.getStringExtra(FileUploader.EXTRA_OLD_FILE_PATH);
-            if (!db.removeIUPendingFile(localPath,
-                                        intent.getStringExtra(FileUploader.ACCOUNT_NAME))) {
+            if (!db.removeIUPendingFile(localPath)) {
                 Log.w(TAG, "Tried to remove non existing instant upload file " + localPath);
             }
             db.close();
@@ -88,10 +84,8 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
             return;
         }
 
-        Cursor c = context.getContentResolver().query(intent.getData(),
-                                                      CONTENT_PROJECTION,
-                                                      null, null, null);
-        
+        Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
+
         if (!c.moveToFirst()) {
             Log.e(TAG, "Couldn't resolve given uri: " + intent.getDataString());
             return;
@@ -102,25 +96,28 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE));
 
         c.close();
-        Log.e(TAG, file_path+"");
-        
-        if (!isOnline(context) ||
-            (instantUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))) {
-            DbHandler db = new DbHandler(context);
-            db.putFileForLater(file_path, account.name);
-            db.close();
+        Log.e(TAG, file_path + "");
+
+        // same always temporally the picture to upload
+        DbHandler db = new DbHandler(context);
+        db.putFileForLater(file_path, account.name);
+        db.close();
+
+        if (!isOnline(context) || (instantUploadViaWiFiOnly(context) && !isConnectedViaWiFi(context))) {
             return;
         }
-        
+
         // register for upload finishe message
-        // there is a litte problem with android API, we can register for particular
-        // intent in registerReceiver but we cannot unregister from precise intent
+        // there is a litte problem with android API, we can register for
+        // particular
+        // intent in registerReceiver but we cannot unregister from precise
+        // intent
         // we can unregister from entire listenings but thats suck a bit.
         // On the other hand this might be only for dynamicly registered
         // broadcast receivers, needs investigation.
         IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
         context.getApplicationContext().registerReceiver(this, filter);
-                
+
         Intent i = new Intent(context, FileUploader.class);
         i.putExtra(FileUploader.KEY_ACCOUNT, account);
         i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
@@ -137,11 +134,10 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
             Log.d(TAG, "Instant upload disabled, abording uploading");
             return;
         }
-        
-        if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY) && 
-            isOnline(context) &&
-             (!instantUploadViaWiFiOnly(context) ||
-              (instantUploadViaWiFiOnly(context) == isConnectedViaWiFi(context) == true)) ) {
+
+        if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY)
+                && isOnline(context)
+                && (!instantUploadViaWiFiOnly(context) || (instantUploadViaWiFiOnly(context) == isConnectedViaWiFi(context) == true))) {
             DbHandler db = new DbHandler(context);
             Cursor c = db.getAwaitingFiles();
             if (c.moveToFirst()) {
@@ -156,16 +152,15 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
 
                         String mimeType = null;
                         try {
-                            mimeType = MimeTypeMap.getSingleton()
-                                    .getMimeTypeFromExtension(
-                                            f.getName().substring(f.getName().lastIndexOf('.') + 1));
-                        
+                            mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
+                                    f.getName().substring(f.getName().lastIndexOf('.') + 1));
+
                         } catch (Throwable e) {
                             Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
                         }
                         if (mimeType == null)
                             mimeType = "application/octet-stream";
-                        
+
                         Intent i = new Intent(context, FileUploader.class);
                         i.putExtra(FileUploader.KEY_ACCOUNT, account);
                         i.putExtra(FileUploader.KEY_LOCAL_FILE, file_path);
@@ -173,35 +168,35 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
                         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
                         i.putExtra(FileUploader.KEY_INSTANT_UPLOAD, true);
                         context.startService(i);
-                        
+
                     } else {
                         Log.w(TAG, "Instant upload file " + f.getAbsolutePath() + " dont exist anymore");
                     }
-                } while(c.moveToNext());
+                } while (c.moveToNext());
             }
             c.close();
             db.close();
         }
-        
+
     }
 
-    private boolean isOnline(Context context) {
+    public static boolean isOnline(Context context) {
         ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
         return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
     }
-    
-    private boolean isConnectedViaWiFi(Context context) {
+
+    public static boolean isConnectedViaWiFi(Context context) {
         ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        return cm != null && cm.getActiveNetworkInfo() != null &&
-               cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI &&
-               cm.getActiveNetworkInfo().getState() == State.CONNECTED;
+        return cm != null && cm.getActiveNetworkInfo() != null
+                && cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI
+                && cm.getActiveNetworkInfo().getState() == State.CONNECTED;
     }
-    
-    private boolean instantUploadEnabled(Context context) {
+
+    public static boolean instantUploadEnabled(Context context) {
         return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false);
     }
-    
-    private boolean instantUploadViaWiFiOnly(Context context) {
+
+    public static boolean instantUploadViaWiFiOnly(Context context) {
         return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_upload_on_wifi", false);
     }
 }

+ 300 - 225
src/com/owncloud/android/files/services/FileUploader.java

@@ -30,24 +30,6 @@ import org.apache.http.HttpStatus;
 import org.apache.jackrabbit.webdav.MultiStatus;
 import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 
-import com.owncloud.android.authenticator.AccountAuthenticator;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.InstantUploadBroadcastReceiver;
-import com.owncloud.android.operations.ChunkedUploadFileOperation;
-import com.owncloud.android.operations.RemoteOperationResult;
-import com.owncloud.android.operations.UploadFileOperation;
-import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
-import com.owncloud.android.ui.activity.FileDetailActivity;
-import com.owncloud.android.ui.fragment.FileDetailFragment;
-import com.owncloud.android.utils.OwnCloudVersion;
-
-import eu.alefzero.webdav.OnDatatransferProgressListener;
-import eu.alefzero.webdav.WebdavEntry;
-import eu.alefzero.webdav.WebdavUtils;
-
-import com.owncloud.android.network.OwnCloudClientUtils;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.app.Notification;
@@ -65,9 +47,28 @@ import android.os.Process;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 import android.widget.RemoteViews;
+import android.widget.Toast;
 
 import com.owncloud.android.R;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.db.DbHandler;
+import com.owncloud.android.files.InstantUploadBroadcastReceiver;
+import com.owncloud.android.network.OwnCloudClientUtils;
+import com.owncloud.android.operations.ChunkedUploadFileOperation;
+import com.owncloud.android.operations.RemoteOperationResult;
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.operations.UploadFileOperation;
+import com.owncloud.android.ui.activity.FileDetailActivity;
+import com.owncloud.android.ui.activity.InstantUploadActivity;
+import com.owncloud.android.ui.fragment.FileDetailFragment;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.OnDatatransferProgressListener;
 import eu.alefzero.webdav.WebdavClient;
+import eu.alefzero.webdav.WebdavEntry;
+import eu.alefzero.webdav.WebdavUtils;
 
 public class FileUploader extends Service implements OnDatatransferProgressListener {
 
@@ -76,20 +77,20 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
     public static final String EXTRA_OLD_REMOTE_PATH = "OLD_REMOTE_PATH";
     public static final String EXTRA_OLD_FILE_PATH = "OLD_FILE_PATH";
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";    
-    
+    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
+
     public static final String KEY_FILE = "FILE";
     public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
     public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
     public static final String KEY_MIME_TYPE = "MIME_TYPE";
 
     public static final String KEY_ACCOUNT = "ACCOUNT";
-    
+
     public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
     public static final String KEY_FORCE_OVERWRITE = "KEY_FORCE_OVERWRITE";
     public static final String KEY_INSTANT_UPLOAD = "INSTANT_UPLOAD";
     public static final String KEY_LOCAL_BEHAVIOUR = "BEHAVIOUR";
-    
+
     public static final int LOCAL_BEHAVIOUR_COPY = 0;
     public static final int LOCAL_BEHAVIOUR_MOVE = 1;
     public static final int LOCAL_BEHAVIOUR_FORGET = 2;
@@ -98,7 +99,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     public static final int UPLOAD_MULTIPLE_FILES = 1;
 
     private static final String TAG = FileUploader.class.getSimpleName();
-    
+
     private Looper mServiceLooper;
     private ServiceHandler mServiceHandler;
     private IBinder mBinder;
@@ -108,18 +109,17 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     private ConcurrentMap<String, UploadFileOperation> mPendingUploads = new ConcurrentHashMap<String, UploadFileOperation>();
     private UploadFileOperation mCurrentUpload = null;
-    
+
     private NotificationManager mNotificationManager;
     private Notification mNotification;
     private int mLastPercent;
     private RemoteViews mDefaultNotificationContentView;
-    
-    
+
     /**
      * Builds a key for mPendingUploads from the account and file to upload
      * 
-     * @param account   Account where the file to download is stored
-     * @param file      File to download
+     * @param account Account where the file to download is stored
+     * @param file File to download
      */
     private String buildRemoteName(Account account, OCFile file) {
         return account.name + file.getRemotePath();
@@ -129,44 +129,44 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         return account.name + remotePath;
     }
 
-    
     /**
      * Checks if an ownCloud server version should support chunked uploads.
      * 
-     * @param version   OwnCloud version instance corresponding to an ownCloud server.
-     * @return          'True' if the ownCloud server with version supports chunked uploads.
+     * @param version OwnCloud version instance corresponding to an ownCloud
+     *            server.
+     * @return 'True' if the ownCloud server with version supports chunked
+     *         uploads.
      */
     private static boolean chunkedUploadIsSupported(OwnCloudVersion version) {
         return (version != null && version.compareTo(OwnCloudVersion.owncloud_v4_5) >= 0);
     }
 
-    
-
     /**
      * Service initialization
      */
     @Override
     public void onCreate() {
         super.onCreate();
+        Log.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        HandlerThread thread = new HandlerThread("FileUploaderThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
+        HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
         mServiceLooper = thread.getLooper();
         mServiceHandler = new ServiceHandler(mServiceLooper, this);
         mBinder = new FileUploaderBinder();
     }
 
-    
     /**
      * Entry point to add one or several files to the queue of uploads.
      * 
-     * New uploads are added calling to startService(), resulting in a call to this method. This ensures the service will keep on working 
-     * although the caller activity goes away.
+     * New uploads are added calling to startService(), resulting in a call to
+     * this method. This ensures the service will keep on working although the
+     * caller activity goes away.
      */
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_UPLOAD_TYPE) || !(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) {
+        if (!intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_UPLOAD_TYPE)
+                || !(intent.hasExtra(KEY_LOCAL_FILE) || intent.hasExtra(KEY_FILE))) {
             Log.e(TAG, "Not enough information provided in intent");
             return Service.START_NOT_STICKY;
         }
@@ -176,25 +176,30 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             return Service.START_NOT_STICKY;
         }
         Account account = intent.getParcelableExtra(KEY_ACCOUNT);
-        
+
         String[] localPaths = null, remotePaths = null, mimeTypes = null;
         OCFile[] files = null;
         if (uploadType == UPLOAD_SINGLE_FILE) {
-            
+
             if (intent.hasExtra(KEY_FILE)) {
-                files = new OCFile[] {intent.getParcelableExtra(KEY_FILE) };
-                
+                files = new OCFile[] { intent.getParcelableExtra(KEY_FILE) };
+
             } else {
                 localPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
                 remotePaths = new String[] { intent.getStringExtra(KEY_REMOTE_FILE) };
                 mimeTypes = new String[] { intent.getStringExtra(KEY_MIME_TYPE) };
             }
-            
+
         } else { // mUploadType == UPLOAD_MULTIPLE_FILES
-            
+
             if (intent.hasExtra(KEY_FILE)) {
-                files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE);    // TODO will this casting work fine?
-                
+                files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE); // TODO
+                                                                             // will
+                                                                             // this
+                                                                             // casting
+                                                                             // work
+                                                                             // fine?
+
             } else {
                 localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
                 remotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
@@ -203,19 +208,24 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         }
 
         FileDataStorageManager storageManager = new FileDataStorageManager(account, getContentResolver());
-        
+
         boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
         boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
         int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_COPY);
         boolean fixed = false;
         if (isInstant) {
-            fixed = checkAndFixInstantUploadDirectory(storageManager);  // MUST be done BEFORE calling obtainNewOCFileToUpload
+            fixed = checkAndFixInstantUploadDirectory(storageManager); // MUST
+                                                                       // be
+                                                                       // done
+                                                                       // BEFORE
+                                                                       // calling
+                                                                       // obtainNewOCFileToUpload
         }
-        
+
         if (intent.hasExtra(KEY_FILE) && files == null) {
             Log.e(TAG, "Incorrect array for OCFiles provided in upload intent");
             return Service.START_NOT_STICKY;
-            
+
         } else if (!intent.hasExtra(KEY_FILE)) {
             if (localPaths == null) {
                 Log.e(TAG, "Incorrect array for local paths provided in upload intent");
@@ -229,63 +239,71 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 Log.e(TAG, "Different number of remote paths and local paths!");
                 return Service.START_NOT_STICKY;
             }
-            
+
             files = new OCFile[localPaths.length];
-            for (int i=0; i < localPaths.length; i++) {
-                files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes!=null)?mimeTypes[i]:(String)null), storageManager);
+            for (int i = 0; i < localPaths.length; i++) {
+                files[i] = obtainNewOCFileToUpload(remotePaths[i], localPaths[i], ((mimeTypes != null) ? mimeTypes[i]
+                        : (String) null), storageManager);
+                if (files[i] == null) {
+                    // TODO @andromaex add failure Notiification
+                    return Service.START_NOT_STICKY;
+                }
             }
         }
-            
-        OwnCloudVersion ocv = new OwnCloudVersion(AccountManager.get(this).getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
+
+        OwnCloudVersion ocv = new OwnCloudVersion(AccountManager.get(this).getUserData(account,
+                AccountAuthenticator.KEY_OC_VERSION));
         boolean chunked = FileUploader.chunkedUploadIsSupported(ocv);
         AbstractList<String> requestedUploads = new Vector<String>();
         String uploadKey = null;
         UploadFileOperation newUpload = null;
         try {
-            for (int i=0; i < files.length; i++) {
+            for (int i = 0; i < files.length; i++) {
                 uploadKey = buildRemoteName(account, files[i].getRemotePath());
                 if (chunked) {
-                    newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction);
+                    newUpload = new ChunkedUploadFileOperation(account, files[i], isInstant, forceOverwrite,
+                            localAction);
                 } else {
                     newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction);
                 }
-                if (fixed && i==0) {
+                if (fixed && i == 0) {
                     newUpload.setRemoteFolderToBeCreated();
                 }
                 mPendingUploads.putIfAbsent(uploadKey, newUpload);
                 newUpload.addDatatransferProgressListener(this);
                 requestedUploads.add(uploadKey);
             }
-            
+
         } catch (IllegalArgumentException e) {
             Log.e(TAG, "Not enough information provided in intent: " + e.getMessage());
             return START_NOT_STICKY;
-            
+
         } catch (IllegalStateException e) {
             Log.e(TAG, "Bad information provided in intent: " + e.getMessage());
             return START_NOT_STICKY;
-            
+
         } catch (Exception e) {
             Log.e(TAG, "Unexpected exception while processing upload intent", e);
             return START_NOT_STICKY;
-            
+
         }
-        
+
         if (requestedUploads.size() > 0) {
             Message msg = mServiceHandler.obtainMessage();
             msg.arg1 = startId;
             msg.obj = requestedUploads;
             mServiceHandler.sendMessage(msg);
         }
-
+        Log.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
         return Service.START_NOT_STICKY;
     }
 
-    
     /**
-     * Provides a binder object that clients can use to perform operations on the queue of uploads, excepting the addition of new files. 
+     * Provides a binder object that clients can use to perform operations on
+     * the queue of uploads, excepting the addition of new files.
      * 
-     * Implemented to perform cancellation, pause and resume of existing uploads.
+     * Implemented to perform cancellation, pause and resume of existing
+     * uploads.
      */
     @Override
     public IBinder onBind(Intent arg0) {
@@ -293,17 +311,18 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     }
 
     /**
-     *  Binder to let client components to perform operations on the queue of uploads.
+     * Binder to let client components to perform operations on the queue of
+     * uploads.
      * 
-     *  It provides by itself the available operations.
+     * It provides by itself the available operations.
      */
     public class FileUploaderBinder extends Binder {
-        
+
         /**
          * Cancels a pending or current upload of a remote file.
          * 
-         * @param account       Owncloud account where the remote file will be stored.
-         * @param file          A file in the queue of pending uploads
+         * @param account Owncloud account where the remote file will be stored.
+         * @param file A file in the queue of pending uploads
          */
         public void cancel(Account account, OCFile file) {
             UploadFileOperation upload = null;
@@ -314,18 +333,20 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 upload.cancel();
             }
         }
-        
-        
+
         /**
-         * Returns True when the file described by 'file' is being uploaded to the ownCloud account 'account' or waiting for it
+         * Returns True when the file described by 'file' is being uploaded to
+         * the ownCloud account 'account' or waiting for it
          * 
-         * If 'file' is a directory, returns 'true' if some of its descendant files is downloading or waiting to download. 
+         * If 'file' is a directory, returns 'true' if some of its descendant
+         * files is downloading or waiting to download.
          * 
-         * @param account       Owncloud account where the remote file will be stored.
-         * @param file          A file that could be in the queue of pending uploads
+         * @param account Owncloud account where the remote file will be stored.
+         * @param file A file that could be in the queue of pending uploads
          */
         public boolean isUploading(Account account, OCFile file) {
-            if (account == null || file == null) return false;
+            if (account == null || file == null)
+                return false;
             String targetKey = buildRemoteName(account, file);
             synchronized (mPendingUploads) {
                 if (file.isDirectory()) {
@@ -342,18 +363,19 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             }
         }
     }
-    
-    
-    
-    
-    /** 
-     * Upload worker. Performs the pending uploads in the order they were requested. 
+
+    /**
+     * Upload worker. Performs the pending uploads in the order they were
+     * requested.
      * 
-     * Created with the Looper of a new thread, started in {@link FileUploader#onCreate()}. 
+     * Created with the Looper of a new thread, started in
+     * {@link FileUploader#onCreate()}.
      */
     private static class ServiceHandler extends Handler {
-        // don't make it a final class, and don't remove the static ; lint will warn about a possible memory leak
+        // don't make it a final class, and don't remove the static ; lint will
+        // warn about a possible memory leak
         FileUploader mService;
+
         public ServiceHandler(Looper looper, FileUploader service) {
             super(looper);
             if (service == null)
@@ -375,66 +397,84 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         }
     }
 
-    
-    
-    
     /**
      * Core upload method: sends the file(s) to upload
      * 
-     * @param uploadKey   Key to access the upload to perform, contained in mPendingUploads
+     * @param uploadKey Key to access the upload to perform, contained in
+     *            mPendingUploads
      */
     public void uploadFile(String uploadKey) {
 
-        synchronized(mPendingUploads) {
+        synchronized (mPendingUploads) {
             mCurrentUpload = mPendingUploads.get(uploadKey);
         }
-        
+
         if (mCurrentUpload != null) {
-            
+
             notifyUploadStart(mCurrentUpload);
 
-            
-            /// prepare client object to send requests to the ownCloud server
+            // / prepare client object to send requests to the ownCloud server
             if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
                 mLastAccount = mCurrentUpload.getAccount();
                 mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
                 mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
             }
-            
-            /// create remote folder for instant uploads
+
+            // / create remote folder for instant uploads
             if (mCurrentUpload.isRemoteFolderToBeCreated()) {
-                mUploadClient.createDirectory(InstantUploadBroadcastReceiver.INSTANT_UPLOAD_DIR);    // ignoring result; fail could just mean that it already exists, but local database is not synchronized; the upload will be tried anyway
+                mUploadClient.createDirectory(InstantUploadBroadcastReceiver.INSTANT_UPLOAD_DIR); // ignoring
+                                                                                                  // result;
+                                                                                                  // fail
+                                                                                                  // could
+                                                                                                  // just
+                                                                                                  // mean
+                                                                                                  // that
+                                                                                                  // it
+                                                                                                  // already
+                                                                                                  // exists,
+                                                                                                  // but
+                                                                                                  // local
+                                                                                                  // database
+                                                                                                  // is
+                                                                                                  // not
+                                                                                                  // synchronized;
+                                                                                                  // the
+                                                                                                  // upload
+                                                                                                  // will
+                                                                                                  // be
+                                                                                                  // tried
+                                                                                                  // anyway
             }
 
-            
-            /// perform the upload
+            // / perform the upload
             RemoteOperationResult uploadResult = null;
             try {
                 uploadResult = mCurrentUpload.execute(mUploadClient);
                 if (uploadResult.isSuccess()) {
                     saveUploadedFile();
                 }
-                
+
             } finally {
-                synchronized(mPendingUploads) {
+                synchronized (mPendingUploads) {
                     mPendingUploads.remove(uploadKey);
+                    Log.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
                 }
             }
-        
-            /// notify result
+
+            // notify result
             notifyUploadResult(uploadResult, mCurrentUpload);
-            
             sendFinalBroadcast(mCurrentUpload, uploadResult);
-            
+
         }
-        
+
     }
 
     /**
      * Saves a OC File after a successful upload.
      * 
-     * A PROPFIND is necessary to keep the props in the local database synchronized with the server, 
-     * specially the modification time and Etag (where available)
+     * A PROPFIND is necessary to keep the props in the local database
+     * synchronized with the server, specially the modification time and Etag
+     * (where available)
      * 
      * TODO refactor this ugly thing
      */
@@ -442,94 +482,107 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         OCFile file = mCurrentUpload.getFile();
         long syncDate = System.currentTimeMillis();
         file.setLastSyncDateForData(syncDate);
-        
-        /// new PROPFIND to keep data consistent with server in theory, should return the same we already have
+
+        // / new PROPFIND to keep data consistent with server in theory, should
+        // return the same we already have
         PropFindMethod propfind = null;
         RemoteOperationResult result = null;
         try {
-          propfind = new PropFindMethod(mUploadClient.getBaseUri() + WebdavUtils.encodePath(mCurrentUpload.getRemotePath()));
-          int status = mUploadClient.executeMethod(propfind);
-          boolean isMultiStatus = (status == HttpStatus.SC_MULTI_STATUS);
-          if (isMultiStatus) {
-              MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
-              WebdavEntry we = new WebdavEntry(resp.getResponses()[0],
-                                               mUploadClient.getBaseUri().getPath());
-              updateOCFile(file, we);
-              file.setLastSyncDateForProperties(syncDate);
-              
-          } else {
-              mUploadClient.exhaustResponse(propfind.getResponseBodyAsStream());
-          }
-          
-          result = new RemoteOperationResult(isMultiStatus, status);
-          Log.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " + result.getLogMessage());
-          
+            propfind = new PropFindMethod(mUploadClient.getBaseUri()
+                    + WebdavUtils.encodePath(mCurrentUpload.getRemotePath()));
+            int status = mUploadClient.executeMethod(propfind);
+            boolean isMultiStatus = (status == HttpStatus.SC_MULTI_STATUS);
+            if (isMultiStatus) {
+                MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
+                WebdavEntry we = new WebdavEntry(resp.getResponses()[0], mUploadClient.getBaseUri().getPath());
+                updateOCFile(file, we);
+                file.setLastSyncDateForProperties(syncDate);
+
+            } else {
+                mUploadClient.exhaustResponse(propfind.getResponseBodyAsStream());
+            }
+
+            result = new RemoteOperationResult(isMultiStatus, status);
+            Log.i(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": "
+                    + result.getLogMessage());
+
         } catch (Exception e) {
             result = new RemoteOperationResult(e);
-            Log.e(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": " + result.getLogMessage(), e);
+            Log.e(TAG, "Update: synchronizing properties for uploaded " + mCurrentUpload.getRemotePath() + ": "
+                    + result.getLogMessage(), e);
 
         } finally {
             if (propfind != null)
                 propfind.releaseConnection();
         }
 
-        /// maybe this would be better as part of UploadFileOperation... or maybe all this method
+        // / maybe this would be better as part of UploadFileOperation... or
+        // maybe all this method
         if (mCurrentUpload.wasRenamed()) {
             OCFile oldFile = mCurrentUpload.getOldFile();
             if (oldFile.fileExists()) {
                 oldFile.setStoragePath(null);
                 mStorageManager.saveFile(oldFile);
-                
-            } // else: it was just an automatic renaming due to a name coincidence; nothing else is needed, the storagePath is right in the instance returned by mCurrentUpload.getFile()
+
+            } // else: it was just an automatic renaming due to a name
+              // coincidence; nothing else is needed, the storagePath is right
+              // in the instance returned by mCurrentUpload.getFile()
         }
-        
+
         mStorageManager.saveFile(file);
     }
 
-    
     private void updateOCFile(OCFile file, WebdavEntry we) {
         file.setCreationTimestamp(we.createTimestamp());
         file.setFileLength(we.contentLength());
         file.setMimetype(we.contentType());
         file.setModificationTimestamp(we.modifiedTimestamp());
         file.setModificationTimestampAtLastSyncForData(we.modifiedTimestamp());
-        // file.setEtag(mCurrentDownload.getEtag());    // TODO Etag, where available
+        // file.setEtag(mCurrentDownload.getEtag()); // TODO Etag, where
+        // available
     }
-    
-    
+
     private boolean checkAndFixInstantUploadDirectory(FileDataStorageManager storageManager) {
         OCFile instantUploadDir = storageManager.getFileByPath(InstantUploadBroadcastReceiver.INSTANT_UPLOAD_DIR);
         if (instantUploadDir == null) {
-            // first instant upload in the account, or never account not synchronized after the remote InstantUpload folder was created
+            // first instant upload in the account, or never account not
+            // synchronized after the remote InstantUpload folder was created
             OCFile newDir = new OCFile(InstantUploadBroadcastReceiver.INSTANT_UPLOAD_DIR);
             newDir.setMimetype("DIR");
-            newDir.setParentId(storageManager.getFileByPath(OCFile.PATH_SEPARATOR).getFileId());
-            storageManager.saveFile(newDir);
-            return true;
+            OCFile path = storageManager.getFileByPath(OCFile.PATH_SEPARATOR);
+
+            if (path != null) {
+                newDir.setParentId(path.getFileId());
+                storageManager.saveFile(newDir);
+                return true;
+            } else {
+                return false;
+            }
+
         }
         return false;
     }
 
-    
-    private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType, FileDataStorageManager storageManager) {
+    private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
+            FileDataStorageManager storageManager) {
         OCFile newFile = new OCFile(remotePath);
         newFile.setStoragePath(localPath);
         newFile.setLastSyncDateForProperties(0);
         newFile.setLastSyncDateForData(0);
-        
+
         // size
         if (localPath != null && localPath.length() > 0) {
             File localFile = new File(localPath);
             newFile.setFileLength(localFile.length());
             newFile.setLastSyncDateForData(localFile.lastModified());
-        }   // don't worry about not assigning size, the problems with localPath are checked when the UploadFileOperation instance is created
-        
+        } // don't worry about not assigning size, the problems with localPath
+          // are checked when the UploadFileOperation instance is created
+
         // MIME type
         if (mimeType == null || mimeType.length() <= 0) {
             try {
-                mimeType = MimeTypeMap.getSingleton()
-                    .getMimeTypeFromExtension(
-                            remotePath.substring(remotePath.lastIndexOf('.') + 1));
+                mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
+                        remotePath.substring(remotePath.lastIndexOf('.') + 1));
             } catch (IndexOutOfBoundsException e) {
                 Log.e(TAG, "Trying to find out MIME type of a file without extension: " + remotePath);
             }
@@ -538,53 +591,62 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             mimeType = "application/octet-stream";
         }
         newFile.setMimetype(mimeType);
-        
+
         // parent dir
         String parentPath = new File(remotePath).getParent();
-        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR ;
+        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
         OCFile parentDir = storageManager.getFileByPath(parentPath);
         if (parentDir == null) {
-            throw new IllegalStateException("Can not upload a file to a non existing remote location: " + parentPath);
+            Toast t = Toast
+                    .makeText(
+                            getApplicationContext(),
+                            "The first time the InstantUpload is running you must be online, so the target folder can successfully created by the upload process",
+                            30);
+            t.show();
+            return null;
         }
         long parentDirId = parentDir.getFileId();
         newFile.setParentId(parentDirId);
         return newFile;
     }
-    
 
     /**
      * Creates a status notification to show the upload progress
      * 
-     * @param upload    Upload operation starting.
+     * @param upload Upload operation starting.
      */
     private void notifyUploadStart(UploadFileOperation upload) {
-        /// create status notification with a progress bar
+        // / create status notification with a progress bar
         mLastPercent = 0;
-        mNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_in_progress_ticker), System.currentTimeMillis());
+        mNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_in_progress_ticker),
+                System.currentTimeMillis());
         mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
         mDefaultNotificationContentView = mNotification.contentView;
-        mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
+        mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(),
+                R.layout.progressbar_layout);
         mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
-        mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName()));
+        mNotification.contentView.setTextViewText(R.id.status_text,
+                String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName()));
         mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
-        
-        /// includes a pending intent in the notification showing the details view of the file
+
+        // / includes a pending intent in the notification showing the details
+        // view of the file
         Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
         showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, upload.getFile());
         showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, upload.getAccount());
         showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), showDetailsIntent, 0);
-        
+        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(),
+                (int) System.currentTimeMillis(), showDetailsIntent, 0);
+
         mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
     }
 
-    
     /**
      * Callback method to update the progress bar in the status notification
      */
     @Override
     public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileName) {
-        int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer));
+        int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
         if (percent != mLastPercent) {
             mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, false);
             String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName);
@@ -593,98 +655,112 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         }
         mLastPercent = percent;
     }
-    
-    
+
     /**
-     * Callback method to update the progress bar in the status notification  (old version)
+     * Callback method to update the progress bar in the status notification
+     * (old version)
      */
     @Override
     public void onTransferProgress(long progressRate) {
         // NOTHING TO DO HERE ANYMORE
     }
 
-    
     /**
      * Updates the status notification with the result of an upload operation.
      * 
-     * @param uploadResult    Result of the upload operation.
-     * @param upload          Finished upload operation
+     * @param uploadResult Result of the upload operation.
+     * @param upload Finished upload operation
      */
     private void notifyUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
+        Log.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
         if (uploadResult.isCancelled()) {
-            /// cancelled operation -> silent removal of progress notification
+            // / cancelled operation -> silent removal of progress notification
             mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
-            
+
         } else if (uploadResult.isSuccess()) {
-            /// success -> silent update of progress notification to success message 
-            mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove the ongoing flag
+            // / success -> silent update of progress notification to success
+            // message
+            mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove
+                                                                    // the
+                                                                    // ongoing
+                                                                    // flag
             mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
             mNotification.contentView = mDefaultNotificationContentView;
-            
-            /// includes a pending intent in the notification showing the details view of the file
+
+            // / includes a pending intent in the notification showing the
+            // details view of the file
             Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
             showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, upload.getFile());
             showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, upload.getAccount());
             showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), showDetailsIntent, 0);
-            
-            mNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                getString(R.string.uploader_upload_succeeded_ticker), 
-                                                String.format(getString(R.string.uploader_upload_succeeded_content_single), upload.getFileName()), 
-                                                mNotification.contentIntent);
-            
-            mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);    // NOT AN ERROR; uploader_upload_in_progress_ticker is the target, not a new notification
-            
-            /* Notification about multiple uploads: pending of update
-            mNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                    getString(R.string.uploader_upload_succeeded_ticker), 
-                                                    String.format(getString(R.string.uploader_upload_succeeded_content_multiple), mSuccessCounter), 
-                                                    mNotification.contentIntent);
-             */
-            
+            mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(),
+                    (int) System.currentTimeMillis(), showDetailsIntent, 0);
+
+            mNotification.setLatestEventInfo(getApplicationContext(),
+                    getString(R.string.uploader_upload_succeeded_ticker),
+                    String.format(getString(R.string.uploader_upload_succeeded_content_single), upload.getFileName()),
+                    mNotification.contentIntent);
+
+            mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); // NOT
+                                                                                                     // AN
+            DbHandler db = new DbHandler(this.getBaseContext());
+            db.removeIUPendingFile(mCurrentUpload.getFile().getStoragePath());
+            db.close();
+
         } else {
-            /// fail -> explicit failure notification
+
+            // / fail -> explicit failure notification
             mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
-            Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis());
+            Notification finalNotification = new Notification(R.drawable.icon,
+                    getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis());
             finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
-            // TODO put something smart in the contentIntent below
-            finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0);
-            
-            String content = null; 
-            if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL ||
-                uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
-                // TODO we need a class to provide error messages for the users from a RemoteOperationResult and a RemoteOperation 
-                content = String.format(getString(R.string.error__upload__local_file_not_copied), upload.getFileName(), getString(R.string.app_name));
+
+            Intent detailUploudIntent = new Intent(this, InstantUploadActivity.class);
+            detailUploudIntent.putExtra(FileUploader.KEY_ACCOUNT, upload.getAccount());
+            finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(),
+                    (int) System.currentTimeMillis(), detailUploudIntent, PendingIntent.FLAG_UPDATE_CURRENT
+                            | PendingIntent.FLAG_ONE_SHOT);
+
+            String content = null;
+            if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL
+                    || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) {
+                // TODO we need a class to provide error messages for the users
+                // from a RemoteOperationResult and a RemoteOperation
+                content = String.format(getString(R.string.error__upload__local_file_not_copied), upload.getFileName(),
+                        getString(R.string.app_name));
             } else {
-                content = String.format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
+                content = String
+                        .format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName());
             }
-            finalNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                    getString(R.string.uploader_upload_failed_ticker), 
-                                                    content, 
-                                                    finalNotification.contentIntent);
-            
+            finalNotification.setLatestEventInfo(getApplicationContext(),
+                    getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent);
+
             mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
-            
-            /* Notification about multiple uploads failure: pending of update
-            finalNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                        getString(R.string.uploader_upload_failed_ticker), 
-                                                        String.format(getString(R.string.uploader_upload_failed_content_multiple), mSuccessCounter, mTotalFilesToSend), 
-                                                        finalNotification.contentIntent);
-            } */                
+
+            DbHandler db = new DbHandler(this.getBaseContext());
+            if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED) == 0) {
+                db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name);
+            }
+            db.close();
+
         }
-        
+
     }
-    
-    
+
     /**
-     * Sends a broadcast in order to the interested activities can update their view
+     * Sends a broadcast in order to the interested activities can update their
+     * view
      * 
-     * @param upload          Finished upload operation
-     * @param uploadResult    Result of the upload operation
+     * @param upload Finished upload operation
+     * @param uploadResult Result of the upload operation
      */
     private void sendFinalBroadcast(UploadFileOperation upload, RemoteOperationResult uploadResult) {
         Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
-        end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath());    // real remote path, after possible automatic renaming
+        end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
+                                                                 // path, after
+                                                                 // possible
+                                                                 // automatic
+                                                                 // renaming
         if (upload.wasRenamed()) {
             end.putExtra(EXTRA_OLD_REMOTE_PATH, upload.getOldFile().getRemotePath());
         }
@@ -694,5 +770,4 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         sendStickyBroadcast(end);
     }
 
-
 }

+ 8 - 8
src/com/owncloud/android/files/services/InstantUploadService.java

@@ -40,22 +40,22 @@ public class InstantUploadService extends Service {
     public static String KEY_MIME_TYPE = "KEY_MIMETYPE";
     public static String KEY_DISPLAY_NAME = "KEY_FILENAME";
     public static String KEY_ACCOUNT = "KEY_ACCOUNT";
-    
+
     private static String TAG = "InstantUploadService";
-    private static String INSTANT_UPLOAD_DIR = "/InstantUpload";
+    // TODO make it configurable over the settings dialog
+    public static String INSTANT_UPLOAD_DIR = "/InstantUpload";
     private UploaderRunnable mUploaderRunnable;
-    
+
     @Override
     public IBinder onBind(Intent arg0) {
         return null;
     }
-    
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        if (intent == null ||
-            !intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_DISPLAY_NAME) ||
-            !intent.hasExtra(KEY_FILE_PATH) || !intent.hasExtra(KEY_FILE_SIZE) ||
-            !intent.hasExtra(KEY_MIME_TYPE)) {
+        if (intent == null || !intent.hasExtra(KEY_ACCOUNT) || !intent.hasExtra(KEY_DISPLAY_NAME)
+                || !intent.hasExtra(KEY_FILE_PATH) || !intent.hasExtra(KEY_FILE_SIZE)
+                || !intent.hasExtra(KEY_MIME_TYPE)) {
             Log.w(TAG, "Not all required information was provided, abording");
             return Service.START_NOT_STICKY;
         }

+ 1309 - 1288
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -1,1288 +1,1309 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *   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 as published by
- *   the Free Software Foundation, either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   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 java.io.File;
-
-import android.accounts.Account;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.app.AlertDialog.Builder;
-import android.app.Dialog;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.SharedPreferences;
-import android.content.SharedPreferences.Editor;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources.NotFoundException;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore;
-import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.EditText;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuInflater;
-import com.actionbarsherlock.view.MenuItem;
-import com.actionbarsherlock.view.Window;
-import com.owncloud.android.AccountUtils;
-import com.owncloud.android.authenticator.AccountAuthenticator;
-import com.owncloud.android.datamodel.DataStorageManager;
-import com.owncloud.android.datamodel.FileDataStorageManager;
-import com.owncloud.android.datamodel.OCFile;
-import com.owncloud.android.files.services.FileDownloader;
-import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
-import com.owncloud.android.files.services.FileObserverService;
-import com.owncloud.android.files.services.FileUploader;
-import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
-import com.owncloud.android.network.OwnCloudClientUtils;
-import com.owncloud.android.operations.OnRemoteOperationListener;
-import com.owncloud.android.operations.RemoteOperation;
-import com.owncloud.android.operations.RemoteOperationResult;
-import com.owncloud.android.operations.RemoveFileOperation;
-import com.owncloud.android.operations.RenameFileOperation;
-import com.owncloud.android.operations.SynchronizeFileOperation;
-import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
-import com.owncloud.android.syncadapter.FileSyncService;
-import com.owncloud.android.ui.dialog.ChangelogDialog;
-import com.owncloud.android.ui.dialog.SslValidatorDialog;
-import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;
-import com.owncloud.android.ui.fragment.FileDetailFragment;
-import com.owncloud.android.ui.fragment.OCFileListFragment;
-
-import com.owncloud.android.R;
-import eu.alefzero.webdav.WebdavClient;
-
-/**
- * Displays, what files the user has available in his ownCloud.
- * 
- * @author Bartek Przybylski
- * 
- */
-
-public class FileDisplayActivity extends SherlockFragmentActivity implements
-    OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener, OnRemoteOperationListener {
-    
-    private ArrayAdapter<String> mDirectories;
-    private OCFile mCurrentDir = null;
-    private OCFile mCurrentFile = null;
-
-    private DataStorageManager mStorageManager;
-    private SyncBroadcastReceiver mSyncBroadcastReceiver;
-    private UploadFinishReceiver mUploadFinishReceiver;
-    private DownloadFinishReceiver mDownloadFinishReceiver;
-    private FileDownloaderBinder mDownloaderBinder = null;
-    private FileUploaderBinder mUploaderBinder = null;
-    private ServiceConnection mDownloadConnection = null, mUploadConnection = null;
-    private RemoteOperationResult mLastSslUntrustedServerResult = null;
-    
-    private OCFileListFragment mFileList;
-    
-    private boolean mDualPane;
-    
-    private static final int DIALOG_SETUP_ACCOUNT = 0;
-    private static final int DIALOG_CREATE_DIR = 1;
-    private static final int DIALOG_ABOUT_APP = 2;
-    public static final int DIALOG_SHORT_WAIT = 3;
-    private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 4;
-    private static final int DIALOG_SSL_VALIDATOR = 5;
-    private static final int DIALOG_CERT_NOT_SAVED = 6;
-    private static final String DIALOG_CHANGELOG_TAG = "DIALOG_CHANGELOG";
-
-    
-    private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
-    private static final int ACTION_SELECT_MULTIPLE_FILES = 2;
-    
-    private static final String TAG = "FileDisplayActivity";
-
-    private static int[] mMenuIdentifiersToPatch = {R.id.about_app};
-    
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        Log.d(getClass().toString(), "onCreate() start");
-        super.onCreate(savedInstanceState);
-
-        /// Load of parameters from received intent
-        mCurrentDir = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE); // no check necessary, mCurrenDir == null if the parameter is not in the intent
-        Account account = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
-        if (account != null)
-            AccountUtils.setCurrentOwnCloudAccount(this, account.name);
-        
-        /// Load of saved instance state: keep this always before initDataFromCurrentAccount()
-        if(savedInstanceState != null) {
-            // TODO - test if savedInstanceState should take precedence over file in the intent ALWAYS (now), NEVER, or SOME TIMES
-            mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
-        }
-        
-        if (!AccountUtils.accountsAreSetup(this)) {
-            /// no account available: FORCE ACCOUNT CREATION
-            mStorageManager = null;
-            createFirstAccount();
-            
-        } else {    /// at least an account is available
-            
-            initDataFromCurrentAccount();   // it checks mCurrentDir and mCurrentFile with the current account
-            
-        }
-        
-        mUploadConnection = new ListServiceConnection(); 
-        mDownloadConnection = new ListServiceConnection();
-        bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
-        bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
-
-        // PIN CODE request ;  best location is to decide, let's try this first
-        if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
-            requestPinCode();
-        }
-
-        // file observer
-        Intent observer_intent = new Intent(this, FileObserverService.class);
-        observer_intent.putExtra(FileObserverService.KEY_FILE_CMD, FileObserverService.CMD_INIT_OBSERVED_LIST);
-        startService(observer_intent);
-        
-            
-        /// USER INTERFACE
-        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-            
-        // Drop-down navigation 
-        mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
-        OCFile currFile = mCurrentDir;
-        while(currFile != null && currFile.getFileName() != OCFile.PATH_SEPARATOR) {
-            mDirectories.add(currFile.getFileName());
-            currFile = mStorageManager.getFileById(currFile.getParentId());
-        }
-        mDirectories.add(OCFile.PATH_SEPARATOR);
-
-        // Inflate and set the layout view
-        setContentView(R.layout.files);    
-        mFileList = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
-        mDualPane = (findViewById(R.id.file_details_container) != null);
-        if (mDualPane) {
-            initFileDetailsInDualPane();
-        }
-            
-        // Action bar setup
-        ActionBar actionBar = getSupportActionBar();
-        actionBar.setHomeButtonEnabled(true);   // mandatory since Android ICS, according to the official documentation
-        actionBar.setDisplayHomeAsUpEnabled(mCurrentDir != null && mCurrentDir.getParentId() != 0);
-        actionBar.setDisplayShowTitleEnabled(false);
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
-        actionBar.setListNavigationCallbacks(mDirectories, this);
-        setSupportProgressBarIndeterminateVisibility(false);        // always AFTER setContentView(...) ; to workaround bug in its implementation
-        
-        
-        // show changelog, if needed
-        showChangeLog();
-        
-        Log.d(getClass().toString(), "onCreate() end");
-    }
-
-    
-    /**
-     * Shows a dialog with the change log of the current version after each app update
-     * 
-     *  TODO make it permanent; by now, only to advice the workaround app for 4.1.x
-     */
-    private void showChangeLog() {
-        if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.JELLY_BEAN) {
-            final String KEY_VERSION = "version";
-            SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-            int currentVersionNumber = 0;
-            int savedVersionNumber = sharedPref.getInt(KEY_VERSION, 0);
-            try {
-                PackageInfo pi          = getPackageManager().getPackageInfo(getPackageName(), 0);
-                currentVersionNumber    = pi.versionCode;
-            } catch (Exception e) {}
-     
-            if (currentVersionNumber > savedVersionNumber) {
-                ChangelogDialog.newInstance(true).show(getSupportFragmentManager(), DIALOG_CHANGELOG_TAG);
-                Editor editor   = sharedPref.edit();
-                editor.putInt(KEY_VERSION, currentVersionNumber);
-                editor.commit();
-            }
-        }
-    }
-    
-
-    /**
-     * Launches the account creation activity. To use when no ownCloud account is available
-     */
-    private void createFirstAccount() {
-        Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
-        intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
-        startActivity(intent);  // the new activity won't be created until this.onStart() and this.onResume() are finished;
-    }
-
-
-    /**
-     *  Load of state dependent of the existence of an ownCloud account
-     */
-    private void initDataFromCurrentAccount() {
-        /// Storage manager initialization - access to local database
-        mStorageManager = new FileDataStorageManager(
-                AccountUtils.getCurrentOwnCloudAccount(this),
-                getContentResolver());
-
-        /// Check if mCurrentDir is a directory
-        if(mCurrentDir != null && !mCurrentDir.isDirectory()) {
-            mCurrentFile = mCurrentDir;
-            mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());
-        }
-        
-        /// Check if mCurrentDir and mCurrentFile are in the current account, and update them
-        if (mCurrentDir != null) {
-            mCurrentDir = mStorageManager.getFileByPath(mCurrentDir.getRemotePath());   // mCurrentDir == null if it is not in the current account
-        }
-        if (mCurrentFile != null) {
-            if (mCurrentFile.fileExists()) {
-                mCurrentFile = mStorageManager.getFileByPath(mCurrentFile.getRemotePath());   // mCurrentFile == null if it is not in the current account
-            }   // else : keep mCurrentFile with the received value; this is currently the case of an upload in progress, when the user presses the status notification in a landscape tablet
-        }
-        
-        /// Default to root if mCurrentDir was not found
-        if (mCurrentDir == null) {
-            mCurrentDir = mStorageManager.getFileByPath("/"); // will be NULL if the database was never synchronized
-        }
-    }
-        
-    
-    private void initFileDetailsInDualPane() {
-        if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {
-            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-            if (mCurrentFile != null) {
-                transaction.replace(R.id.file_details_container, new FileDetailFragment(mCurrentFile, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG); // empty FileDetailFragment
-                mCurrentFile = null;
-            } else {
-                transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null), FileDetailFragment.FTAG); // empty FileDetailFragment
-            }
-            transaction.commit();
-        }
-    }
-    
-    
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        if (mDownloadConnection != null)
-            unbindService(mDownloadConnection);
-        if (mUploadConnection != null)
-            unbindService(mUploadConnection);
-    }
-
-    
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getSherlock().getMenuInflater();
-            inflater.inflate(R.menu.menu, menu);
-            
-            patchHiddenAccents(menu);
-            
-            return true;
-    }
-
-    /**
-     * Workaround for this: <a href="http://code.google.com/p/android/issues/detail?id=3974">http://code.google.com/p/android/issues/detail?id=3974</a> 
-     * 
-     * @param menu      Menu to patch
-     */
-    private void patchHiddenAccents(Menu menu) {
-        for (int i = 0; i < mMenuIdentifiersToPatch.length ; i++) {
-            MenuItem aboutItem = menu.findItem(mMenuIdentifiersToPatch[i]);
-            if (aboutItem != null && aboutItem.getIcon() instanceof BitmapDrawable) {
-                // Clip off the bottom three (density independent) pixels of transparent padding
-                Bitmap original = ((BitmapDrawable) aboutItem.getIcon()).getBitmap();
-                float scale = getResources().getDisplayMetrics().density;
-                int clippedHeight = (int) (original.getHeight() - (3 * scale));
-                Bitmap scaled = Bitmap.createBitmap(original, 0, 0, original.getWidth(), clippedHeight);
-                aboutItem.setIcon(new BitmapDrawable(getResources(), scaled));
-            }
-        }
-    }
-
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        boolean retval = true;
-        switch (item.getItemId()) {
-            case R.id.createDirectoryItem: {
-                showDialog(DIALOG_CREATE_DIR);
-                break;
-            }
-            case R.id.startSync: {
-                startSynchronization();
-                break;
-            }
-            case R.id.action_upload: {
-                showDialog(DIALOG_CHOOSE_UPLOAD_SOURCE);
-                break;
-            }
-            case R.id.action_settings: {
-                Intent settingsIntent = new Intent(this, Preferences.class);
-                startActivity(settingsIntent);
-                break;
-            }
-            case R.id.about_app : {
-                showDialog(DIALOG_ABOUT_APP);
-                break;
-            }
-            case android.R.id.home: {
-                if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
-                    onBackPressed(); 
-                }
-                break;
-            }
-            default:
-                retval = super.onOptionsItemSelected(item);
-        }
-        return retval;
-    }
-
-    private void startSynchronization() {
-        ContentResolver.cancelSync(null, AccountAuthenticator.AUTH_TOKEN_TYPE);   // cancel the current synchronizations of any ownCloud account
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
-        ContentResolver.requestSync(
-                AccountUtils.getCurrentOwnCloudAccount(this),
-                AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
-    }
-
-
-    @Override
-    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
-        int i = itemPosition;
-        while (i-- != 0) {
-            onBackPressed();
-        }
-        // the next operation triggers a new call to this method, but it's necessary to 
-        // ensure that the name exposed in the action bar is the current directory when the 
-        // user selected it in the navigation list
-        if (itemPosition != 0)
-            getSupportActionBar().setSelectedNavigationItem(0);
-        return true;
-    }
-
-    /**
-     * Called, when the user selected something for uploading
-     */
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        
-        if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
-            requestSimpleUpload(data, resultCode);
-            
-        } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
-            requestMultipleUpload(data, resultCode);
-            
-        }
-    }
-
-    private void requestMultipleUpload(Intent data, int resultCode) {
-        String[] filePaths = data.getStringArrayExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES);
-        if (filePaths != null) {
-            String[] remotePaths = new String[filePaths.length];
-            String remotePathBase = "";
-            for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
-                remotePathBase += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
-            }
-            if (!remotePathBase.endsWith(OCFile.PATH_SEPARATOR))
-                remotePathBase += OCFile.PATH_SEPARATOR;
-            for (int j = 0; j< remotePaths.length; j++) {
-                remotePaths[j] = remotePathBase + (new File(filePaths[j])).getName();
-            }
-
-            Intent i = new Intent(this, FileUploader.class);
-            i.putExtra(FileUploader.KEY_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
-            i.putExtra(FileUploader.KEY_LOCAL_FILE, filePaths);
-            i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePaths);
-            i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
-            if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
-                i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
-            startService(i);
-            
-        } else {
-            Log.d("FileDisplay", "User clicked on 'Update' with no selection");
-            Toast t = Toast.makeText(this, getString(R.string.filedisplay_no_file_selected), Toast.LENGTH_LONG);
-            t.show();
-            return;
-        }
-    }
-
-
-    private void requestSimpleUpload(Intent data, int resultCode) {
-        String filepath = null;
-        try {
-            Uri selectedImageUri = data.getData();
-
-            String filemanagerstring = selectedImageUri.getPath();
-            String selectedImagePath = getPath(selectedImageUri);
-
-            if (selectedImagePath != null)
-                filepath = selectedImagePath;
-            else
-                filepath = filemanagerstring;
-            
-        } catch (Exception e) {
-            Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
-            e.printStackTrace();
-            
-        } finally {
-            if (filepath == null) {
-                Log.e("FileDisplay", "Couldnt resolve path to file");
-                Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
-                t.show();
-                return;
-            }
-        }
-
-        Intent i = new Intent(this, FileUploader.class);
-        i.putExtra(FileUploader.KEY_ACCOUNT,
-                AccountUtils.getCurrentOwnCloudAccount(this));
-        String remotepath = new String();
-        for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
-            remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
-        }
-        if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
-            remotepath += OCFile.PATH_SEPARATOR;
-        remotepath += new File(filepath).getName();
-
-        i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
-        i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
-        i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
-        if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
-            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
-        startService(i);
-    }
-
-
-    @Override
-    public void onBackPressed() {
-        if (mDirectories.getCount() <= 1) {
-            finish();
-            return;
-        }
-        popDirname();
-        mFileList.onNavigateUp();
-        mCurrentDir = mFileList.getCurrentFile();
-        
-        if (mDualPane) {
-            // Resets the FileDetailsFragment on Tablets so that it always displays
-            FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-            if (fileDetails != null && !fileDetails.isEmpty()) {
-                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-                transaction.remove(fileDetails);
-                transaction.add(R.id.file_details_container, new FileDetailFragment(null, null), FileDetailFragment.FTAG);
-                transaction.commit();
-            }
-        }
-        
-        if(mCurrentDir.getParentId() == 0){
-            ActionBar actionBar = getSupportActionBar(); 
-            actionBar.setDisplayHomeAsUpEnabled(false);
-        } 
-    }
-
-    @Override
-    protected void onSaveInstanceState(Bundle outState) {
-        // responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
-        Log.d(getClass().toString(), "onSaveInstanceState() start");
-        super.onSaveInstanceState(outState);
-        outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);
-        if (mDualPane) {
-            FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-            if (fragment != null) {
-                OCFile file = fragment.getDisplayedFile();
-                if (file != null) {
-                    outState.putParcelable(FileDetailFragment.EXTRA_FILE, file);
-                }
-            }
-        }
-        Log.d(getClass().toString(), "onSaveInstanceState() end");
-    }
-
-    @Override
-    protected void onResume() {
-        Log.d(getClass().toString(), "onResume() start");
-        super.onResume();
-
-        if (AccountUtils.accountsAreSetup(this)) {
-            
-            if (mStorageManager == null) {
-                // this is necessary for handling the come back to FileDisplayActivity when the first ownCloud account is created 
-                initDataFromCurrentAccount();
-                if (mDualPane) {
-                    initFileDetailsInDualPane();
-                }
-            }
-            
-            // Listen for sync messages
-            IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);
-            mSyncBroadcastReceiver = new SyncBroadcastReceiver();
-            registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
-            
-            // Listen for upload messages
-            IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
-            mUploadFinishReceiver = new UploadFinishReceiver();
-            registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
-            
-            // Listen for download messages
-            IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
-            mDownloadFinishReceiver = new DownloadFinishReceiver();
-            registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
-        
-            // List current directory
-            mFileList.listDirectory(mCurrentDir);   // TODO we should find the way to avoid the need of this (maybe it's not necessary yet; to check)
-            
-        } else {
-            
-            mStorageManager = null;     // an invalid object will be there if all the ownCloud accounts are removed
-            showDialog(DIALOG_SETUP_ACCOUNT);
-            
-        }
-        Log.d(getClass().toString(), "onResume() end");
-    }
-
-    
-    @Override
-    protected void onPause() {
-        Log.d(getClass().toString(), "onPause() start");
-        super.onPause();
-        if (mSyncBroadcastReceiver != null) {
-            unregisterReceiver(mSyncBroadcastReceiver);
-            mSyncBroadcastReceiver = null;
-        }
-        if (mUploadFinishReceiver != null) {
-            unregisterReceiver(mUploadFinishReceiver);
-            mUploadFinishReceiver = null;
-        }
-        if (mDownloadFinishReceiver != null) {
-            unregisterReceiver(mDownloadFinishReceiver);
-            mDownloadFinishReceiver = null;
-        }
-        if (!AccountUtils.accountsAreSetup(this)) {
-            dismissDialog(DIALOG_SETUP_ACCOUNT);
-        }
-        
-        Log.d(getClass().toString(), "onPause() end");
-    }
-
-    
-    @Override
-    protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
-        if (id == DIALOG_SSL_VALIDATOR && mLastSslUntrustedServerResult != null) {
-            ((SslValidatorDialog)dialog).updateResult(mLastSslUntrustedServerResult);
-        }
-    }
-
-    
-    @Override
-    protected Dialog onCreateDialog(int id) {
-        Dialog dialog = null;
-        AlertDialog.Builder builder;
-        switch (id) {
-        case DIALOG_SETUP_ACCOUNT: {
-            builder = new AlertDialog.Builder(this);
-            builder.setTitle(R.string.main_tit_accsetup);
-            builder.setMessage(R.string.main_wrn_accsetup);
-            builder.setCancelable(false);
-            builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    createFirstAccount();
-                    dialog.dismiss();
-                }
-            });
-            String message = String.format(getString(R.string.common_exit), getString(R.string.app_name));
-            builder.setNegativeButton(message, new OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    dialog.dismiss();
-                    finish();
-                }
-            });
-            //builder.setNegativeButton(android.R.string.cancel, this);
-            dialog = builder.create();
-            break;
-        }
-        case DIALOG_ABOUT_APP: {
-            builder = new AlertDialog.Builder(this);
-            builder.setTitle(getString(R.string.about_title));
-            PackageInfo pkg;
-            try {
-                pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
-                builder.setMessage(String.format(getString(R.string.about_message), getString(R.string.app_name), pkg.versionName));
-                builder.setIcon(android.R.drawable.ic_menu_info_details);
-                dialog = builder.create();
-            } catch (NameNotFoundException e) {
-                builder = null;
-                dialog = null;
-                Log.e(TAG, "Error while showing about dialog", e);
-            }
-            break;
-        }
-        case DIALOG_CREATE_DIR: {
-            builder = new Builder(this);
-            final EditText dirNameInput = new EditText(getBaseContext());
-            builder.setView(dirNameInput);
-            builder.setTitle(R.string.uploader_info_dirname);
-            int typed_color = getResources().getColor(R.color.setup_text_typed);
-            dirNameInput.setTextColor(typed_color);
-            builder.setPositiveButton(android.R.string.ok,
-                    new OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            String directoryName = dirNameInput.getText().toString();
-                            if (directoryName.trim().length() == 0) {
-                                dialog.cancel();
-                                return;
-                            }
-    
-                            // Figure out the path where the dir needs to be created
-                            String path;
-                            if (mCurrentDir == null) {
-                                // this is just a patch; we should ensure that mCurrentDir never is null
-                                if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
-                                    OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
-                                    mStorageManager.saveFile(file);
-                                }
-                                mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
-                            }
-                            path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
-                            
-                            // Create directory
-                            path += directoryName + OCFile.PATH_SEPARATOR;
-                            Thread thread = new Thread(new DirectoryCreator(path,  AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this), new Handler()));
-                            thread.start();
-                            
-                            dialog.dismiss();
-                            
-                            showDialog(DIALOG_SHORT_WAIT);
-                        }
-                    });
-            builder.setNegativeButton(R.string.common_cancel,
-                    new OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            dialog.cancel();
-                        }
-                    });
-            dialog = builder.create();
-            break;
-        }
-        case DIALOG_SHORT_WAIT: {
-            ProgressDialog working_dialog = new ProgressDialog(this);
-            working_dialog.setMessage(getResources().getString(
-                    R.string.wait_a_moment));
-            working_dialog.setIndeterminate(true);
-            working_dialog.setCancelable(false);
-            dialog = working_dialog;
-            break;
-        }
-        case DIALOG_CHOOSE_UPLOAD_SOURCE: {
-            final String [] items = {   getString(R.string.actionbar_upload_files), 
-                                        getString(R.string.actionbar_upload_from_apps) }; 
-            builder = new AlertDialog.Builder(this);
-            builder.setTitle(R.string.actionbar_upload);
-            builder.setItems(items, new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int item) {
-                    if (item == 0) {
-                        //if (!mDualPane) { 
-                            Intent action = new Intent(FileDisplayActivity.this, UploadFilesActivity.class);
-                            action.putExtra(UploadFilesActivity.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this));
-                            startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
-                        //} else {
-                            // TODO create and handle new fragment LocalFileListFragment
-                        //}
-                    } else if (item == 1) {
-                        Intent action = new Intent(Intent.ACTION_GET_CONTENT);
-                        action = action.setType("*/*")
-                                .addCategory(Intent.CATEGORY_OPENABLE);
-                        startActivityForResult(
-                                Intent.createChooser(action, getString(R.string.upload_chooser_title)),
-                                ACTION_SELECT_CONTENT_FROM_APPS);
-                    }
-                }
-            });
-            dialog = builder.create();
-            break;
-        }
-        case DIALOG_SSL_VALIDATOR: {
-            dialog = SslValidatorDialog.newInstance(this, mLastSslUntrustedServerResult, this);
-            break;
-        }
-        case DIALOG_CERT_NOT_SAVED: {
-            builder = new AlertDialog.Builder(this);
-            builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));
-            builder.setCancelable(false);
-            builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        dialog.dismiss();
-                    };
-                });
-            dialog = builder.create();
-            break;
-        }
-        default:
-            dialog = null;
-        }
-    
-        return dialog;
-    }
-
-    
-    /**
-     * Translates a content URI of an image to a physical path
-     * on the disk
-     * @param uri The URI to resolve
-     * @return The path to the image or null if it could not be found
-     */
-    public String getPath(Uri uri) {
-        String[] projection = { MediaStore.Images.Media.DATA };
-        Cursor cursor = managedQuery(uri, projection, null, null, null);
-        if (cursor != null) {
-            int column_index = cursor
-                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
-            cursor.moveToFirst();
-            return cursor.getString(column_index);
-        } 
-        return null;
-    }
-    
-    /**
-     * Pushes a directory to the drop down list
-     * @param directory to push
-     * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.
-     */
-    public void pushDirname(OCFile directory) {
-        if(!directory.isDirectory()){
-            throw new IllegalArgumentException("Only directories may be pushed!");
-        }
-        mDirectories.insert(directory.getFileName(), 0);
-        mCurrentDir = directory;
-    }
-
-    /**
-     * Pops a directory name from the drop down list
-     * @return True, unless the stack is empty
-     */
-    public boolean popDirname() {
-        mDirectories.remove(mDirectories.getItem(0));
-        return !mDirectories.isEmpty();
-    }
-
-    private class DirectoryCreator implements Runnable {
-        private String mTargetPath;
-        private Account mAccount;
-        private Handler mHandler; 
-    
-        public DirectoryCreator(String targetPath, Account account, Handler handler) {
-            mTargetPath = targetPath;
-            mAccount = account;
-            mHandler = handler;
-        }
-    
-        @Override
-        public void run() {
-            WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext());
-            boolean created = wdc.createDirectory(mTargetPath);
-            if (created) {
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() { 
-                        dismissDialog(DIALOG_SHORT_WAIT);
-                        
-                        // Save new directory in local database
-                        OCFile newDir = new OCFile(mTargetPath);
-                        newDir.setMimetype("DIR");
-                        newDir.setParentId(mCurrentDir.getFileId());
-                        mStorageManager.saveFile(newDir);
-    
-                        // Display the new folder right away
-                        mFileList.listDirectory();
-                    }
-                });
-                
-            } else {
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        dismissDialog(DIALOG_SHORT_WAIT);
-                        try {
-                            Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG); 
-                            msg.show();
-                        
-                        } catch (NotFoundException e) {
-                            Log.e(TAG, "Error while trying to show fail message " , e);
-                        }
-                    }
-                });
-            }
-        }
-    
-    }
-
-    // Custom array adapter to override text colors
-    private class CustomArrayAdapter<T> extends ArrayAdapter<T> {
-    
-        public CustomArrayAdapter(FileDisplayActivity ctx, int view) {
-            super(ctx, view);
-        }
-    
-        public View getView(int position, View convertView, ViewGroup parent) {
-            View v = super.getView(position, convertView, parent);
-    
-            ((TextView) v).setTextColor(getResources().getColorStateList(
-                    android.R.color.white));
-            return v;
-        }
-    
-        public View getDropDownView(int position, View convertView,
-                ViewGroup parent) {
-            View v = super.getDropDownView(position, convertView, parent);
-    
-            ((TextView) v).setTextColor(getResources().getColorStateList(
-                    android.R.color.white));
-    
-            return v;
-        }
-    
-    }
-
-    private class SyncBroadcastReceiver extends BroadcastReceiver {
-
-        /**
-         * {@link BroadcastReceiver} to enable syncing feedback in UI
-         */
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            boolean inProgress = intent.getBooleanExtra(
-                    FileSyncService.IN_PROGRESS, false);
-            String accountName = intent
-                    .getStringExtra(FileSyncService.ACCOUNT_NAME);
-
-            Log.d("FileDisplay", "sync of account " + accountName
-                    + " is in_progress: " + inProgress);
-
-            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {  
-            
-                String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH); 
-                 
-                boolean fillBlankRoot = false;
-                if (mCurrentDir == null) {
-                    mCurrentDir = mStorageManager.getFileByPath("/");
-                    fillBlankRoot = (mCurrentDir != null);
-                }
-
-                if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath().equals(synchFolderRemotePath)))
-                        || fillBlankRoot ) {
-                    if (!fillBlankRoot) 
-                        mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);
-                    OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager()
-                            .findFragmentById(R.id.fileList);
-                    if (fileListFragment != null) {
-                        fileListFragment.listDirectory(mCurrentDir);
-                    }
-                }
-                
-                setSupportProgressBarIndeterminateVisibility(inProgress);
-                removeStickyBroadcast(intent);
-                
-            }
-            
-            RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncService.SYNC_RESULT);
-            if (synchResult != null) {
-                if (synchResult.getCode().equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) {
-                    mLastSslUntrustedServerResult = synchResult;
-                    showDialog(DIALOG_SSL_VALIDATOR); 
-                }
-            }
-        }
-    }
-    
-
-    private class UploadFinishReceiver extends BroadcastReceiver {
-        /**
-         * Once the file upload has finished -> update view
-         *  @author David A. Velasco
-         * {@link BroadcastReceiver} to enable upload feedback in UI
-         */
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String uploadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
-            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
-            boolean sameAccount = accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name);
-            boolean isDescendant = (mCurrentDir != null) && (uploadedRemotePath != null) && (uploadedRemotePath.startsWith(mCurrentDir.getRemotePath()));
-            if (sameAccount && isDescendant) {
-                OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
-                if (fileListFragment != null) { 
-                    fileListFragment.listDirectory();
-                }
-            }
-        }
-        
-    }
-    
-    
-    /**
-     * Once the file download has finished -> update view
-     */
-    private class DownloadFinishReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
-            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
-            boolean sameAccount = accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name);
-            boolean isDescendant = (mCurrentDir != null) && (downloadedRemotePath != null) && (downloadedRemotePath.startsWith(mCurrentDir.getRemotePath()));
-            if (sameAccount && isDescendant) {
-                OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
-                if (fileListFragment != null) { 
-                    fileListFragment.listDirectory();
-                }
-            }
-        }
-    }
-    
-    
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public DataStorageManager getStorageManager() {
-        return mStorageManager;
-    }
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onDirectoryClick(OCFile directory) {
-        pushDirname(directory);
-        ActionBar actionBar = getSupportActionBar();
-        actionBar.setDisplayHomeAsUpEnabled(true);
-        
-        if (mDualPane) {
-            // Resets the FileDetailsFragment on Tablets so that it always displays
-            FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-            if (fileDetails != null && !fileDetails.isEmpty()) {
-                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-                transaction.remove(fileDetails);
-                transaction.add(R.id.file_details_container, new FileDetailFragment(null, null), FileDetailFragment.FTAG);
-                transaction.commit();
-            }
-        }
-    }
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onFileClick(OCFile file) {
-        
-        // If we are on a large device -> update fragment
-        if (mDualPane) {
-            // buttons in the details view are problematic when trying to reuse an existing fragment; create always a new one solves some of them, BUT no all; downloads are 'dangerous'
-            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-            transaction.replace(R.id.file_details_container, new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG);
-            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
-            transaction.commit();
-            
-        } else {    // small or medium screen device -> new Activity
-            Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
-            showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
-            showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
-            startActivity(showDetailsIntent);
-        }
-    }
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public OCFile getInitialDirectory() {
-        return mCurrentDir;
-    }
-    
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onFileStateChanged() {
-        OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
-        if (fileListFragment != null) { 
-            fileListFragment.listDirectory();
-        }
-    }
-
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public FileDownloaderBinder getFileDownloaderBinder() {
-        return mDownloaderBinder;
-    }
-
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public FileUploaderBinder getFileUploaderBinder() {
-        return mUploaderBinder;
-    }
-    
-    
-    /** Defines callbacks for service binding, passed to bindService() */
-    private class ListServiceConnection implements ServiceConnection {
-
-        @Override
-        public void onServiceConnected(ComponentName component, IBinder service) {
-            if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
-                Log.d(TAG, "Download service connected");
-                mDownloaderBinder = (FileDownloaderBinder) service;
-            } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
-                Log.d(TAG, "Upload service connected");
-                mUploaderBinder = (FileUploaderBinder) service;
-            } else {
-                return;
-            }
-            // a new chance to get the mDownloadBinder through getFileDownloadBinder() - THIS IS A MESS
-            if (mFileList != null)
-                mFileList.listDirectory();
-            if (mDualPane) {
-                FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-                if (fragment != null)
-                    fragment.updateFileDetails(false);
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName component) {
-            if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
-                Log.d(TAG, "Download service disconnected");
-                mDownloaderBinder = null;
-            } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
-                Log.d(TAG, "Upload service disconnected");
-                mUploaderBinder = null;
-            }
-        }
-    };    
-
-    
-    
-    /**
-     * Launch an intent to request the PIN code to the user before letting him use the app
-     */
-    private void requestPinCode() {
-        boolean pinStart = false;
-        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-        pinStart = appPrefs.getBoolean("set_pincode", false);
-        if (pinStart) {
-            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
-            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
-            startActivity(i);
-        }
-    }
-
-
-    @Override
-    public void onSavedCertificate() {
-        startSynchronization();                
-    }
-
-
-    @Override
-    public void onFailedSavingCertificate() {
-        showDialog(DIALOG_CERT_NOT_SAVED);
-    }
-
-
-    /**
-     * Updates the view associated to the activity after the finish of some operation over files
-     * in the current account.
-     * 
-     * @param operation     Removal operation performed.
-     * @param result        Result of the removal.
-     */
-    @Override
-    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
-        if (operation instanceof RemoveFileOperation) {
-            onRemoveFileOperationFinish((RemoveFileOperation)operation, result);
-                
-        } else if (operation instanceof RenameFileOperation) {
-            onRenameFileOperationFinish((RenameFileOperation)operation, result);
-            
-        } else if (operation instanceof SynchronizeFileOperation) {
-            onSynchronizeFileOperationFinish((SynchronizeFileOperation)operation, result);
-        }
-    }
-
-
-    /**
-     * Updates the view associated to the activity after the finish of an operation trying to remove a 
-     * file. 
-     * 
-     * @param operation     Removal operation performed.
-     * @param result        Result of the removal.
-     */
-    private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) {
-        dismissDialog(DIALOG_SHORT_WAIT);
-        if (result.isSuccess()) {
-            Toast msg = Toast.makeText(this, R.string.remove_success_msg, Toast.LENGTH_LONG);
-            msg.show();
-            OCFile removedFile = operation.getFile();
-            if (mDualPane) {
-                FileDetailFragment details = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-                if (details != null && removedFile.equals(details.getDisplayedFile()) ) {
-                    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
-                    transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
-                    transaction.commit();
-                }
-            }
-            if (mStorageManager.getFileById(removedFile.getParentId()).equals(mCurrentDir)) {
-                mFileList.listDirectory();
-            }
-                
-        } else {
-            Toast msg = Toast.makeText(this, R.string.remove_fail_msg, Toast.LENGTH_LONG); 
-            msg.show();
-            if (result.isSslRecoverableException()) {
-                mLastSslUntrustedServerResult = result;
-                showDialog(DIALOG_SSL_VALIDATOR); 
-            }
-        }
-    }
-
-    /**
-     * Updates the view associated to the activity after the finish of an operation trying to rename a 
-     * file. 
-     * 
-     * @param operation     Renaming operation performed.
-     * @param result        Result of the renaming.
-     */
-    private void onRenameFileOperationFinish(RenameFileOperation operation, RemoteOperationResult result) {
-        dismissDialog(DIALOG_SHORT_WAIT);
-        OCFile renamedFile = operation.getFile();
-        if (result.isSuccess()) {
-            if (mDualPane) {
-                FileDetailFragment details = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-                if (details != null && renamedFile.equals(details.getDisplayedFile()) ) {
-                    details.updateFileDetails(renamedFile, AccountUtils.getCurrentOwnCloudAccount(this));
-                }
-            }
-            if (mStorageManager.getFileById(renamedFile.getParentId()).equals(mCurrentDir)) {
-                mFileList.listDirectory();
-            }
-            
-        } else {
-            if (result.getCode().equals(ResultCode.INVALID_LOCAL_FILE_NAME)) {
-                Toast msg = Toast.makeText(this, R.string.rename_local_fail_msg, Toast.LENGTH_LONG); 
-                msg.show();
-                // TODO throw again the new rename dialog
-            } else {
-                Toast msg = Toast.makeText(this, R.string.rename_server_fail_msg, Toast.LENGTH_LONG); 
-                msg.show();
-                if (result.isSslRecoverableException()) {
-                    mLastSslUntrustedServerResult = result;
-                    showDialog(DIALOG_SSL_VALIDATOR); 
-                }
-            }
-        }
-    }
-
-
-    private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, RemoteOperationResult result) {
-        dismissDialog(DIALOG_SHORT_WAIT);
-        OCFile syncedFile = operation.getLocalFile();
-        if (!result.isSuccess()) {
-            if (result.getCode() == ResultCode.SYNC_CONFLICT) {
-                Intent i = new Intent(this, ConflictsResolveActivity.class);
-                i.putExtra(ConflictsResolveActivity.EXTRA_FILE, syncedFile);
-                i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
-                startActivity(i);
-                
-            } else {
-                Toast msg = Toast.makeText(this, R.string.sync_file_fail_msg, Toast.LENGTH_LONG); 
-                msg.show();
-            }
-            
-        } else {
-            if (operation.transferWasRequested()) {
-                mFileList.listDirectory();
-                onTransferStateChanged(syncedFile, true, true);
-                
-            } else {
-                Toast msg = Toast.makeText(this, R.string.sync_file_nothing_to_do_msg, Toast.LENGTH_LONG); 
-                msg.show();
-            }
-        }
-    }
-
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void onTransferStateChanged(OCFile file, boolean downloading, boolean uploading) {
-        /*OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
-        if (fileListFragment != null) { 
-            fileListFragment.listDirectory();
-        }*/
-        if (mDualPane) {
-            FileDetailFragment details = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
-            if (details != null && file.equals(details.getDisplayedFile()) ) {
-                if (downloading || uploading) {
-                    details.updateFileDetails(file, AccountUtils.getCurrentOwnCloudAccount(this));
-                } else {
-                    details.updateFileDetails(downloading || uploading);
-                }
-            }
-        }
-    }
-
-
-    
-
-
-}
+/* ownCloud Android client application
+ *   Copyright (C) 2011  Bartek Przybylski
+ *   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 as published by
+ *   the Free Software Foundation, either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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 java.io.File;
+
+import android.accounts.Account;
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore;
+import android.support.v4.app.FragmentTransaction;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+import com.actionbarsherlock.view.Window;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.R;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.datamodel.DataStorageManager;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.services.FileDownloader;
+import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
+import com.owncloud.android.files.services.FileObserverService;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
+import com.owncloud.android.network.OwnCloudClientUtils;
+import com.owncloud.android.operations.OnRemoteOperationListener;
+import com.owncloud.android.operations.RemoteOperation;
+import com.owncloud.android.operations.RemoteOperationResult;
+import com.owncloud.android.operations.RemoteOperationResult.ResultCode;
+import com.owncloud.android.operations.RemoveFileOperation;
+import com.owncloud.android.operations.RenameFileOperation;
+import com.owncloud.android.operations.SynchronizeFileOperation;
+import com.owncloud.android.syncadapter.FileSyncService;
+import com.owncloud.android.ui.dialog.ChangelogDialog;
+import com.owncloud.android.ui.dialog.SslValidatorDialog;
+import com.owncloud.android.ui.dialog.SslValidatorDialog.OnSslValidatorListener;
+import com.owncloud.android.ui.fragment.FileDetailFragment;
+import com.owncloud.android.ui.fragment.OCFileListFragment;
+
+import eu.alefzero.webdav.WebdavClient;
+
+/**
+ * Displays, what files the user has available in his ownCloud.
+ * 
+ * @author Bartek Przybylski
+ * 
+ */
+
+public class FileDisplayActivity extends SherlockFragmentActivity implements OCFileListFragment.ContainerActivity,
+        FileDetailFragment.ContainerActivity, OnNavigationListener, OnSslValidatorListener, OnRemoteOperationListener {
+
+    private ArrayAdapter<String> mDirectories;
+    private OCFile mCurrentDir = null;
+    private OCFile mCurrentFile = null;
+
+    private DataStorageManager mStorageManager;
+    private SyncBroadcastReceiver mSyncBroadcastReceiver;
+    private UploadFinishReceiver mUploadFinishReceiver;
+    private DownloadFinishReceiver mDownloadFinishReceiver;
+    private FileDownloaderBinder mDownloaderBinder = null;
+    private FileUploaderBinder mUploaderBinder = null;
+    private ServiceConnection mDownloadConnection = null, mUploadConnection = null;
+    private RemoteOperationResult mLastSslUntrustedServerResult = null;
+    
+    private OCFileListFragment mFileList;
+    
+    private boolean mDualPane;
+    
+    private static final int DIALOG_SETUP_ACCOUNT = 0;
+    private static final int DIALOG_CREATE_DIR = 1;
+    private static final int DIALOG_ABOUT_APP = 2;
+    public static final int DIALOG_SHORT_WAIT = 3;
+    private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 4;
+    private static final int DIALOG_SSL_VALIDATOR = 5;
+    private static final int DIALOG_CERT_NOT_SAVED = 6;
+    private static final String DIALOG_CHANGELOG_TAG = "DIALOG_CHANGELOG";
+
+    
+    private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
+    private static final int ACTION_SELECT_MULTIPLE_FILES = 2;
+    private static final int ACTION_SELECT_FAILED_INSTANT_UPLOAD = 2;
+
+    private static final String TAG = "FileDisplayActivity";
+
+    private static int[] mMenuIdentifiersToPatch = {R.id.about_app};
+    
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        Log.d(getClass().toString(), "onCreate() start");
+        super.onCreate(savedInstanceState);
+
+        /// Load of parameters from received intent
+        mCurrentDir = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE); // no check necessary, mCurrenDir == null if the parameter is not in the intent
+        Account account = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
+        if (account != null)
+            AccountUtils.setCurrentOwnCloudAccount(this, account.name);
+        
+        /// Load of saved instance state: keep this always before initDataFromCurrentAccount()
+        if(savedInstanceState != null) {
+            // TODO - test if savedInstanceState should take precedence over file in the intent ALWAYS (now), NEVER, or SOME TIMES
+            mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
+        }
+        
+        if (!AccountUtils.accountsAreSetup(this)) {
+            /// no account available: FORCE ACCOUNT CREATION
+            mStorageManager = null;
+            createFirstAccount();
+
+        } else { // / at least an account is available
+
+            initDataFromCurrentAccount(); // it checks mCurrentDir and
+                                          // mCurrentFile with the current
+                                          // account
+
+        }
+        
+        mUploadConnection = new ListServiceConnection(); 
+        mDownloadConnection = new ListServiceConnection();
+        bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
+        bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
+
+        // PIN CODE request ;  best location is to decide, let's try this first
+        if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
+            requestPinCode();
+        }
+
+        // file observer
+        Intent observer_intent = new Intent(this, FileObserverService.class);
+        observer_intent.putExtra(FileObserverService.KEY_FILE_CMD, FileObserverService.CMD_INIT_OBSERVED_LIST);
+        startService(observer_intent);
+        
+            
+        /// USER INTERFACE
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+            
+        // Drop-down navigation 
+        mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
+        OCFile currFile = mCurrentDir;
+        while (currFile != null && currFile.getFileName() != OCFile.PATH_SEPARATOR) {
+            mDirectories.add(currFile.getFileName());
+            currFile = mStorageManager.getFileById(currFile.getParentId());
+        }
+        mDirectories.add(OCFile.PATH_SEPARATOR);
+
+        // Inflate and set the layout view
+        setContentView(R.layout.files);    
+        mFileList = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+        mDualPane = (findViewById(R.id.file_details_container) != null);
+        if (mDualPane) {
+            initFileDetailsInDualPane();
+        }
+            
+        // Action bar setup
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setHomeButtonEnabled(true);   // mandatory since Android ICS, according to the official documentation
+        actionBar.setDisplayHomeAsUpEnabled(mCurrentDir != null && mCurrentDir.getParentId() != 0);
+        actionBar.setDisplayShowTitleEnabled(false);
+        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
+        actionBar.setListNavigationCallbacks(mDirectories, this);
+        setSupportProgressBarIndeterminateVisibility(false);        // always AFTER setContentView(...) ; to workaround bug in its implementation
+        
+        
+        // show changelog, if needed
+        showChangeLog();
+        
+        Log.d(getClass().toString(), "onCreate() end");
+    }
+
+    
+    /**
+     * Shows a dialog with the change log of the current version after each app update
+     * 
+     *  TODO make it permanent; by now, only to advice the workaround app for 4.1.x
+     */
+    private void showChangeLog() {
+        if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.JELLY_BEAN) {
+            final String KEY_VERSION = "version";
+            SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+            int currentVersionNumber = 0;
+            int savedVersionNumber = sharedPref.getInt(KEY_VERSION, 0);
+            try {
+                PackageInfo pi          = getPackageManager().getPackageInfo(getPackageName(), 0);
+                currentVersionNumber    = pi.versionCode;
+            } catch (Exception e) {}
+     
+            if (currentVersionNumber > savedVersionNumber) {
+                ChangelogDialog.newInstance(true).show(getSupportFragmentManager(), DIALOG_CHANGELOG_TAG);
+                Editor editor   = sharedPref.edit();
+                editor.putInt(KEY_VERSION, currentVersionNumber);
+                editor.commit();
+            }
+        }
+    }
+    
+
+    /**
+     * Launches the account creation activity. To use when no ownCloud account is available
+     */
+    private void createFirstAccount() {
+        Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
+        intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+        startActivity(intent);  // the new activity won't be created until this.onStart() and this.onResume() are finished;
+    }
+
+
+    /**
+     *  Load of state dependent of the existence of an ownCloud account
+     */
+    private void initDataFromCurrentAccount() {
+        /// Storage manager initialization - access to local database
+        mStorageManager = new FileDataStorageManager(
+                AccountUtils.getCurrentOwnCloudAccount(this),
+                getContentResolver());
+
+        /// Check if mCurrentDir is a directory
+        if(mCurrentDir != null && !mCurrentDir.isDirectory()) {
+            mCurrentFile = mCurrentDir;
+            mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());
+        }
+        
+        /// Check if mCurrentDir and mCurrentFile are in the current account, and update them
+        if (mCurrentDir != null) {
+            mCurrentDir = mStorageManager.getFileByPath(mCurrentDir.getRemotePath());   // mCurrentDir == null if it is not in the current account
+        }
+        if (mCurrentFile != null) {
+            if (mCurrentFile.fileExists()) {
+                mCurrentFile = mStorageManager.getFileByPath(mCurrentFile.getRemotePath());   // mCurrentFile == null if it is not in the current account
+            }   // else : keep mCurrentFile with the received value; this is currently the case of an upload in progress, when the user presses the status notification in a landscape tablet
+        }
+        
+        /// Default to root if mCurrentDir was not found
+        if (mCurrentDir == null) {
+            mCurrentDir = mStorageManager.getFileByPath("/"); // will be NULL if the database was never synchronized
+        }
+    }
+        
+    
+    private void initFileDetailsInDualPane() {
+        if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+            if (mCurrentFile != null) {
+                transaction.replace(R.id.file_details_container,
+                        new FileDetailFragment(mCurrentFile, AccountUtils.getCurrentOwnCloudAccount(this)),
+                        FileDetailFragment.FTAG); // empty FileDetailFragment
+                mCurrentFile = null;
+            } else {
+                transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null),
+                        FileDetailFragment.FTAG); // empty FileDetailFragment
+            }
+            transaction.commit();
+        }
+    }
+    
+    
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        if (mDownloadConnection != null)
+            unbindService(mDownloadConnection);
+        if (mUploadConnection != null)
+            unbindService(mUploadConnection);
+    }
+
+    
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getSherlock().getMenuInflater();
+            inflater.inflate(R.menu.menu, menu);
+            
+            patchHiddenAccents(menu);
+            
+            return true;
+    }
+
+    /**
+     * Workaround for this: <a href="http://code.google.com/p/android/issues/detail?id=3974">http://code.google.com/p/android/issues/detail?id=3974</a> 
+     * 
+     * @param menu      Menu to patch
+     */
+    private void patchHiddenAccents(Menu menu) {
+        for (int i = 0; i < mMenuIdentifiersToPatch.length ; i++) {
+            MenuItem aboutItem = menu.findItem(mMenuIdentifiersToPatch[i]);
+            if (aboutItem != null && aboutItem.getIcon() instanceof BitmapDrawable) {
+                // Clip off the bottom three (density independent) pixels of transparent padding
+                Bitmap original = ((BitmapDrawable) aboutItem.getIcon()).getBitmap();
+                float scale = getResources().getDisplayMetrics().density;
+                int clippedHeight = (int) (original.getHeight() - (3 * scale));
+                Bitmap scaled = Bitmap.createBitmap(original, 0, 0, original.getWidth(), clippedHeight);
+                aboutItem.setIcon(new BitmapDrawable(getResources(), scaled));
+            }
+        }
+    }
+
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        boolean retval = true;
+        switch (item.getItemId()) {
+        case R.id.createDirectoryItem: {
+            showDialog(DIALOG_CREATE_DIR);
+            break;
+        }
+        case R.id.startSync: {
+            startSynchronization();
+            break;
+        }
+        case R.id.action_upload: {
+            showDialog(DIALOG_CHOOSE_UPLOAD_SOURCE);
+            break;
+        }
+        case R.id.action_settings: {
+            Intent settingsIntent = new Intent(this, Preferences.class);
+            startActivity(settingsIntent);
+            break;
+        }
+        case R.id.about_app: {
+            showDialog(DIALOG_ABOUT_APP);
+            break;
+        }
+        case android.R.id.home: {
+            if (mCurrentDir != null && mCurrentDir.getParentId() != 0) {
+                onBackPressed();
+            }
+            break;
+        }
+        default:
+            retval = super.onOptionsItemSelected(item);
+        }
+        return retval;
+    }
+
+    private void startSynchronization() {
+        ContentResolver.cancelSync(null, AccountAuthenticator.AUTH_TOKEN_TYPE);   // cancel the current synchronizations of any ownCloud account
+        Bundle bundle = new Bundle();
+        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        ContentResolver.requestSync(
+                AccountUtils.getCurrentOwnCloudAccount(this),
+                AccountAuthenticator.AUTH_TOKEN_TYPE, bundle);
+    }
+
+
+    @Override
+    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
+        int i = itemPosition;
+        while (i-- != 0) {
+            onBackPressed();
+        }
+        // the next operation triggers a new call to this method, but it's necessary to 
+        // ensure that the name exposed in the action bar is the current directory when the 
+        // user selected it in the navigation list
+        if (itemPosition != 0)
+            getSupportActionBar().setSelectedNavigationItem(0);
+        return true;
+    }
+
+    /**
+     * Called, when the user selected something for uploading
+     */
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+
+        if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS
+                && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
+            requestSimpleUpload(data, resultCode);
+
+        } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES
+                && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
+            requestMultipleUpload(data, resultCode);
+            
+        }
+    }
+
+    private void requestMultipleUpload(Intent data, int resultCode) {
+        String[] filePaths = data.getStringArrayExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES);
+        if (filePaths != null) {
+            String[] remotePaths = new String[filePaths.length];
+            String remotePathBase = "";
+            for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
+                remotePathBase += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
+            }
+            if (!remotePathBase.endsWith(OCFile.PATH_SEPARATOR))
+                remotePathBase += OCFile.PATH_SEPARATOR;
+            for (int j = 0; j < remotePaths.length; j++) {
+                remotePaths[j] = remotePathBase + (new File(filePaths[j])).getName();
+            }
+
+            Intent i = new Intent(this, FileUploader.class);
+            i.putExtra(FileUploader.KEY_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
+            i.putExtra(FileUploader.KEY_LOCAL_FILE, filePaths);
+            i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePaths);
+            i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);
+            if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
+                i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
+            startService(i);
+            
+        } else {
+            Log.d("FileDisplay", "User clicked on 'Update' with no selection");
+            Toast t = Toast.makeText(this, getString(R.string.filedisplay_no_file_selected), Toast.LENGTH_LONG);
+            t.show();
+            return;
+        }
+    }
+
+
+    private void requestSimpleUpload(Intent data, int resultCode) {
+        String filepath = null;
+        try {
+            Uri selectedImageUri = data.getData();
+
+            String filemanagerstring = selectedImageUri.getPath();
+            String selectedImagePath = getPath(selectedImageUri);
+
+            if (selectedImagePath != null)
+                filepath = selectedImagePath;
+            else
+                filepath = filemanagerstring;
+            
+        } catch (Exception e) {
+            Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
+            e.printStackTrace();
+            
+        } finally {
+            if (filepath == null) {
+                Log.e("FileDisplay", "Couldnt resolve path to file");
+                Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
+                t.show();
+                return;
+            }
+        }
+
+        Intent i = new Intent(this, FileUploader.class);
+        i.putExtra(FileUploader.KEY_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
+        String remotepath = new String();
+        for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
+            remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
+        }
+        if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
+            remotepath += OCFile.PATH_SEPARATOR;
+        remotepath += new File(filepath).getName();
+
+        i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
+        i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
+        i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
+        if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
+            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
+        startService(i);
+    }
+
+
+    @Override
+    public void onBackPressed() {
+        if (mDirectories.getCount() <= 1) {
+            finish();
+            return;
+        }
+        popDirname();
+        mFileList.onNavigateUp();
+        mCurrentDir = mFileList.getCurrentFile();
+        
+        if (mDualPane) {
+            // Resets the FileDetailsFragment on Tablets so that it always
+            // displays
+            FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(
+                    FileDetailFragment.FTAG);
+            if (fileDetails != null && !fileDetails.isEmpty()) {
+                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+                transaction.remove(fileDetails);
+                transaction.add(R.id.file_details_container, new FileDetailFragment(null, null),
+                        FileDetailFragment.FTAG);
+                transaction.commit();
+            }
+        }
+
+        if (mCurrentDir.getParentId() == 0) {
+            ActionBar actionBar = getSupportActionBar();
+            actionBar.setDisplayHomeAsUpEnabled(false);
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        // responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
+        Log.d(getClass().toString(), "onSaveInstanceState() start");
+        super.onSaveInstanceState(outState);
+        outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);
+        if (mDualPane) {
+            FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
+            if (fragment != null) {
+                OCFile file = fragment.getDisplayedFile();
+                if (file != null) {
+                    outState.putParcelable(FileDetailFragment.EXTRA_FILE, file);
+                }
+            }
+        }
+        Log.d(getClass().toString(), "onSaveInstanceState() end");
+    }
+
+    @Override
+    protected void onResume() {
+        Log.d(getClass().toString(), "onResume() start");
+        super.onResume();
+
+        if (AccountUtils.accountsAreSetup(this)) {
+            
+            if (mStorageManager == null) {
+                // this is necessary for handling the come back to FileDisplayActivity when the first ownCloud account is created 
+                initDataFromCurrentAccount();
+                if (mDualPane) {
+                    initFileDetailsInDualPane();
+                }
+            }
+            
+            // Listen for sync messages
+            IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);
+            mSyncBroadcastReceiver = new SyncBroadcastReceiver();
+            registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
+            
+            // Listen for upload messages
+            IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
+            mUploadFinishReceiver = new UploadFinishReceiver();
+            registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
+            
+            // Listen for download messages
+            IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);
+            mDownloadFinishReceiver = new DownloadFinishReceiver();
+            registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
+        
+            // List current directory
+            mFileList.listDirectory(mCurrentDir);   // TODO we should find the way to avoid the need of this (maybe it's not necessary yet; to check)
+            
+        } else {
+            
+            mStorageManager = null;     // an invalid object will be there if all the ownCloud accounts are removed
+            showDialog(DIALOG_SETUP_ACCOUNT);
+            
+        }
+        Log.d(getClass().toString(), "onResume() end");
+    }
+
+    
+    @Override
+    protected void onPause() {
+        Log.d(getClass().toString(), "onPause() start");
+        super.onPause();
+        if (mSyncBroadcastReceiver != null) {
+            unregisterReceiver(mSyncBroadcastReceiver);
+            mSyncBroadcastReceiver = null;
+        }
+        if (mUploadFinishReceiver != null) {
+            unregisterReceiver(mUploadFinishReceiver);
+            mUploadFinishReceiver = null;
+        }
+        if (mDownloadFinishReceiver != null) {
+            unregisterReceiver(mDownloadFinishReceiver);
+            mDownloadFinishReceiver = null;
+        }
+        if (!AccountUtils.accountsAreSetup(this)) {
+            dismissDialog(DIALOG_SETUP_ACCOUNT);
+        }
+        
+        Log.d(getClass().toString(), "onPause() end");
+    }
+
+    
+    @Override
+    protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
+        if (id == DIALOG_SSL_VALIDATOR && mLastSslUntrustedServerResult != null) {
+            ((SslValidatorDialog)dialog).updateResult(mLastSslUntrustedServerResult);
+        }
+    }
+
+    
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        Dialog dialog = null;
+        AlertDialog.Builder builder;
+        switch (id) {
+        case DIALOG_SETUP_ACCOUNT: {
+            builder = new AlertDialog.Builder(this);
+            builder.setTitle(R.string.main_tit_accsetup);
+            builder.setMessage(R.string.main_wrn_accsetup);
+            builder.setCancelable(false);
+            builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    createFirstAccount();
+                    dialog.dismiss();
+                }
+            });
+            String message = String.format(getString(R.string.common_exit), getString(R.string.app_name));
+            builder.setNegativeButton(message, new OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    dialog.dismiss();
+                    finish();
+                }
+            });
+            //builder.setNegativeButton(android.R.string.cancel, this);
+            dialog = builder.create();
+            break;
+        }
+        case DIALOG_ABOUT_APP: {
+            builder = new AlertDialog.Builder(this);
+            builder.setTitle(getString(R.string.about_title));
+            PackageInfo pkg;
+            try {
+                pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
+                builder.setMessage(String.format(getString(R.string.about_message), getString(R.string.app_name), pkg.versionName));
+                builder.setIcon(android.R.drawable.ic_menu_info_details);
+                dialog = builder.create();
+            } catch (NameNotFoundException e) {
+                builder = null;
+                dialog = null;
+                Log.e(TAG, "Error while showing about dialog", e);
+            }
+            break;
+        }
+        case DIALOG_CREATE_DIR: {
+            builder = new Builder(this);
+            final EditText dirNameInput = new EditText(getBaseContext());
+            builder.setView(dirNameInput);
+            builder.setTitle(R.string.uploader_info_dirname);
+            int typed_color = getResources().getColor(R.color.setup_text_typed);
+            dirNameInput.setTextColor(typed_color);
+            builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    String directoryName = dirNameInput.getText().toString();
+                    if (directoryName.trim().length() == 0) {
+                        dialog.cancel();
+                        return;
+                    }
+
+                    // Figure out the path where the dir needs to be created
+                    String path;
+                    if (mCurrentDir == null) {
+                        // this is just a patch; we should ensure that
+                        // mCurrentDir never is null
+                        if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
+                            OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
+                            mStorageManager.saveFile(file);
+                        }
+                        mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
+                    }
+                    path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
+
+                    // Create directory
+                    path += directoryName + OCFile.PATH_SEPARATOR;
+                    Thread thread = new Thread(new DirectoryCreator(path, AccountUtils
+                            .getCurrentOwnCloudAccount(FileDisplayActivity.this), new Handler()));
+                    thread.start();
+
+                    dialog.dismiss();
+
+                    showDialog(DIALOG_SHORT_WAIT);
+                }
+            });
+            builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
+                public void onClick(DialogInterface dialog, int which) {
+                    dialog.cancel();
+                }
+            });
+            dialog = builder.create();
+            break;
+        }
+        case DIALOG_SHORT_WAIT: {
+            ProgressDialog working_dialog = new ProgressDialog(this);
+            working_dialog.setMessage(getResources().getString(R.string.wait_a_moment));
+            working_dialog.setIndeterminate(true);
+            working_dialog.setCancelable(false);
+            dialog = working_dialog;
+            break;
+        }
+        case DIALOG_CHOOSE_UPLOAD_SOURCE: {
+            final String[] items = { getString(R.string.actionbar_upload_files),
+                    getString(R.string.actionbar_upload_from_apps), getString(R.string.actionbar_failed_instant_upload) };
+            builder = new AlertDialog.Builder(this);
+            builder.setTitle(R.string.actionbar_upload);
+            builder.setItems(items, new DialogInterface.OnClickListener() {
+                public void onClick(DialogInterface dialog, int item) {
+                    if (item == 0) {
+                        // if (!mDualPane) {
+                        Intent action = new Intent(FileDisplayActivity.this, UploadFilesActivity.class);
+                        action.putExtra(UploadFilesActivity.EXTRA_ACCOUNT,
+                                AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this));
+                        startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
+                        // } else {
+                        // TODO create and handle new fragment
+                        // LocalFileListFragment
+                        // }
+                    } else if (item == 1) {
+                        Intent action = new Intent(Intent.ACTION_GET_CONTENT);
+                        action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
+                        startActivityForResult(Intent.createChooser(action, getString(R.string.upload_chooser_title)),
+                                ACTION_SELECT_CONTENT_FROM_APPS);
+                    } else if (item == 2) {
+                        Account account = AccountUtils.getCurrentOwnCloudAccount(FileDisplayActivity.this);
+                        Intent action = new Intent(FileDisplayActivity.this, InstantUploadActivity.class);
+                        action.putExtra(FileUploader.KEY_ACCOUNT, account);
+                        startActivity(action);
+                    }
+                }
+            });
+            dialog = builder.create();
+            break;
+        }
+        case DIALOG_SSL_VALIDATOR: {
+            dialog = SslValidatorDialog.newInstance(this, mLastSslUntrustedServerResult, this);
+            break;
+        }
+        case DIALOG_CERT_NOT_SAVED: {
+            builder = new AlertDialog.Builder(this);
+            builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));
+            builder.setCancelable(false);
+            builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    dialog.dismiss();
+                };
+            });
+            dialog = builder.create();
+            break;
+        }
+        default:
+            dialog = null;
+        }
+    
+        return dialog;
+    }
+
+    
+    /**
+     * Translates a content URI of an image to a physical path
+     * on the disk
+     * @param uri The URI to resolve
+     * @return The path to the image or null if it could not be found
+     */
+    public String getPath(Uri uri) {
+        String[] projection = { MediaStore.Images.Media.DATA };
+        Cursor cursor = managedQuery(uri, projection, null, null, null);
+        if (cursor != null) {
+            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
+            cursor.moveToFirst();
+            return cursor.getString(column_index);
+        }
+        return null;
+    }
+    
+    /**
+     * Pushes a directory to the drop down list
+     * @param directory to push
+     * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.
+     */
+    public void pushDirname(OCFile directory) {
+        if(!directory.isDirectory()){
+            throw new IllegalArgumentException("Only directories may be pushed!");
+        }
+        mDirectories.insert(directory.getFileName(), 0);
+        mCurrentDir = directory;
+    }
+
+    /**
+     * Pops a directory name from the drop down list
+     * @return True, unless the stack is empty
+     */
+    public boolean popDirname() {
+        mDirectories.remove(mDirectories.getItem(0));
+        return !mDirectories.isEmpty();
+    }
+
+    private class DirectoryCreator implements Runnable {
+        private String mTargetPath;
+        private Account mAccount;
+        private Handler mHandler; 
+    
+        public DirectoryCreator(String targetPath, Account account, Handler handler) {
+            mTargetPath = targetPath;
+            mAccount = account;
+            mHandler = handler;
+        }
+    
+        @Override
+        public void run() {
+            WebdavClient wdc = OwnCloudClientUtils.createOwnCloudClient(mAccount, getApplicationContext());
+            boolean created = wdc.createDirectory(mTargetPath);
+            if (created) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() { 
+                        dismissDialog(DIALOG_SHORT_WAIT);
+                        
+                        // Save new directory in local database
+                        OCFile newDir = new OCFile(mTargetPath);
+                        newDir.setMimetype("DIR");
+                        newDir.setParentId(mCurrentDir.getFileId());
+                        mStorageManager.saveFile(newDir);
+    
+                        // Display the new folder right away
+                        mFileList.listDirectory();
+                    }
+                });
+                
+            } else {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        dismissDialog(DIALOG_SHORT_WAIT);
+                        try {
+                            Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg,
+                                    Toast.LENGTH_LONG);
+                            msg.show();
+                        
+                        } catch (NotFoundException e) {
+                            Log.e(TAG, "Error while trying to show fail message ", e);
+                        }
+                    }
+                });
+            }
+        }
+    
+    }
+
+    // Custom array adapter to override text colors
+    private class CustomArrayAdapter<T> extends ArrayAdapter<T> {
+    
+        public CustomArrayAdapter(FileDisplayActivity ctx, int view) {
+            super(ctx, view);
+        }
+    
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View v = super.getView(position, convertView, parent);
+
+            ((TextView) v).setTextColor(getResources().getColorStateList(android.R.color.white));
+            return v;
+        }
+
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
+            View v = super.getDropDownView(position, convertView, parent);
+
+            ((TextView) v).setTextColor(getResources().getColorStateList(android.R.color.white));
+
+            return v;
+        }
+    
+    }
+
+    private class SyncBroadcastReceiver extends BroadcastReceiver {
+
+        /**
+         * {@link BroadcastReceiver} to enable syncing feedback in UI
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            boolean inProgress = intent.getBooleanExtra(FileSyncService.IN_PROGRESS, false);
+            String accountName = intent.getStringExtra(FileSyncService.ACCOUNT_NAME);
+
+            Log.d("FileDisplay", "sync of account " + accountName + " is in_progress: " + inProgress);
+
+            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {
+
+                String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH);
+
+                boolean fillBlankRoot = false;
+                if (mCurrentDir == null) {
+                    mCurrentDir = mStorageManager.getFileByPath("/");
+                    fillBlankRoot = (mCurrentDir != null);
+                }
+
+                if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath()
+                        .equals(synchFolderRemotePath))) || fillBlankRoot) {
+                    if (!fillBlankRoot)
+                        mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);
+                    OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager()
+                            .findFragmentById(R.id.fileList);
+                    if (fileListFragment != null) {
+                        fileListFragment.listDirectory(mCurrentDir);
+                    }
+                }
+                
+                setSupportProgressBarIndeterminateVisibility(inProgress);
+                removeStickyBroadcast(intent);
+                
+            }
+
+            RemoteOperationResult synchResult = (RemoteOperationResult) intent
+                    .getSerializableExtra(FileSyncService.SYNC_RESULT);
+            if (synchResult != null) {
+                if (synchResult.getCode().equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) {
+                    mLastSslUntrustedServerResult = synchResult;
+                    showDialog(DIALOG_SSL_VALIDATOR);
+                }
+            }
+        }
+    }
+    
+
+    private class UploadFinishReceiver extends BroadcastReceiver {
+        /**
+         * Once the file upload has finished -> update view
+         *  @author David A. Velasco
+         * {@link BroadcastReceiver} to enable upload feedback in UI
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String uploadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
+            boolean sameAccount = accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name);
+            boolean isDescendant = (mCurrentDir != null) && (uploadedRemotePath != null)
+                    && (uploadedRemotePath.startsWith(mCurrentDir.getRemotePath()));
+            if (sameAccount && isDescendant) {
+                OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager()
+                        .findFragmentById(R.id.fileList);
+                if (fileListFragment != null) {
+                    fileListFragment.listDirectory();
+                }
+            }
+        }
+        
+    }
+    
+    
+    /**
+     * Once the file download has finished -> update view
+     */
+    private class DownloadFinishReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
+            boolean sameAccount = accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name);
+            boolean isDescendant = (mCurrentDir != null) && (downloadedRemotePath != null)
+                    && (downloadedRemotePath.startsWith(mCurrentDir.getRemotePath()));
+            if (sameAccount && isDescendant) {
+                OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager()
+                        .findFragmentById(R.id.fileList);
+                if (fileListFragment != null) {
+                    fileListFragment.listDirectory();
+                }
+            }
+        }
+    }
+    
+    
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public DataStorageManager getStorageManager() {
+        return mStorageManager;
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onDirectoryClick(OCFile directory) {
+        pushDirname(directory);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setDisplayHomeAsUpEnabled(true);
+        
+        if (mDualPane) {
+            // Resets the FileDetailsFragment on Tablets so that it always displays
+            FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
+            if (fileDetails != null && !fileDetails.isEmpty()) {
+                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+                transaction.remove(fileDetails);
+                transaction.add(R.id.file_details_container, new FileDetailFragment(null, null),
+                        FileDetailFragment.FTAG);
+                transaction.commit();
+            }
+        }
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onFileClick(OCFile file) {
+        
+        // If we are on a large device -> update fragment
+        if (mDualPane) {
+            // buttons in the details view are problematic when trying to reuse an existing fragment; create always a new one solves some of them, BUT no all; downloads are 'dangerous'
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+            transaction
+                    .replace(R.id.file_details_container,
+                            new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)),
+                            FileDetailFragment.FTAG);
+            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
+            transaction.commit();
+
+        } else { // small or medium screen device -> new Activity
+            Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
+            showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
+            showDetailsIntent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
+            startActivity(showDetailsIntent);
+        }
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public OCFile getInitialDirectory() {
+        return mCurrentDir;
+    }
+    
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onFileStateChanged() {
+        OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager().findFragmentById(
+                R.id.fileList);
+        if (fileListFragment != null) {
+            fileListFragment.listDirectory();
+        }
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FileDownloaderBinder getFileDownloaderBinder() {
+        return mDownloaderBinder;
+    }
+
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FileUploaderBinder getFileUploaderBinder() {
+        return mUploaderBinder;
+    }
+    
+    
+    /** Defines callbacks for service binding, passed to bindService() */
+    private class ListServiceConnection implements ServiceConnection {
+
+        @Override
+        public void onServiceConnected(ComponentName component, IBinder service) {
+            if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
+                Log.d(TAG, "Download service connected");
+                mDownloaderBinder = (FileDownloaderBinder) service;
+            } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
+                Log.d(TAG, "Upload service connected");
+                mUploaderBinder = (FileUploaderBinder) service;
+            } else {
+                return;
+            }
+            // a new chance to get the mDownloadBinder through getFileDownloadBinder() - THIS IS A MESS
+            if (mFileList != null)
+                mFileList.listDirectory();
+            if (mDualPane) {
+                FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(
+                        FileDetailFragment.FTAG);
+                if (fragment != null)
+                    fragment.updateFileDetails(false);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName component) {
+            if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
+                Log.d(TAG, "Download service disconnected");
+                mDownloaderBinder = null;
+            } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
+                Log.d(TAG, "Upload service disconnected");
+                mUploaderBinder = null;
+            }
+        }
+    };    
+
+    
+    
+    /**
+     * Launch an intent to request the PIN code to the user before letting him use the app
+     */
+    private void requestPinCode() {
+        boolean pinStart = false;
+        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+        pinStart = appPrefs.getBoolean("set_pincode", false);
+        if (pinStart) {
+            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
+            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
+            startActivity(i);
+        }
+    }
+
+
+    @Override
+    public void onSavedCertificate() {
+        startSynchronization();                
+    }
+
+    @Override
+    public void onFailedSavingCertificate() {
+        showDialog(DIALOG_CERT_NOT_SAVED);
+    }
+
+
+    /**
+     * Updates the view associated to the activity after the finish of some operation over files
+     * in the current account.
+     * 
+     * @param operation     Removal operation performed.
+     * @param result        Result of the removal.
+     */
+    @Override
+    public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
+        if (operation instanceof RemoveFileOperation) {
+            onRemoveFileOperationFinish((RemoveFileOperation) operation, result);
+
+        } else if (operation instanceof RenameFileOperation) {
+            onRenameFileOperationFinish((RenameFileOperation) operation, result);
+
+        } else if (operation instanceof SynchronizeFileOperation) {
+            onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result);
+        }
+    }
+
+
+    /**
+     * Updates the view associated to the activity after the finish of an operation trying to remove a 
+     * file. 
+     * 
+     * @param operation     Removal operation performed.
+     * @param result        Result of the removal.
+     */
+    private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) {
+        dismissDialog(DIALOG_SHORT_WAIT);
+        if (result.isSuccess()) {
+            Toast msg = Toast.makeText(this, R.string.remove_success_msg, Toast.LENGTH_LONG);
+            msg.show();
+            OCFile removedFile = operation.getFile();
+            if (mDualPane) {
+                FileDetailFragment details = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(
+                        FileDetailFragment.FTAG);
+                if (details != null && removedFile.equals(details.getDisplayedFile())) {
+                    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+                    transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty
+                                                                                                          // FileDetailFragment
+                    transaction.commit();
+                }
+            }
+            if (mStorageManager.getFileById(removedFile.getParentId()).equals(mCurrentDir)) {
+                mFileList.listDirectory();
+            }
+                
+        } else {
+            Toast msg = Toast.makeText(this, R.string.remove_fail_msg, Toast.LENGTH_LONG);
+            msg.show();
+            if (result.isSslRecoverableException()) {
+                mLastSslUntrustedServerResult = result;
+                showDialog(DIALOG_SSL_VALIDATOR);
+            }
+        }
+    }
+
+    /**
+     * Updates the view associated to the activity after the finish of an operation trying to rename a 
+     * file. 
+     * 
+     * @param operation     Renaming operation performed.
+     * @param result        Result of the renaming.
+     */
+    private void onRenameFileOperationFinish(RenameFileOperation operation, RemoteOperationResult result) {
+        dismissDialog(DIALOG_SHORT_WAIT);
+        OCFile renamedFile = operation.getFile();
+        if (result.isSuccess()) {
+            if (mDualPane) {
+                FileDetailFragment details = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(
+                        FileDetailFragment.FTAG);
+                if (details != null && renamedFile.equals(details.getDisplayedFile())) {
+                    details.updateFileDetails(renamedFile, AccountUtils.getCurrentOwnCloudAccount(this));
+                }
+            }
+            if (mStorageManager.getFileById(renamedFile.getParentId()).equals(mCurrentDir)) {
+                mFileList.listDirectory();
+            }
+            
+        } else {
+            if (result.getCode().equals(ResultCode.INVALID_LOCAL_FILE_NAME)) {
+                Toast msg = Toast.makeText(this, R.string.rename_local_fail_msg, Toast.LENGTH_LONG);
+                msg.show();
+                // TODO throw again the new rename dialog
+            } else {
+                Toast msg = Toast.makeText(this, R.string.rename_server_fail_msg, Toast.LENGTH_LONG);
+                msg.show();
+                if (result.isSslRecoverableException()) {
+                    mLastSslUntrustedServerResult = result;
+                    showDialog(DIALOG_SSL_VALIDATOR);
+                }
+            }
+        }
+    }
+
+    private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, RemoteOperationResult result) {
+        dismissDialog(DIALOG_SHORT_WAIT);
+        OCFile syncedFile = operation.getLocalFile();
+        if (!result.isSuccess()) {
+            if (result.getCode() == ResultCode.SYNC_CONFLICT) {
+                Intent i = new Intent(this, ConflictsResolveActivity.class);
+                i.putExtra(ConflictsResolveActivity.EXTRA_FILE, syncedFile);
+                i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
+                startActivity(i);
+                
+            } else {
+                Toast msg = Toast.makeText(this, R.string.sync_file_fail_msg, Toast.LENGTH_LONG);
+                msg.show();
+            }
+            
+        } else {
+            if (operation.transferWasRequested()) {
+                mFileList.listDirectory();
+                onTransferStateChanged(syncedFile, true, true);
+                
+            } else {
+                Toast msg = Toast.makeText(this, R.string.sync_file_nothing_to_do_msg, Toast.LENGTH_LONG);
+                msg.show();
+            }
+        }
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransferStateChanged(OCFile file, boolean downloading, boolean uploading) {
+        /*OCFileListFragment fileListFragment = (OCFileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
+        if (fileListFragment != null) { 
+            fileListFragment.listDirectory();
+        }*/
+        if (mDualPane) {
+            FileDetailFragment details = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(
+                    FileDetailFragment.FTAG);
+            if (details != null && file.equals(details.getDisplayedFile())) {
+                if (downloading || uploading) {
+                    details.updateFileDetails(file, AccountUtils.getCurrentOwnCloudAccount(this));
+                } else {
+                    details.updateFileDetails(downloading || uploading);
+                }
+            }
+        }
+    }
+
+
+    
+
+
+}

+ 436 - 0
src/com/owncloud/android/ui/activity/InstantUploadActivity.java

@@ -0,0 +1,436 @@
+/* ownCloud Android client application
+ *   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 as published by
+ *   the Free Software Foundation, either version 3 of the License, or
+ *   (at your option) any later version.
+ *
+ *   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 java.util.ArrayList;
+import java.util.List;
+
+import android.accounts.Account;
+import android.app.Activity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.Gravity;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.Toast;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.R;
+import com.owncloud.android.db.DbHandler;
+import com.owncloud.android.files.InstantUploadBroadcastReceiver;
+import com.owncloud.android.files.services.FileUploader;
+import com.owncloud.android.files.services.InstantUploadService;
+
+/**
+ * This Activity is used to display a list with images they could not be
+ * uploaded instantly. The images can be selected for delete or for a try again
+ * upload
+ * 
+ * The entrypoint for this activity is the 'Failed upload Notification" and a
+ * submenue underneath the 'Upload' menuentry
+ * 
+ * @author andomaex / Matthias Baumann
+ * 
+ *         This program is free software: you can redistribute it and/or modify
+ *         it under the terms of the GNU General Public License as published by
+ *         the Free Software Foundation, either version 3 of the License, or (at
+ *         your option) any later version.
+ * 
+ *         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 de/
+ */
+public class InstantUploadActivity extends Activity {
+
+    private static final String LOG_TAG = InstantUploadActivity.class.getSimpleName();
+    private LinearLayout listView;
+    private static final String retry_chexbox_tag = "retry_chexbox_tag";
+    private static int MAX_LOAD_IMAGES = 5;
+    private int lastLoadImageIdx = 0;
+
+    private SparseArray<String> fileList = null;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.failed_upload_files);
+
+        Button delete_all_btn = (Button) findViewById(R.id.failed_upload_delete_all_btn);
+        delete_all_btn.setOnClickListener(getDeleteListner());
+        Button retry_all_btn = (Button) findViewById(R.id.failed_upload_retry_all_btn);
+        retry_all_btn.setOnClickListener(getRetryListner());
+        CheckBox failed_upload_all_cb = (CheckBox) findViewById(R.id.failed_upload_headline_cb);
+        failed_upload_all_cb.setOnCheckedChangeListener(getCheckAllListener());
+        listView = (LinearLayout) findViewById(R.id.failed_upload_scrollviewlayout);
+
+        loadListView(true);
+
+    }
+
+    /**
+     * init the listview with ImageButtons, checkboxes and filename for every
+     * Image that was not successfully uploaded
+     * 
+     * this method is call at Activity creation and on delete one ore more
+     * list-entry an on retry the upload by clicking the ImageButton or by click
+     * to the 'retry all' button
+     * 
+     */
+    private void loadListView(boolean reset) {
+        DbHandler db = new DbHandler(getApplicationContext());
+        Cursor c = db.getFailedFiles();
+
+        if (reset) {
+            fileList = new SparseArray<String>();
+            listView.removeAllViews();
+            lastLoadImageIdx = 0;
+        }
+        if (c != null) {
+            try {
+                c.moveToPosition(lastLoadImageIdx);
+
+                while (c.moveToNext()) {
+
+                    lastLoadImageIdx++;
+                    String imp_path = c.getString(1);
+                    fileList.put(lastLoadImageIdx, imp_path);
+                    LinearLayout rowLayout = getLinearLayout(lastLoadImageIdx);
+                    rowLayout.addView(getFileCheckbox(lastLoadImageIdx));
+                    rowLayout.addView(getImageButton(imp_path, lastLoadImageIdx));
+                    rowLayout.addView(getFileButton(imp_path, lastLoadImageIdx));
+                    listView.addView(rowLayout);
+                    Log.d(LOG_TAG, imp_path + " on idx: " + lastLoadImageIdx);
+                    if (lastLoadImageIdx % MAX_LOAD_IMAGES == 0) {
+                        break;
+                    }
+                }
+                if (lastLoadImageIdx > 0) {
+                    addLoadMoreButton(listView);
+                }
+            } finally {
+                db.close();
+            }
+        }
+    }
+
+    private void addLoadMoreButton(LinearLayout listView) {
+        if (listView != null) {
+            Button loadmoreBtn = null;
+            View oldButton = listView.findViewById(42);
+            if (oldButton != null) {
+                // remove existing button
+                listView.removeView(oldButton);
+                // to add the button at the end
+                loadmoreBtn = (Button) oldButton;
+            } else {
+                // create a new button to add to the scoll view
+                loadmoreBtn = new Button(this);
+                loadmoreBtn.setId(42);
+                loadmoreBtn.setText(getString(R.string.failed_upload_load_more_images));
+                loadmoreBtn.setBackgroundResource(R.color.owncloud_white);
+                loadmoreBtn.setTextSize(12);
+                loadmoreBtn.setOnClickListener(new OnClickListener() {
+                    @Override
+                    public void onClick(View v) {
+                        loadListView(false);
+                    }
+
+                });
+            }
+            listView.addView(loadmoreBtn);
+        }
+    }
+
+    /**
+     * provide a list of CheckBox instances, looked up from parent listview this
+     * list ist used to select/deselect all checkboxes at the list
+     * 
+     * @return List<CheckBox>
+     */
+    private List<CheckBox> getCheckboxList() {
+        List<CheckBox> list = new ArrayList<CheckBox>();
+        for (int i = 0; i < listView.getChildCount(); i++) {
+            Log.d(LOG_TAG, "ListView has Childs: " + listView.getChildCount());
+            View childView = listView.getChildAt(i);
+            if (childView != null && childView instanceof ViewGroup) {
+                View checkboxView = getChildViews((ViewGroup) childView);
+                if (checkboxView != null && checkboxView instanceof CheckBox) {
+                    Log.d(LOG_TAG, "found Child: " + checkboxView.getId() + " " + checkboxView.getClass());
+                    list.add((CheckBox) checkboxView);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * recursive called method, used from getCheckboxList method
+     * 
+     * @param View
+     * @return View
+     */
+    private View getChildViews(ViewGroup view) {
+        if (view != null) {
+            for (int i = 0; i < view.getChildCount(); i++) {
+                View cb = view.getChildAt(i);
+                if (cb != null && cb instanceof ViewGroup) {
+                    return getChildViews((ViewGroup) cb);
+                } else if (cb instanceof CheckBox) {
+                    return cb;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * create a new OnCheckedChangeListener for the 'check all' checkbox *
+     * 
+     * @return OnCheckedChangeListener to select all checkboxes at the list
+     */
+    private OnCheckedChangeListener getCheckAllListener() {
+        return new OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                List<CheckBox> list = getCheckboxList();
+                for (CheckBox checkbox : list) {
+                    ((CheckBox) checkbox).setChecked(isChecked);
+                }
+            }
+
+        };
+    }
+
+    /**
+     * Button click Listener for the retry button at the headline
+     * 
+     * @return a Listener to perform a retry for all selected images
+     */
+    private OnClickListener getRetryListner() {
+        return new OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+
+                try {
+                    List<CheckBox> list = getCheckboxList();
+                    for (CheckBox checkbox : list) {
+                        boolean to_retry = checkbox.isChecked();
+
+                        Log.d(LOG_TAG, "Checkbox for " + checkbox.getId() + " was checked: " + to_retry);
+                        String img_path = fileList.get(checkbox.getId());
+                        if (to_retry) {
+
+                            final String msg = "Image-Path " + checkbox.getId() + " was checked: " + img_path;
+                            Log.d(LOG_TAG, msg);
+                            startUpload(img_path);
+                        }
+
+                    }
+                } finally {
+                    // refresh the List
+                    listView.removeAllViews();
+                    loadListView(true);
+                }
+
+            }
+        };
+    }
+
+    /**
+     * Button click Listener for the delete button at the headline
+     * 
+     * @return a Listener to perform a delete for all selected images
+     */
+    private OnClickListener getDeleteListner() {
+
+        return new OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                final DbHandler dbh = new DbHandler(getApplicationContext());
+                try {
+                    List<CheckBox> list = getCheckboxList();
+                    for (CheckBox checkbox : list) {
+                        boolean to_be_delete = checkbox.isChecked();
+
+                        Log.d(LOG_TAG, "Checkbox for " + checkbox.getId() + " was checked: " + to_be_delete);
+                        String img_path = fileList.get(checkbox.getId());
+                        Log.d(LOG_TAG, "Image-Path " + checkbox.getId() + " was checked: " + img_path);
+                        if (to_be_delete) {
+                            boolean deleted = dbh.removeIUPendingFile(img_path);
+                            Log.d(LOG_TAG, "removing " + checkbox.getId() + " was : " + deleted);
+
+                        }
+
+                    }
+                } finally {
+                    dbh.close();
+                    // refresh the List
+                    listView.removeAllViews();
+                    loadListView(true);
+                }
+
+            }
+        };
+    }
+
+    private LinearLayout getLinearLayout(int id) {
+        LinearLayout linearLayout = new LinearLayout(getApplicationContext());
+        linearLayout.setId(id);
+        linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
+                LinearLayout.LayoutParams.MATCH_PARENT));
+        linearLayout.setGravity(Gravity.RIGHT);
+        linearLayout.setOrientation(LinearLayout.HORIZONTAL);
+        return linearLayout;
+    }
+
+    private Button getFileButton(final String img_path, int id) {
+        Button retryButton = new Button(this);
+        retryButton.setId(id);
+        retryButton.setText(img_path);
+        retryButton.setBackgroundResource(R.color.owncloud_white);
+        retryButton.setTextSize(8);
+        retryButton.setOnClickListener(getImageButtonOnClickListener(img_path));
+        return retryButton;
+    }
+
+    private CheckBox getFileCheckbox(int id) {
+        CheckBox retryCB = new CheckBox(this);
+        retryCB.setId(id);
+        retryCB.setBackgroundResource(R.color.owncloud_white);
+        retryCB.setTextSize(8);
+        retryCB.setTag(retry_chexbox_tag);
+        return retryCB;
+    }
+
+    private ImageButton getImageButton(String img_path, int id) {
+        ImageButton imageButton = new ImageButton(this);
+        imageButton.setId(id);
+        imageButton.setClickable(true);
+        imageButton.setOnClickListener(getImageButtonOnClickListener(img_path));
+
+        // scale and add a thumbnail to the imagebutton
+        int base_scale_size = 32;
+        if (img_path != null) {
+            Log.d(LOG_TAG, "add " + img_path + " to Image Button");
+            BitmapFactory.Options options = new BitmapFactory.Options();
+            options.inJustDecodeBounds = true;
+            Bitmap bitmap = BitmapFactory.decodeFile(img_path, options);
+            int width_tpm = options.outWidth, height_tmp = options.outHeight;
+            int scale = 3;
+            while (true) {
+                if (width_tpm / 2 < base_scale_size || height_tmp / 2 < base_scale_size) {
+                    break;
+                }
+                width_tpm /= 2;
+                height_tmp /= 2;
+                scale++;
+            }
+
+            Log.d(LOG_TAG, "scale Imgae with: " + scale);
+            BitmapFactory.Options options2 = new BitmapFactory.Options();
+            options2.inSampleSize = scale;
+            bitmap = BitmapFactory.decodeFile(img_path, options2);
+
+            if (bitmap != null) {
+                Log.d(LOG_TAG, "loaded Bitmap Bytes: " + bitmap.getRowBytes());
+                imageButton.setImageBitmap(bitmap);
+            } else {
+                Log.d(LOG_TAG, "could not load imgage: " + img_path);
+            }
+        }
+        return imageButton;
+    }
+
+    private OnClickListener getImageButtonOnClickListener(final String img_path) {
+        return new OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                startUpload(img_path);
+                loadListView(true);
+            }
+
+        };
+    }
+
+    /**
+     * start uploading a file to the INSTANT_UPLOD_DIR
+     * 
+     * @param img_path
+     */
+    private void startUpload(String img_path) {
+        // extract filename
+        String filename = img_path.substring(img_path.lastIndexOf('/'), img_path.length());
+        if (canInstantUpload()) {
+            Account account = AccountUtils.getCurrentOwnCloudAccount(InstantUploadActivity.this);
+            // add file again to upload queue
+            DbHandler db = new DbHandler(InstantUploadActivity.this);
+            try {
+                db.updateFileState(img_path, DbHandler.UPLOAD_STATUS_UPLOAD_LATER);
+            } finally {
+                db.close();
+            }
+
+            Intent i = new Intent(InstantUploadActivity.this, FileUploader.class);
+            i.putExtra(FileUploader.KEY_ACCOUNT, account);
+            i.putExtra(FileUploader.KEY_LOCAL_FILE, img_path);
+            i.putExtra(FileUploader.KEY_REMOTE_FILE, InstantUploadService.INSTANT_UPLOAD_DIR + "/" + filename);
+            i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
+            i.putExtra(com.owncloud.android.files.services.FileUploader.KEY_INSTANT_UPLOAD, true);
+
+            final String msg = "try to upload file with name :" + filename;
+            Log.d(LOG_TAG, msg);
+            Toast toast = Toast.makeText(InstantUploadActivity.this, getString(R.string.failed_upload_retry_text)
+                    + filename, Toast.LENGTH_LONG);
+            toast.show();
+
+            startService(i);
+        } else {
+            Toast toast = Toast.makeText(InstantUploadActivity.this,
+                    getString(R.string.failed_upload_retry_do_nothing_text) + filename, Toast.LENGTH_LONG);
+            toast.show();
+        }
+    }
+
+    private boolean canInstantUpload() {
+
+        if (!InstantUploadBroadcastReceiver.isOnline(this)
+                || (InstantUploadBroadcastReceiver.instantUploadViaWiFiOnly(this) && !InstantUploadBroadcastReceiver
+                        .isConnectedViaWiFi(this))) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+}