moving from eu.alefzero.eu to com.owncloud.android
authorBartek Przybylski <bart.p.pl@gmail.com>
Tue, 31 Jul 2012 15:43:37 +0000 (17:43 +0200)
committerBartek Przybylski <bart.p.pl@gmail.com>
Tue, 31 Jul 2012 15:43:37 +0000 (17:43 +0200)
129 files changed:
AndroidManifest.xml
res/layout-land/account_setup.xml
res/layout-large-land/files.xml
res/layout/account_setup.xml
res/layout/files.xml
res/layout/pincodelock.xml
src/com/owncloud/android/AccountUtils.java [new file with mode: 0644]
src/com/owncloud/android/CrashHandler.java [new file with mode: 0644]
src/com/owncloud/android/CrashlogSendActivity.java [new file with mode: 0644]
src/com/owncloud/android/DisplayUtils.java [new file with mode: 0644]
src/com/owncloud/android/OwnCloudSession.java [new file with mode: 0644]
src/com/owncloud/android/Uploader.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/AccountAuthenticator.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/AccountAuthenticatorService.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/AuthenticationRunnable.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/ConnectionCheckerRunnable.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/EasySSLSocketFactory.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/EasyX509TrustManager.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/OnAuthenticationResultListener.java [new file with mode: 0644]
src/com/owncloud/android/authenticator/OnConnectCheckListener.java [new file with mode: 0644]
src/com/owncloud/android/datamodel/DataStorageManager.java [new file with mode: 0644]
src/com/owncloud/android/datamodel/FileDataStorageManager.java [new file with mode: 0644]
src/com/owncloud/android/datamodel/OCFile.java [new file with mode: 0644]
src/com/owncloud/android/db/DbHandler.java [new file with mode: 0644]
src/com/owncloud/android/db/ProviderMeta.java [new file with mode: 0644]
src/com/owncloud/android/extensions/ExtensionsAvailableActivity.java [new file with mode: 0644]
src/com/owncloud/android/extensions/ExtensionsAvailableDialog.java [new file with mode: 0644]
src/com/owncloud/android/extensions/ExtensionsListActivity.java [new file with mode: 0644]
src/com/owncloud/android/files/PhotoTakenBroadcastReceiver.java [new file with mode: 0644]
src/com/owncloud/android/files/interfaces/OnDatatransferProgressListener.java [new file with mode: 0644]
src/com/owncloud/android/files/managers/OCNotificationManager.java [new file with mode: 0644]
src/com/owncloud/android/files/services/FileDownloader.java [new file with mode: 0644]
src/com/owncloud/android/files/services/FileOperation.java [new file with mode: 0644]
src/com/owncloud/android/files/services/FileUploader.java [new file with mode: 0644]
src/com/owncloud/android/files/services/InstantUploadService.java [new file with mode: 0644]
src/com/owncloud/android/files/services/OnUploadCompletedListener.java [new file with mode: 0644]
src/com/owncloud/android/location/LocationServiceLauncherReciever.java [new file with mode: 0644]
src/com/owncloud/android/location/LocationUpdateService.java [new file with mode: 0644]
src/com/owncloud/android/providers/FileContentProvider.java [new file with mode: 0644]
src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java [new file with mode: 0644]
src/com/owncloud/android/syncadapter/ContactSyncAdapter.java [new file with mode: 0644]
src/com/owncloud/android/syncadapter/ContactSyncService.java [new file with mode: 0644]
src/com/owncloud/android/syncadapter/FileSyncAdapter.java [new file with mode: 0644]
src/com/owncloud/android/syncadapter/FileSyncService.java [new file with mode: 0644]
src/com/owncloud/android/ui/ActionItem.java [new file with mode: 0644]
src/com/owncloud/android/ui/CustomPopup.java [new file with mode: 0644]
src/com/owncloud/android/ui/FragmentListView.java [new file with mode: 0644]
src/com/owncloud/android/ui/QuickAction.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/AccountSelectActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/AuthenticatorActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/FileDetailActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/FileDisplayActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/LandingActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/PinCodeActivity.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/Preferences.java [new file with mode: 0644]
src/com/owncloud/android/ui/activity/PreferencesNewSession.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/FileListActionListAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/FileListListAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/adapter/LandingScreenAdapter.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/FileDetailFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/FileListFragment.java [new file with mode: 0644]
src/com/owncloud/android/ui/fragment/LandingPageFragment.java [new file with mode: 0644]
src/com/owncloud/android/utils/OwnCloudVersion.java [new file with mode: 0644]
src/com/owncloud/android/widgets/ActionEditText.java [new file with mode: 0644]
src/eu/alefzero/owncloud/AccountUtils.java [deleted file]
src/eu/alefzero/owncloud/CrashHandler.java [deleted file]
src/eu/alefzero/owncloud/CrashlogSendActivity.java [deleted file]
src/eu/alefzero/owncloud/DisplayUtils.java [deleted file]
src/eu/alefzero/owncloud/OwnCloudSession.java [deleted file]
src/eu/alefzero/owncloud/Uploader.java [deleted file]
src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java [deleted file]
src/eu/alefzero/owncloud/authenticator/AccountAuthenticatorService.java [deleted file]
src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java [deleted file]
src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java [deleted file]
src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java [deleted file]
src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java [deleted file]
src/eu/alefzero/owncloud/authenticator/OnAuthenticationResultListener.java [deleted file]
src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java [deleted file]
src/eu/alefzero/owncloud/datamodel/DataStorageManager.java [deleted file]
src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java [deleted file]
src/eu/alefzero/owncloud/datamodel/OCFile.java [deleted file]
src/eu/alefzero/owncloud/db/DbHandler.java [deleted file]
src/eu/alefzero/owncloud/db/ProviderMeta.java [deleted file]
src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java [deleted file]
src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java [deleted file]
src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java [deleted file]
src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java [deleted file]
src/eu/alefzero/owncloud/files/interfaces/OnDatatransferProgressListener.java [deleted file]
src/eu/alefzero/owncloud/files/services/FileDownloader.java [deleted file]
src/eu/alefzero/owncloud/files/services/FileOperation.java [deleted file]
src/eu/alefzero/owncloud/files/services/FileUploader.java [deleted file]
src/eu/alefzero/owncloud/files/services/InstantUploadService.java [deleted file]
src/eu/alefzero/owncloud/files/services/OnUploadCompletedListener.java [deleted file]
src/eu/alefzero/owncloud/location/LocationServiceLauncherReciever.java [deleted file]
src/eu/alefzero/owncloud/location/LocationUpdateService.java [deleted file]
src/eu/alefzero/owncloud/providers/FileContentProvider.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java [deleted file]
src/eu/alefzero/owncloud/syncadapter/FileSyncService.java [deleted file]
src/eu/alefzero/owncloud/ui/ActionItem.java [deleted file]
src/eu/alefzero/owncloud/ui/CustomPopup.java [deleted file]
src/eu/alefzero/owncloud/ui/FragmentListView.java [deleted file]
src/eu/alefzero/owncloud/ui/QuickAction.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/LandingActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/PinCodeActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/Preferences.java [deleted file]
src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java [deleted file]
src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java [deleted file]
src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java [deleted file]
src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java [deleted file]
src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java [deleted file]
src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java [deleted file]
src/eu/alefzero/owncloud/ui/fragment/ConfirmationDialogFragment.java [deleted file]
src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java [deleted file]
src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java [deleted file]
src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java [deleted file]
src/eu/alefzero/owncloud/utils/OwnCloudVersion.java [deleted file]
src/eu/alefzero/owncloud/widgets/ActionEditText.java [deleted file]
src/eu/alefzero/webdav/FileRequestEntity.java
src/eu/alefzero/webdav/WebdavClient.java

index 53a199d..a75fbfb 100644 (file)
@@ -16,7 +16,7 @@
   You should have received a copy of the GNU General Public License\r
   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
  -->\r
-<manifest package="eu.alefzero.owncloud"\r
+<manifest package="com.owncloud.android"\r
     android:versionCode="103000"\r
     android:versionName="1.3.0" xmlns:android="http://schemas.android.com/apk/res/android">\r
 \r
 \r
         <service android:name=".files.services.FileDownloader" >\r
         </service>\r
-        <service android:name=".location.LocationUpdateService" >\r
-            <intent-filter>\r
-                <action android:name="eu.alefzero.owncloud.location.LocationUpdateService" />\r
-            </intent-filter>\r
-        </service>\r
 \r
         <activity android:name=".ui.activity.FileDetailActivity" />
         <activity android:name=".ui.activity.PinCodeActivity" />\r
index 1420234..1a452dd 100644 (file)
@@ -17,7 +17,7 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
+    xmlns:oc="http://schemas.android.com/apk/res/com.owncloud.android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:focusable="true"
         </LinearLayout>
     </RelativeLayout>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
index 32d86b0..13d16f9 100644 (file)
@@ -32,7 +32,7 @@
             android:id="@+id/fileList"\r
             android:layout_width="fill_parent"\r
             android:layout_height="fill_parent"\r
-            class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >\r
+            class="com.owncloud.android.ui.fragment.FileListFragment" >\r
 \r
             <!-- Preview: layout=@layout/list_layout -->\r
         </fragment>\r
@@ -46,4 +46,4 @@
         <!-- Preview: layout=@layout/file_details_empty -->\r
     </LinearLayout>\r
 \r
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>\r
index 65e1cd9..5f12872 100644 (file)
@@ -17,7 +17,7 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
+    xmlns:oc="http://schemas.android.com/apk/res/com.owncloud.android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:focusable="true"
         </LinearLayout>
     </RelativeLayout>
 
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
index 9f868ca..78f8daf 100644 (file)
@@ -27,9 +27,9 @@
         android:id="@+id/fileList"\r
         android:layout_width="fill_parent"\r
         android:layout_height="fill_parent"\r
-        class="eu.alefzero.owncloud.ui.fragment.FileListFragment" >\r
+        class="com.owncloud.android.ui.fragment.FileListFragment" >\r
 \r
         <!-- Preview: layout=@layout/list_layout -->\r
     </fragment>\r
 \r
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>\r
index 61645fe..a02ca26 100644 (file)
@@ -16,7 +16,7 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
 -->\r
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
-    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"\r
+    xmlns:oc="http://schemas.android.com/apk/res/com.owncloud.android"\r
     android:layout_width="fill_parent"\r
     android:layout_height="fill_parent"\r
     android:gravity="center_horizontal"\r
@@ -62,4 +62,4 @@
         android:text="@android:string/cancel"\r
         android:textColor="@android:color/black"\r
         android:id="@+id/cancel"/>\r
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>\r
diff --git a/src/com/owncloud/android/AccountUtils.java b/src/com/owncloud/android/AccountUtils.java
new file mode 100644 (file)
index 0000000..9c48793
--- /dev/null
@@ -0,0 +1,109 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2012  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android;\r
+\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.utils.OwnCloudVersion;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.content.Context;\r
+import android.content.SharedPreferences;\r
+import android.preference.PreferenceManager;\r
+\r
+public class AccountUtils {\r
+    public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";\r
+    public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";\r
+    public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";\r
+    public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";\r
+    public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";\r
+    public static final String STATUS_PATH = "/status.php";\r
+\r
+    /**\r
+     * Can be used to get the currently selected ownCloud account in the\r
+     * preferences\r
+     * \r
+     * @param context The current appContext\r
+     * @return The current account or first available, if none is available,\r
+     *         then null.\r
+     */\r
+    public static Account getCurrentOwnCloudAccount(Context context) {\r
+        Account[] ocAccounts = AccountManager.get(context).getAccountsByType(\r
+                AccountAuthenticator.ACCOUNT_TYPE);\r
+        Account defaultAccount = null;\r
+\r
+        SharedPreferences appPreferences = PreferenceManager\r
+                .getDefaultSharedPreferences(context);\r
+        String accountName = appPreferences\r
+                .getString("select_oc_account", null);\r
+\r
+        if (accountName != null) {\r
+            for (Account account : ocAccounts) {\r
+                if (account.name.equals(accountName)) {\r
+                    defaultAccount = account;\r
+                    break;\r
+                }\r
+            }\r
+        } else if (ocAccounts.length != 0) {\r
+            // we at least need to take first account as fallback\r
+            defaultAccount = ocAccounts[0];\r
+        }\r
+\r
+        return defaultAccount;\r
+    }\r
+\r
+    \r
+\r
+    /**\r
+     * Checks, whether or not there are any ownCloud accounts setup.\r
+     * \r
+     * @return true, if there is at least one account.\r
+     */\r
+    public static boolean accountsAreSetup(Context context) {\r
+        AccountManager accMan = AccountManager.get(context);\r
+        Account[] accounts = accMan\r
+                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
+        return accounts.length > 0;\r
+    }\r
+    \r
+    \r
+    public static void setCurrentOwnCloudAccount(Context context, String name) {\r
+        SharedPreferences.Editor appPrefs = PreferenceManager\r
+                .getDefaultSharedPreferences(context).edit();\r
+        appPrefs.putString("select_oc_account", name);\r
+        appPrefs.commit();\r
+    }\r
+\r
+    /**\r
+     * \r
+     * @param version version of owncloud\r
+     * @return webdav path for given OC version, null if OC version unknown\r
+     */\r
+    public static String getWebdavPath(OwnCloudVersion version) {\r
+        if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0)\r
+            return WEBDAV_PATH_4_0;\r
+        if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0\r
+                || version.compareTo(OwnCloudVersion.owncloud_v2) >= 0)\r
+            return WEBDAV_PATH_2_0;\r
+        if (version.compareTo(OwnCloudVersion.owncloud_v1) >= 0)\r
+            return WEBDAV_PATH_1_2;\r
+        return null;\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/CrashHandler.java b/src/com/owncloud/android/CrashHandler.java
new file mode 100644 (file)
index 0000000..e2ceb10
--- /dev/null
@@ -0,0 +1,154 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.net.ConnectivityManager;
+import android.os.Environment;
+import android.util.Log;
+
+public class CrashHandler implements UncaughtExceptionHandler {
+
+    public static final String KEY_CRASH_FILENAME = "KEY_CRASH_FILENAME";
+    
+    private Context mContext;
+    private static final String TAG = "CrashHandler";
+    private static final String crash_filename_template = "crash";
+    private static List<String> TAGS;
+    private UncaughtExceptionHandler defaultUEH;
+    
+    // TODO: create base activity which will register for crashlog tag automaticly
+    static {
+        TAGS = new LinkedList<String>();
+        TAGS.add("AccountAuthenticator");
+        TAGS.add("AccountAuthenticator");
+        TAGS.add("ConnectionCheckerRunnable");
+        TAGS.add("EasySSLSocketFactory");
+        TAGS.add("FileDataStorageManager");
+        TAGS.add("PhotoTakenBroadcastReceiver");
+        TAGS.add("InstantUploadService");
+        TAGS.add("FileDownloader");
+        TAGS.add("FileUploader");
+        TAGS.add("LocationUpdateService");
+        TAGS.add("FileSyncAdapter");
+        TAGS.add("AuthActivity");
+        TAGS.add("OwnCloudPreferences");
+        TAGS.add("FileDetailFragment");
+        TAGS.add("FileListFragment");
+        TAGS.add("ownCloudUploader");
+        TAGS.add("WebdavClient");
+    }
+    
+    public CrashHandler(Context context) {
+        mContext = context;
+        defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
+    }
+    
+    @Override
+    public void uncaughtException(Thread thread, Throwable ex) {
+        final Writer writer = new StringWriter();
+        final PrintWriter printwriter = new PrintWriter(writer);
+        ex.printStackTrace(printwriter);
+        final String startrace = writer.toString();
+        printwriter.close();
+        File ocdir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), "owncloud");
+        ocdir.mkdirs();
+
+        String crash_filename = crash_filename_template + System.currentTimeMillis() + ".txt";
+        File crashfile = new File(ocdir, crash_filename);
+        try {
+            PackageInfo pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
+            ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+            String header = String.format("Model: %s, SDK: %d, Current net: %s AppVersion: %s\n\n",
+                                          android.os.Build.MODEL,
+                                          android.os.Build.VERSION.SDK_INT,
+                                          cm.getActiveNetworkInfo() != null ? cm.getActiveNetworkInfo().getTypeName() : "NONE",
+                                          pi.versionName);
+            Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
+            AccountManager am = AccountManager.get(mContext);
+            String header2 = String.format("Account: %s, OCUrl: %s, OCVersion: %s\n\n",
+                                           account.name,
+                                           am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL),
+                                           am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
+            
+            crashfile.createNewFile();
+            FileWriter fw = new FileWriter(crashfile);
+            fw.write(header);
+            fw.write(header2);
+            fw.write(startrace);
+            fw.write("\n\n");
+            
+            String logcat = "logcat -d *:S ";
+            
+            for (String s : TAGS)
+                logcat += s + ":V ";
+            
+            Process process = Runtime.getRuntime().exec(logcat);
+            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            String logline;
+            while ((logline = br.readLine()) != null)
+                fw.write(logline+"\n");
+            
+            br.close();
+            fw.close();
+            
+            Intent dataintent = new Intent(mContext, CrashlogSendActivity.class);
+            dataintent.putExtra(KEY_CRASH_FILENAME, crashfile.getAbsolutePath());
+            PendingIntent intent;
+            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+                intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+            } else {
+                intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            }
+            AlarmManager mngr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+            if (mngr == null) {
+                Log.e(TAG, "Couldn't retrieve alarm manager!");
+                defaultUEH.uncaughtException(thread, ex);
+                return;
+            }
+            mngr.set(AlarmManager.RTC, System.currentTimeMillis(), intent);
+            System.exit(2);
+        } catch (Exception e1) {
+            Log.e(TAG, "Crash handler failed!");
+            Log.e(TAG, e1.toString());
+            defaultUEH.uncaughtException(thread, ex);
+            return;
+        }
+    }
+}
diff --git a/src/com/owncloud/android/CrashlogSendActivity.java b/src/com/owncloud/android/CrashlogSendActivity.java
new file mode 100644 (file)
index 0000000..7f4074f
--- /dev/null
@@ -0,0 +1,112 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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;
+
+import java.io.File;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.actionbarsherlock.app.SherlockActivity;
+
+import com.owncloud.android.R;
+
+public class CrashlogSendActivity extends SherlockActivity implements OnClickListener, OnCancelListener {
+    
+    private static final String TAG = "CrashlogSendActivity";
+    private static final String CRASHLOG_SUBMIT_URL = "http://alefzero.eu/a/crashlog/";
+    private static final int DIALOG_SUBMIT = 5;
+    
+    private String mLogFilename;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mLogFilename = getIntent().getStringExtra(CrashHandler.KEY_CRASH_FILENAME);
+        if (mLogFilename == null) {
+            Log.wtf(TAG, "No file crashlog path given!");
+            finish();
+            return;
+        }
+        Log.i(TAG, "crashlog file path " + mLogFilename);
+        
+        showDialog(DIALOG_SUBMIT);
+    }
+    
+
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        if (id == DIALOG_SUBMIT) {
+            AlertDialog.Builder builder = new AlertDialog.Builder(this);
+            builder.setMessage(R.string.crashlog_message);
+            builder.setNegativeButton(R.string.crashlog_dont_send_report, this);
+            builder.setPositiveButton(R.string.crashlog_send_report, this);
+            builder.setCancelable(true);
+            builder.setOnCancelListener(this);
+            return builder.create();
+        }
+        return super.onCreateDialog(id);
+    }
+
+
+    @Override
+    public void onClick(DialogInterface dialog, final int which) {
+        new Thread(new Runnable() {
+            
+            @Override
+            public void run() {
+                // TODO Auto-generated method stub
+                File file = new File(mLogFilename);
+                if (which == Dialog.BUTTON_POSITIVE) {
+                    try {
+                        HttpClient client = new HttpClient();
+                        PostMethod post = new PostMethod(CRASHLOG_SUBMIT_URL);
+                        Part[] parts = {new FilePart("crashfile", file)};
+                        post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
+                        client.executeMethod(post);
+                        post.releaseConnection();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+                file.delete();
+                finish();                
+            }
+        }).start();
+    }
+
+
+    @Override
+    public void onCancel(DialogInterface dialog) {
+        new File(mLogFilename).delete();
+        finish();
+    }
+
+}
diff --git a/src/com/owncloud/android/DisplayUtils.java b/src/com/owncloud/android/DisplayUtils.java
new file mode 100644 (file)
index 0000000..a9cfe1d
--- /dev/null
@@ -0,0 +1,117 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android;\r
+\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+\r
+/**\r
+ * A helper class for some string operations.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class DisplayUtils {\r
+\r
+    private static final String[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };\r
+\r
+    private static HashMap<String, String> mimeType2HUmanReadable;\r
+    static {\r
+        mimeType2HUmanReadable = new HashMap<String, String>();\r
+        // images\r
+        mimeType2HUmanReadable.put("image/jpeg", "JPEG image");\r
+        mimeType2HUmanReadable.put("image/jpg", "JPEG image");\r
+        mimeType2HUmanReadable.put("image/png", "PNG image");\r
+        mimeType2HUmanReadable.put("image/bmp", "Bitmap image");\r
+        mimeType2HUmanReadable.put("image/gif", "GIF image");\r
+        mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");\r
+        mimeType2HUmanReadable.put("image/tiff", "TIFF image");\r
+        // music\r
+        mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");\r
+        mimeType2HUmanReadable.put("application/ogg", "OGG music file");\r
+\r
+    }\r
+\r
+    /**\r
+     * Converts the file size in bytes to human readable output.\r
+     * \r
+     * @param bytes Input file size\r
+     * @return Like something readable like "12 MB"\r
+     */\r
+    public static String bytesToHumanReadable(long bytes) {\r
+        double result = bytes;\r
+        int attachedsuff = 0;\r
+        while (result > 1024 && attachedsuff < suffixes.length) {\r
+            result /= 1024.;\r
+            attachedsuff++;\r
+        }\r
+        result = ((int) (result * 100)) / 100.;\r
+        return result + " " + suffixes[attachedsuff];\r
+    }\r
+\r
+    /**\r
+     * Removes special HTML entities from a string\r
+     * \r
+     * @param s Input string\r
+     * @return A cleaned version of the string\r
+     */\r
+    public static String HtmlDecode(String s) {\r
+        /*\r
+         * TODO: Perhaps we should use something more proven like:\r
+         * http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/StringEscapeUtils.html#unescapeHtml%28java.lang.String%29\r
+         */\r
+\r
+        String ret = "";\r
+        for (int i = 0; i < s.length(); ++i) {\r
+            if (s.charAt(i) == '%') {\r
+                ret += (char) Integer.parseInt(s.substring(i + 1, i + 3), 16);\r
+                i += 2;\r
+            } else {\r
+                ret += s.charAt(i);\r
+            }\r
+        }\r
+        return ret;\r
+    }\r
+\r
+    /**\r
+     * Converts MIME types like "image/jpg" to more end user friendly output\r
+     * like "JPG image".\r
+     * \r
+     * @param mimetype MIME type to convert\r
+     * @return A human friendly version of the MIME type\r
+     */\r
+    public static String convertMIMEtoPrettyPrint(String mimetype) {\r
+        if (mimeType2HUmanReadable.containsKey(mimetype)) {\r
+            return mimeType2HUmanReadable.get(mimetype);\r
+        }\r
+        if (mimetype.split("/").length >= 2)\r
+            return mimetype.split("/")[1].toUpperCase() + " file";\r
+        return "Unknown type";\r
+    }\r
+\r
+    /**\r
+     * Converts Unix time to human readable format\r
+     * @param miliseconds that have passed since 01/01/1970\r
+     * @return The human readable time for the users locale\r
+     */\r
+    public static String unixTimeToHumanReadable(long milliseconds) {\r
+        Date date = new Date(milliseconds);\r
+        return date.toLocaleString();\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/OwnCloudSession.java b/src/com/owncloud/android/OwnCloudSession.java
new file mode 100644 (file)
index 0000000..67f9b8e
--- /dev/null
@@ -0,0 +1,56 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android;\r
+\r
+/**\r
+ * Represents a session to an ownCloud instance\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class OwnCloudSession {\r
+    private String mSessionName;\r
+    private String mSessionUrl;\r
+    private int mEntryId;\r
+\r
+    public OwnCloudSession(String name, String url, int entryId) {\r
+        mSessionName = name;\r
+        mSessionUrl = url;\r
+        mEntryId = entryId;\r
+    }\r
+\r
+    public void setName(String name) {\r
+        mSessionName = name;\r
+    }\r
+\r
+    public String getName() {\r
+        return mSessionName;\r
+    }\r
+\r
+    public void setUrl(String url) {\r
+        mSessionUrl = url;\r
+    }\r
+\r
+    public String getUrl() {\r
+        return mSessionUrl;\r
+    }\r
+\r
+    public int getEntryId() {\r
+        return mEntryId;\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/Uploader.java b/src/com/owncloud/android/Uploader.java
new file mode 100644 (file)
index 0000000..718911d
--- /dev/null
@@ -0,0 +1,415 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2012  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.LinkedList;\r
+import java.util.List;\r
+import java.util.Stack;\r
+import java.util.Vector;\r
+\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.datamodel.DataStorageManager;\r
+import com.owncloud.android.datamodel.FileDataStorageManager;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.files.services.FileUploader;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.AlertDialog.Builder;\r
+import android.app.Dialog;\r
+import android.app.ListActivity;\r
+import android.app.ProgressDialog;\r
+import android.content.Context;\r
+import android.content.DialogInterface;\r
+import android.content.DialogInterface.OnCancelListener;\r
+import android.content.DialogInterface.OnClickListener;\r
+import android.content.Intent;\r
+import android.database.Cursor;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.Parcelable;\r
+import android.provider.MediaStore.Images.Media;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.Window;\r
+import android.widget.AdapterView;\r
+import android.widget.AdapterView.OnItemClickListener;\r
+import android.widget.Button;\r
+import android.widget.EditText;\r
+import android.widget.SimpleAdapter;\r
+import com.owncloud.android.R;\r
+import eu.alefzero.webdav.WebdavClient;\r
+\r
+/**\r
+ * This can be used to upload things to an ownCloud instance.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {\r
+    private static final String TAG = "ownCloudUploader";\r
+\r
+    private Account mAccount;\r
+    private AccountManager mAccountManager;\r
+    private Stack<String> mParents;\r
+    private ArrayList<Parcelable> mStreamsToUpload;\r
+    private boolean mCreateDir;\r
+    private String mUploadPath;\r
+    private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };\r
+    private DataStorageManager mStorageManager;\r
+    private OCFile mFile;\r
+\r
+    private final static int DIALOG_NO_ACCOUNT = 0;\r
+    private final static int DIALOG_WAITING = 1;\r
+    private final static int DIALOG_NO_STREAM = 2;\r
+    private final static int DIALOG_MULTIPLE_ACCOUNT = 3;\r
+    private final static int DIALOG_GET_DIRNAME = 4;\r
+\r
+    private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+        mParents = new Stack<String>();\r
+        mParents.add("");\r
+        if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {\r
+            prepareStreamsToUpload();\r
+            mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);\r
+            Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
+            if (accounts.length == 0) {\r
+                Log.i(TAG, "No ownCloud account is available");\r
+                showDialog(DIALOG_NO_ACCOUNT);\r
+            } else if (accounts.length > 1) {\r
+                Log.i(TAG, "More then one ownCloud is available");\r
+                showDialog(DIALOG_MULTIPLE_ACCOUNT);\r
+            } else {\r
+                mAccount = accounts[0];\r
+                setContentView(R.layout.uploader_layout);\r
+                mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());\r
+                populateDirectoryList();\r
+            }\r
+        } else {\r
+            showDialog(DIALOG_NO_STREAM);\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    protected Dialog onCreateDialog(final int id) {\r
+        final AlertDialog.Builder builder = new Builder(this);\r
+        switch (id) {\r
+        case DIALOG_WAITING:\r
+            ProgressDialog pDialog = new ProgressDialog(this);\r
+            pDialog.setIndeterminate(false);\r
+            pDialog.setCancelable(false);\r
+            pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));\r
+            return pDialog;\r
+        case DIALOG_NO_ACCOUNT:\r
+            builder.setIcon(android.R.drawable.ic_dialog_alert);\r
+            builder.setTitle(R.string.uploader_wrn_no_account_title);\r
+            builder.setMessage(R.string.uploader_wrn_no_account_text);\r
+            builder.setCancelable(false);\r
+            builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {\r
+                public void onClick(DialogInterface dialog, int which) {\r
+                    if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {\r
+                        // using string value since in API7 this\r
+                        // constatn is not defined\r
+                        // in API7 < this constatant is defined in\r
+                        // Settings.ADD_ACCOUNT_SETTINGS\r
+                        // and Settings.EXTRA_AUTHORITIES\r
+                        Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+                        intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+                        startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);\r
+                    } else {\r
+                        // since in API7 there is no direct call for\r
+                        // account setup, so we need to\r
+                        // show our own AccountSetupAcricity, get\r
+                        // desired results and setup\r
+                        // everything for ourself\r
+                        Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);\r
+                        startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);\r
+                    }\r
+                }\r
+            });\r
+            builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {\r
+                public void onClick(DialogInterface dialog, int which) {\r
+                    finish();\r
+                }\r
+            });\r
+            return builder.create();\r
+        /*case DIALOG_GET_DIRNAME:\r
+            final EditText dirName = new EditText(getBaseContext());\r
+            builder.setView(dirName);\r
+            builder.setTitle(R.string.uploader_info_dirname);\r
+            String pathToUpload;\r
+            if (mParents.empty()) {\r
+                pathToUpload = "/";\r
+            } else {\r
+                mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), null,\r
+                        null, null, null);\r
+                mCursor.moveToFirst();\r
+                pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))\r
+                        + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");   // TODO don't make this ; use WebdavUtils.encode in the right moment\r
+            }\r
+            a a = new a(pathToUpload, dirName);\r
+            builder.setPositiveButton(R.string.common_ok, a);\r
+            builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {\r
+                public void onClick(DialogInterface dialog, int which) {\r
+                    dialog.cancel();\r
+                }\r
+            });\r
+            return builder.create();*/\r
+        case DIALOG_MULTIPLE_ACCOUNT:\r
+            CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];\r
+            for (int i = 0; i < ac.length; ++i) {\r
+                ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;\r
+            }\r
+            builder.setTitle(R.string.common_choose_account);\r
+            builder.setItems(ac, new OnClickListener() {\r
+                public void onClick(DialogInterface dialog, int which) {\r
+                    mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];\r
+                    mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());\r
+                    populateDirectoryList();\r
+                }\r
+            });\r
+            builder.setCancelable(true);\r
+            builder.setOnCancelListener(new OnCancelListener() {\r
+                public void onCancel(DialogInterface dialog) {\r
+                    dialog.cancel();\r
+                    finish();\r
+                }\r
+            });\r
+            return builder.create();\r
+        default:\r
+            throw new IllegalArgumentException("Unknown dialog id: " + id);\r
+        }\r
+    }\r
+\r
+    class a implements OnClickListener {\r
+        String mPath;\r
+        EditText mDirname;\r
+\r
+        public a(String path, EditText dirname) {\r
+            mPath = path; \r
+            mDirname = dirname;\r
+        }\r
+\r
+        public void onClick(DialogInterface dialog, int which) {\r
+            Uploader.this.mUploadPath = mPath + mDirname.getText().toString();\r
+            Uploader.this.mCreateDir = true;\r
+            uploadFiles();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void onBackPressed() {\r
+\r
+        if (mParents.size() <= 1) {\r
+            super.onBackPressed();\r
+            return;\r
+        } else {\r
+            mParents.pop();\r
+            populateDirectoryList();\r
+        }\r
+    }\r
+\r
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\r
+        // click on folder in the list\r
+        Log.d(TAG, "on item click");\r
+        Vector<OCFile> tmpfiles = mStorageManager.getDirectoryContent(mFile);\r
+        if (tmpfiles == null) return;\r
+        // filter on dirtype\r
+        Vector<OCFile> files = new Vector<OCFile>();\r
+        for (OCFile f : tmpfiles)\r
+            if (f.isDirectory())\r
+                files.add(f);\r
+        if (files.size() < position) {\r
+            throw new IndexOutOfBoundsException("Incorrect item selected");\r
+        }\r
+        mParents.push(files.get(position).getFileName());\r
+        populateDirectoryList();\r
+    }\r
+\r
+    public void onClick(View v) {\r
+        // click on button\r
+        switch (v.getId()) {\r
+        case R.id.uploader_choose_folder:\r
+            mUploadPath = "";   // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix\r
+            for (String p : mParents)\r
+                mUploadPath += p + OCFile.PATH_SEPARATOR;\r
+            Log.d(TAG, "Uploading file to dir " + mUploadPath);\r
+\r
+            uploadFiles();\r
+\r
+            break;\r
+        case android.R.id.button1: // dynamic action for create aditional dir\r
+            showDialog(DIALOG_GET_DIRNAME);\r
+            break;\r
+        default:\r
+            throw new IllegalArgumentException("Wrong element clicked");\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        super.onActivityResult(requestCode, resultCode, data);\r
+        Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);\r
+        if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {\r
+            dismissDialog(DIALOG_NO_ACCOUNT);\r
+            if (resultCode == RESULT_CANCELED) {\r
+                finish();\r
+            }\r
+            Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);\r
+            if (accounts.length == 0) {\r
+                showDialog(DIALOG_NO_ACCOUNT);\r
+            } else {\r
+                // there is no need for checking for is there more then one\r
+                // account at this point\r
+                // since account setup can set only one account at time\r
+                mAccount = accounts[0];\r
+                populateDirectoryList();\r
+            }\r
+        }\r
+    }\r
+\r
+    private void populateDirectoryList() {\r
+        setContentView(R.layout.uploader_layout);\r
+\r
+        String full_path = "";\r
+        for (String a : mParents)\r
+            full_path += a + "/";\r
+        \r
+        Log.d(TAG, "Populating view with content of : " + full_path);\r
+        \r
+        mFile = mStorageManager.getFileByPath(full_path);\r
+        if (mFile != null) {\r
+            Vector<OCFile> files = mStorageManager.getDirectoryContent(mFile);\r
+            if (files != null) {\r
+                List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();\r
+                for (OCFile f : files) {\r
+                    HashMap<String, Object> h = new HashMap<String, Object>();\r
+                    if (f.isDirectory()) {\r
+                        h.put("dirname", f.getFileName());\r
+                        data.add(h);\r
+                    }\r
+                }\r
+                SimpleAdapter sa = new SimpleAdapter(this,\r
+                                                     data,\r
+                                                     R.layout.uploader_list_item_layout,\r
+                                                     new String[] {"dirname"},\r
+                                                     new int[] {R.id.textView1});\r
+                setListAdapter(sa);\r
+                Button btn = (Button) findViewById(R.id.uploader_choose_folder);\r
+                btn.setOnClickListener(this);\r
+                getListView().setOnItemClickListener(this);\r
+            }\r
+        }\r
+        /*\r
+        mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI, null, ProviderTableMeta.FILE_NAME\r
+                + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", new String[] { "/", mAccount.name }, null);\r
+\r
+        if (mCursor.moveToFirst()) {\r
+            mCursor = managedQuery(\r
+                    ProviderMeta.ProviderTableMeta.CONTENT_URI,\r
+                    null,\r
+                    ProviderTableMeta.FILE_CONTENT_TYPE + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "\r
+                            + ProviderTableMeta.FILE_PARENT + "=?",\r
+                    new String[] { "DIR", mAccount.name,\r
+                            mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID)) }, null);\r
+\r
+            ListView lv = getListView();\r
+            lv.setOnItemClickListener(this);\r
+            SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout, mCursor,\r
+                    new String[] { ProviderTableMeta.FILE_NAME }, new int[] { R.id.textView1 });\r
+            setListAdapter(sca);\r
+            Button btn = (Button) findViewById(R.id.uploader_choose_folder);\r
+            btn.setOnClickListener(this);\r
+            /*\r
+             * disable this until new server interaction service wont be created\r
+             * // insert create new directory for multiple items uploading if\r
+             * (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {\r
+             * Button createDirBtn = new Button(this);\r
+             * createDirBtn.setId(android.R.id.button1);\r
+             * createDirBtn.setText(R.string.uploader_btn_create_dir_text);\r
+             * createDirBtn.setOnClickListener(this); ((LinearLayout)\r
+             * findViewById(R.id.linearLayout1)).addView( createDirBtn,\r
+             * LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); }\r
+             *\r
+        }*/\r
+    }\r
+\r
+    private void prepareStreamsToUpload() {\r
+        if (getIntent().getAction().equals(Intent.ACTION_SEND)) {\r
+            mStreamsToUpload = new ArrayList<Parcelable>();\r
+            mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));\r
+        } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {\r
+            mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);\r
+        } else {\r
+            // unknow action inserted\r
+            throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());\r
+        }\r
+    }\r
+\r
+    public void uploadFiles() {\r
+        WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());\r
+        wdc.allowSelfsignedCertificates();\r
+\r
+        // create last directory in path if nessesary\r
+        if (mCreateDir) {\r
+            wdc.createDirectory(mUploadPath);\r
+        }\r
+\r
+        String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];\r
+\r
+        for (int i = 0; i < mStreamsToUpload.size(); ++i) {\r
+            Uri uri = (Uri) mStreamsToUpload.get(i);\r
+            if (uri.getScheme().equals("content")) {\r
+                Cursor c = getContentResolver().query((Uri) mStreamsToUpload.get(i),\r
+                                                      CONTENT_PROJECTION,\r
+                                                      null,\r
+                                                      null,\r
+                                                      null);\r
+\r
+                if (!c.moveToFirst())\r
+                    continue;\r
+\r
+                final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),\r
+                             data = c.getString(c.getColumnIndex(Media.DATA));\r
+                local[i] = data;\r
+                remote[i] = mUploadPath + display_name;\r
+            } else if (uri.getScheme().equals("file")) {\r
+                final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));\r
+                local[i] = file.getAbsolutePath();\r
+                remote[i] = mUploadPath + file.getName();\r
+            }\r
+\r
+        }\r
+        Intent intent = new Intent(getApplicationContext(), FileUploader.class);\r
+        intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);\r
+        intent.putExtra(FileUploader.KEY_LOCAL_FILE, local);\r
+        intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote);\r
+        intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);\r
+        startService(intent);\r
+        finish();\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/authenticator/AccountAuthenticator.java b/src/com/owncloud/android/authenticator/AccountAuthenticator.java
new file mode 100644 (file)
index 0000000..543b0df
--- /dev/null
@@ -0,0 +1,281 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2012  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.authenticator;\r
+\r
+import com.owncloud.android.ui.activity.AuthenticatorActivity;\r
+\r
+import android.accounts.*;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+\r
+public class AccountAuthenticator extends AbstractAccountAuthenticator {\r
+    /**\r
+     * Is used by android system to assign accounts to authenticators. Should be\r
+     * used by application and all extensions.\r
+     */\r
+    public static final String ACCOUNT_TYPE = "owncloud";\r
+    public static final String AUTH_TOKEN_TYPE = "org.owncloud";\r
+\r
+    public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";\r
+    public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";\r
+    public static final String KEY_LOGIN_OPTIONS = "loginOptions";\r
+    public static final String KEY_ACCOUNT = "account";\r
+    /**\r
+     * Value under this key should handle path to webdav php script. Will be\r
+     * removed and usage should be replaced by combining\r
+     * {@link eu.alefzero.owncloud.authenticator.KEY_OC_BASE_URL} and\r
+     * {@link com.owncloud.android.utils.OwnCloudVersion}\r
+     * \r
+     * @deprecated\r
+     */\r
+    public static final String KEY_OC_URL = "oc_url";\r
+    /**\r
+     * Version should be 3 numbers separated by dot so it can be parsed by\r
+     * {@link com.owncloud.android.utils.OwnCloudVersion}\r
+     */\r
+    public static final String KEY_OC_VERSION = "oc_version";\r
+    /**\r
+     * Base url should point to owncloud installation without trailing / ie:\r
+     * http://server/path or https://owncloud.server\r
+     */\r
+    public static final String KEY_OC_BASE_URL = "oc_base_url";\r
+\r
+    private static final String TAG = "AccountAuthenticator";\r
+    private Context mContext;\r
+\r
+    public AccountAuthenticator(Context context) {\r
+        super(context);\r
+        mContext = context;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Bundle addAccount(AccountAuthenticatorResponse response,\r
+            String accountType, String authTokenType,\r
+            String[] requiredFeatures, Bundle options)\r
+            throws NetworkErrorException {\r
+        Log.i(TAG, "Adding account with type " + accountType\r
+                + " and auth token " + authTokenType);\r
+        try {\r
+            validateAccountType(accountType);\r
+        } catch (AuthenticatorException e) {\r
+            Log.e(TAG, "Failed to validate account type " + accountType + ": "\r
+                    + e.getMessage());\r
+            e.printStackTrace();\r
+            return e.getFailureBundle();\r
+        }\r
+        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
+                response);\r
+        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);\r
+        intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);\r
+        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
+\r
+        setIntentFlags(intent);\r
+        final Bundle bundle = new Bundle();\r
+        bundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
+        return bundle;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Bundle confirmCredentials(AccountAuthenticatorResponse response,\r
+            Account account, Bundle options) throws NetworkErrorException {\r
+        try {\r
+            validateAccountType(account.type);\r
+        } catch (AuthenticatorException e) {\r
+            Log.e(TAG, "Failed to validate account type " + account.type + ": "\r
+                    + e.getMessage());\r
+            e.printStackTrace();\r
+            return e.getFailureBundle();\r
+        }\r
+        Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
+                response);\r
+        intent.putExtra(KEY_ACCOUNT, account);\r
+        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
+\r
+        setIntentFlags(intent);\r
+\r
+        Bundle resultBundle = new Bundle();\r
+        resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
+        return resultBundle;\r
+    }\r
+\r
+    @Override\r
+    public Bundle editProperties(AccountAuthenticatorResponse response,\r
+            String accountType) {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public Bundle getAuthToken(AccountAuthenticatorResponse response,\r
+            Account account, String authTokenType, Bundle options)\r
+            throws NetworkErrorException {\r
+        try {\r
+            validateAccountType(account.type);\r
+            validateAuthTokenType(authTokenType);\r
+        } catch (AuthenticatorException e) {\r
+            Log.e(TAG, "Failed to validate account type " + account.type + ": "\r
+                    + e.getMessage());\r
+            e.printStackTrace();\r
+            return e.getFailureBundle();\r
+        }\r
+        final AccountManager am = AccountManager.get(mContext);\r
+        final String password = am.getPassword(account);\r
+        if (password != null) {\r
+            final Bundle result = new Bundle();\r
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);\r
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);\r
+            result.putString(AccountManager.KEY_AUTHTOKEN, password);\r
+            return result;\r
+        }\r
+\r
+        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
+                response);\r
+        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);\r
+        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
+        intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);\r
+\r
+        final Bundle bundle = new Bundle();\r
+        bundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
+        return bundle;\r
+    }\r
+\r
+    @Override\r
+    public String getAuthTokenLabel(String authTokenType) {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public Bundle hasFeatures(AccountAuthenticatorResponse response,\r
+            Account account, String[] features) throws NetworkErrorException {\r
+        final Bundle result = new Bundle();\r
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public Bundle updateCredentials(AccountAuthenticatorResponse response,\r
+            Account account, String authTokenType, Bundle options)\r
+            throws NetworkErrorException {\r
+        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
+                response);\r
+        intent.putExtra(KEY_ACCOUNT, account);\r
+        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);\r
+        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
+        setIntentFlags(intent);\r
+\r
+        final Bundle bundle = new Bundle();\r
+        bundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
+        return bundle;\r
+    }\r
+\r
+    @Override\r
+    public Bundle getAccountRemovalAllowed(\r
+            AccountAuthenticatorResponse response, Account account)\r
+            throws NetworkErrorException {\r
+        return super.getAccountRemovalAllowed(response, account);\r
+    }\r
+\r
+    private void setIntentFlags(Intent intent) {\r
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\r
+        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);\r
+        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);\r
+        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);\r
+        intent.addFlags(Intent.FLAG_FROM_BACKGROUND);\r
+    }\r
+\r
+    private void validateAccountType(String type)\r
+            throws UnsupportedAccountTypeException {\r
+        if (!type.equals(ACCOUNT_TYPE)) {\r
+            throw new UnsupportedAccountTypeException();\r
+        }\r
+    }\r
+\r
+    private void validateAuthTokenType(String authTokenType)\r
+            throws UnsupportedAuthTokenTypeException {\r
+        if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {\r
+            throw new UnsupportedAuthTokenTypeException();\r
+        }\r
+    }\r
+\r
+    public static class AuthenticatorException extends Exception {\r
+        private static final long serialVersionUID = 1L;\r
+        private Bundle mFailureBundle;\r
+\r
+        public AuthenticatorException(int code, String errorMsg) {\r
+            mFailureBundle = new Bundle();\r
+            mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);\r
+            mFailureBundle\r
+                    .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);\r
+        }\r
+\r
+        public Bundle getFailureBundle() {\r
+            return mFailureBundle;\r
+        }\r
+    }\r
+\r
+    public static class UnsupportedAccountTypeException extends\r
+            AuthenticatorException {\r
+        private static final long serialVersionUID = 1L;\r
+\r
+        public UnsupportedAccountTypeException() {\r
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+                    "Unsupported account type");\r
+        }\r
+    }\r
+\r
+    public static class UnsupportedAuthTokenTypeException extends\r
+            AuthenticatorException {\r
+        private static final long serialVersionUID = 1L;\r
+\r
+        public UnsupportedAuthTokenTypeException() {\r
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+                    "Unsupported auth token type");\r
+        }\r
+    }\r
+\r
+    public static class UnsupportedFeaturesException extends\r
+            AuthenticatorException {\r
+        public static final long serialVersionUID = 1L;\r
+\r
+        public UnsupportedFeaturesException() {\r
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+                    "Unsupported features");\r
+        }\r
+    }\r
+\r
+    public static class AccessDeniedException extends AuthenticatorException {\r
+        public AccessDeniedException(int code, String errorMsg) {\r
+            super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");\r
+        }\r
+\r
+        private static final long serialVersionUID = 1L;\r
+\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/authenticator/AccountAuthenticatorService.java b/src/com/owncloud/android/authenticator/AccountAuthenticatorService.java
new file mode 100644 (file)
index 0000000..e11b03a
--- /dev/null
@@ -0,0 +1,41 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2011  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 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.authenticator;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class AccountAuthenticatorService extends Service {
+
+    private AccountAuthenticator mAuthenticator;
+    static final public String ACCOUNT_TYPE = "owncloud";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mAuthenticator = new AccountAuthenticator(this);
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mAuthenticator.getIBinder();
+    }
+
+}
diff --git a/src/com/owncloud/android/authenticator/AuthenticationRunnable.java b/src/com/owncloud/android/authenticator/AuthenticationRunnable.java
new file mode 100644 (file)
index 0000000..dba3281
--- /dev/null
@@ -0,0 +1,81 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.authenticator;
+
+import java.net.URL;
+
+import org.apache.commons.httpclient.HttpStatus;
+
+import eu.alefzero.webdav.WebdavClient;
+
+import android.net.Uri;
+import android.os.Handler;
+
+public class AuthenticationRunnable implements Runnable {
+
+    private OnAuthenticationResultListener mListener;
+    private Handler mHandler;
+    private URL mUrl;
+    private String mUsername;
+    private String mPassword;
+
+    public AuthenticationRunnable(URL url, String username, String password) {
+        mListener = null;
+        mUrl = url;
+        mUsername = username;
+        mPassword = password;
+    }
+
+    public void setOnAuthenticationResultListener(
+            OnAuthenticationResultListener listener, Handler handler) {
+        mListener = listener;
+        mHandler = handler;
+    }
+
+    @Override
+    public void run() {
+        Uri uri;
+        uri = Uri.parse(mUrl.toString());
+        int login_result = WebdavClient.tryToLogin(uri, mUsername, mPassword);
+        switch (login_result) {
+        case HttpStatus.SC_OK:
+            postResult(true, uri.toString());
+            break;
+        case HttpStatus.SC_UNAUTHORIZED:
+            postResult(false, "Invalid login or/and password");
+            break;
+        case HttpStatus.SC_NOT_FOUND:
+            postResult(false, "Wrong path given");
+            break;
+        default:
+            postResult(false, "Internal server error, code: " + login_result);
+        }
+    }
+
+    private void postResult(final boolean success, final String message) {
+        if (mHandler != null && mListener != null) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mListener.onAuthenticationResult(success, message);
+                }
+            });
+        }
+    }
+}
diff --git a/src/com/owncloud/android/authenticator/ConnectionCheckerRunnable.java b/src/com/owncloud/android/authenticator/ConnectionCheckerRunnable.java
new file mode 100644 (file)
index 0000000..d1d1070
--- /dev/null
@@ -0,0 +1,170 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.authenticator;
+
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLHandshakeException;
+
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.OnConnectCheckListener.ResultType;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.WebdavClient;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.util.Log;
+
+public class ConnectionCheckerRunnable implements Runnable {
+    
+    /** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs.  */
+    public static final int TRY_CONNECTION_TIMEOUT = 5000;
+    
+    private static final String TAG = "ConnectionCheckerRunnable";
+    private OnConnectCheckListener mListener;
+    private String mUrl;
+    private Handler mHandler;
+    private ResultType mLatestResult;
+    private Context mContext;
+    private OwnCloudVersion mOCVersion;
+
+    public void setListener(OnConnectCheckListener listener, Handler handler) {
+        mListener = listener;
+        mHandler = handler;
+    }
+
+    public ConnectionCheckerRunnable(String url, Context context) {
+        mListener = null;
+        mHandler = null;
+        mUrl = url;
+        mContext = context;
+        mOCVersion = null;
+    }
+
+    @Override
+    public void run() {
+
+        if (!isOnline()) {
+            postResult(ResultType.NO_NETWORK_CONNECTION);
+            return;
+        }
+        if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
+            mLatestResult = (mUrl.startsWith("https://"))? ResultType.OK_SSL : ResultType.OK_NO_SSL;
+            tryConnection(Uri.parse(mUrl + AccountUtils.STATUS_PATH));
+            postResult(mLatestResult);
+        } else {
+            Uri uri = Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH);
+            if (tryConnection(uri)) {
+                postResult(ResultType.OK_SSL);
+                return;
+            }
+            Log.d(TAG,
+                    "establishing secure connection failed, trying non secure connection");
+            uri = Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH);
+
+            if (tryConnection(uri)) {
+                postResult(ResultType.OK_NO_SSL);
+                return;
+            }
+            postResult(mLatestResult);
+        }
+    }
+
+    public OwnCloudVersion getDiscoveredVersion() {
+        return mOCVersion;
+    }
+
+    private boolean tryConnection(Uri uri) {
+        WebdavClient wc = new WebdavClient();
+        wc.allowSelfsignedCertificates();
+        GetMethod get = new GetMethod(uri.toString());
+        boolean retval = false;
+        try {
+            int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT);
+            switch (status) {
+            case HttpStatus.SC_OK: {
+                String response = get.getResponseBodyAsString();
+                JSONObject json = new JSONObject(response);
+                if (!json.getBoolean("installed")) {
+                    mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
+                    break;
+                }
+                mOCVersion = new OwnCloudVersion(json.getString("version"));
+                if (!mOCVersion.isVersionValid())
+                    break;
+                retval = true;
+                break;
+            }
+            case HttpStatus.SC_NOT_FOUND:
+                mLatestResult = ResultType.FILE_NOT_FOUND;
+                break;
+            case HttpStatus.SC_INTERNAL_SERVER_ERROR:
+                mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
+                break;
+            default:
+                mLatestResult = ResultType.UNKNOWN_ERROR;
+                Log.e(TAG, "Not handled status received from server: " + status);
+            }
+
+        } catch (Exception e) {
+            if (e instanceof UnknownHostException
+                    || e instanceof ConnectException 
+                    || e instanceof SocketTimeoutException) {
+                mLatestResult = ResultType.HOST_NOT_AVAILABLE;
+            } else if (e instanceof JSONException) {
+                mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
+            } else if (e instanceof SSLHandshakeException) {
+                mLatestResult = ResultType.SSL_INIT_ERROR;
+            } else {
+                mLatestResult = ResultType.UNKNOWN_ERROR;
+            }
+            e.printStackTrace();
+        }
+
+        return retval;
+    }
+
+    private boolean isOnline() {
+        ConnectivityManager cm = (ConnectivityManager) mContext
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+        return cm != null && cm.getActiveNetworkInfo() != null
+                && cm.getActiveNetworkInfo().isConnectedOrConnecting();
+    }
+
+    private void postResult(final ResultType result) {
+        if (mHandler != null && mListener != null) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mListener.onConnectionCheckResult(result);
+                }
+            });
+        }
+    }
+
+}
diff --git a/src/com/owncloud/android/authenticator/EasySSLSocketFactory.java b/src/com/owncloud/android/authenticator/EasySSLSocketFactory.java
new file mode 100644 (file)
index 0000000..0a3f8be
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ * 
+ * ====================================================================
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package com.owncloud.android.authenticator;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.HttpClientError;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+
+import android.util.Log;
+
+/**
+ * <p>
+ * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s that
+ * accept self-signed certificates.
+ * </p>
+ * <p>
+ * This socket factory SHOULD NOT be used for productive systems due to security
+ * reasons, unless it is a concious decision and you are perfectly aware of
+ * security implications of accepting self-signed certificates
+ * </p>
+ * 
+ * <p>
+ * Example of using custom protocol socket factory for a specific host:
+ * 
+ * <pre>
+ * Protocol easyhttps = new Protocol(&quot;https&quot;, new EasySSLProtocolSocketFactory(),
+ *         443);
+ * 
+ * URI uri = new URI(&quot;https://localhost/&quot;, true);
+ * // use relative url only
+ * GetMethod httpget = new GetMethod(uri.getPathQuery());
+ * HostConfiguration hc = new HostConfiguration();
+ * hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
+ * HttpClient client = new HttpClient();
+ * client.executeMethod(hc, httpget);
+ * </pre>
+ * 
+ * </p>
+ * <p>
+ * Example of using custom protocol socket factory per default instead of the
+ * standard one:
+ * 
+ * <pre>
+ * Protocol easyhttps = new Protocol(&quot;https&quot;, new EasySSLProtocolSocketFactory(),
+ *         443);
+ * Protocol.registerProtocol(&quot;https&quot;, easyhttps);
+ * 
+ * HttpClient client = new HttpClient();
+ * GetMethod httpget = new GetMethod(&quot;https://localhost/&quot;);
+ * client.executeMethod(httpget);
+ * </pre>
+ * 
+ * </p>
+ * 
+ * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
+ * 
+ *         <p>
+ *         DISCLAIMER: HttpClient developers DO NOT actively support this
+ *         component. The component is provided as a reference material, which
+ *         may be inappropriate for use without additional customization.
+ *         </p>
+ */
+
+public class EasySSLSocketFactory implements ProtocolSocketFactory {
+
+    private static final String TAG = "EasySSLSocketFactory";
+    private SSLContext sslcontext = null;
+
+    /**
+     * Constructor for EasySSLProtocolSocketFactory.
+     */
+    public EasySSLSocketFactory() {
+        super();
+    }
+
+    private static SSLContext createEasySSLContext() {
+        try {
+            SSLContext context = SSLContext.getInstance("TLS");
+            context.init(null, new TrustManager[] { new EasyX509TrustManager(
+                    null) }, null);
+            return context;
+        } catch (Exception er) {
+            Log.e(TAG, er.getMessage() + "");
+            throw new HttpClientError(er.toString());
+        }
+    }
+
+    private SSLContext getSSLContext() {
+        if (this.sslcontext == null) {
+            this.sslcontext = createEasySSLContext();
+        }
+        return this.sslcontext;
+    }
+
+    /**
+     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
+     */
+    public Socket createSocket(String host, int port, InetAddress clientHost,
+            int clientPort) throws IOException, UnknownHostException {
+
+        return getSSLContext().getSocketFactory().createSocket(host, port,
+                clientHost, clientPort);
+    }
+
+    /**
+     * Attempts to get a new socket connection to the given host within the
+     * given time limit.
+     * <p>
+     * To circumvent the limitations of older JREs that do not support connect
+     * timeout a controller thread is executed. The controller thread attempts
+     * to create a new socket within the given limit of time. If socket
+     * constructor does not return until the timeout expires, the controller
+     * terminates and throws an {@link ConnectTimeoutException}
+     * </p>
+     * 
+     * @param host the host name/IP
+     * @param port the port on the host
+     * @param clientHost the local host name/IP to bind the socket to
+     * @param clientPort the port on the local machine
+     * @param params {@link HttpConnectionParams Http connection parameters}
+     * 
+     * @return Socket a new socket
+     * 
+     * @throws IOException if an I/O error occurs while creating the socket
+     * @throws UnknownHostException if the IP address of the host cannot be
+     *             determined
+     */
+    public Socket createSocket(final String host, final int port,
+            final InetAddress localAddress, final int localPort,
+            final HttpConnectionParams params) throws IOException,
+            UnknownHostException, ConnectTimeoutException {
+        if (params == null) {
+            throw new IllegalArgumentException("Parameters may not be null");
+        }
+        int timeout = params.getConnectionTimeout();
+        SocketFactory socketfactory = getSSLContext().getSocketFactory();
+        if (timeout == 0) {
+            Socket socket = socketfactory.createSocket(host, port, localAddress,
+                    localPort);
+            socket.setSoTimeout(params.getSoTimeout());
+            return socket;
+        } else {
+            Socket socket = socketfactory.createSocket();
+            SocketAddress localaddr = new InetSocketAddress(localAddress,
+                    localPort);
+            SocketAddress remoteaddr = new InetSocketAddress(host, port);
+            socket.setSoTimeout(params.getSoTimeout());
+            socket.bind(localaddr);
+            socket.connect(remoteaddr, timeout);
+            return socket;
+        }
+    }
+
+    /**
+     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+     */
+    public Socket createSocket(String host, int port) throws IOException,
+            UnknownHostException {
+        return getSSLContext().getSocketFactory().createSocket(host, port);
+    }
+
+    /**
+     * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
+     */
+    public Socket createSocket(Socket socket, String host, int port,
+            boolean autoClose) throws IOException, UnknownHostException {
+        return getSSLContext().getSocketFactory().createSocket(socket, host,
+                port, autoClose);
+    }
+
+    public boolean equals(Object obj) {
+        return ((obj != null) && obj.getClass().equals(
+                EasySSLSocketFactory.class));
+    }
+
+    public int hashCode() {
+        return EasySSLSocketFactory.class.hashCode();
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/authenticator/EasyX509TrustManager.java b/src/com/owncloud/android/authenticator/EasyX509TrustManager.java
new file mode 100644 (file)
index 0000000..0c7b083
--- /dev/null
@@ -0,0 +1,88 @@
+package com.owncloud.android.authenticator;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * @author olamy
+ * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse
+ *          $
+ * @since 1.2.3
+ */
+public class EasyX509TrustManager implements X509TrustManager {
+
+    private X509TrustManager standardTrustManager = null;
+
+    /**
+     * Constructor for EasyX509TrustManager.
+     */
+    public EasyX509TrustManager(KeyStore keystore)
+            throws NoSuchAlgorithmException, KeyStoreException {
+        super();
+        TrustManagerFactory factory = TrustManagerFactory
+                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        factory.init(keystore);
+        TrustManager[] trustmanagers = factory.getTrustManagers();
+        if (trustmanagers.length == 0) {
+            throw new NoSuchAlgorithmException("no trust manager found");
+        }
+        this.standardTrustManager = (X509TrustManager) trustmanagers[0];
+    }
+
+    /**
+     * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],
+     *      String authType)
+     */
+    public void checkClientTrusted(X509Certificate[] certificates,
+            String authType) throws CertificateException {
+        standardTrustManager.checkClientTrusted(certificates, authType);
+    }
+
+    /**
+     * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
+     *      String authType)
+     */
+    public void checkServerTrusted(X509Certificate[] certificates,
+            String authType) throws CertificateException {
+        if ((certificates != null) && (certificates.length == 1)) {
+            certificates[0].checkValidity();
+        } else {
+            // standardTrustManager.checkServerTrusted( certificates, authType
+            // );
+        }
+    }
+
+    /**
+     * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+     */
+    public X509Certificate[] getAcceptedIssuers() {
+        return this.standardTrustManager.getAcceptedIssuers();
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/authenticator/OnAuthenticationResultListener.java b/src/com/owncloud/android/authenticator/OnAuthenticationResultListener.java
new file mode 100644 (file)
index 0000000..11cbdce
--- /dev/null
@@ -0,0 +1,7 @@
+package com.owncloud.android.authenticator;
+
+public interface OnAuthenticationResultListener {
+
+    public void onAuthenticationResult(boolean success, String message);
+
+}
diff --git a/src/com/owncloud/android/authenticator/OnConnectCheckListener.java b/src/com/owncloud/android/authenticator/OnConnectCheckListener.java
new file mode 100644 (file)
index 0000000..bca71ae
--- /dev/null
@@ -0,0 +1,11 @@
+package com.owncloud.android.authenticator;
+
+public interface OnConnectCheckListener {
+
+    enum ResultType {
+        OK_SSL, OK_NO_SSL, SSL_INIT_ERROR, HOST_NOT_AVAILABLE, TIMEOUT, NO_NETWORK_CONNECTION, INORRECT_ADDRESS, INSTANCE_NOT_CONFIGURED, FILE_NOT_FOUND, UNKNOWN_ERROR
+    }
+
+    public void onConnectionCheckResult(ResultType type);
+
+}
diff --git a/src/com/owncloud/android/datamodel/DataStorageManager.java b/src/com/owncloud/android/datamodel/DataStorageManager.java
new file mode 100644 (file)
index 0000000..a73ab66
--- /dev/null
@@ -0,0 +1,41 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.datamodel;
+
+import java.util.List;
+import java.util.Vector;
+
+public interface DataStorageManager {
+
+    public OCFile getFileByPath(String path);
+
+    public OCFile getFileById(long id);
+
+    public boolean fileExists(String path);
+
+    public boolean fileExists(long id);
+
+    public boolean saveFile(OCFile file);
+
+    public void saveFiles(List<OCFile> files);
+
+    public Vector<OCFile> getDirectoryContent(OCFile f);
+    
+    public void removeFile(OCFile file);
+}
diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
new file mode 100644 (file)
index 0000000..49a88c3
--- /dev/null
@@ -0,0 +1,422 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.datamodel;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
+
+import com.owncloud.android.db.ProviderMeta;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+import com.owncloud.android.files.services.FileDownloader;
+
+import android.accounts.Account;
+import android.content.ContentProviderClient;
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.util.Log;
+
+public class FileDataStorageManager implements DataStorageManager {
+
+    private ContentResolver mContentResolver;
+    private ContentProviderClient mContentProvider;
+    private Account mAccount;
+
+    private static String TAG = "FileDataStorageManager";
+
+    public FileDataStorageManager(Account account, ContentResolver cr) {
+        mContentProvider = null;
+        mContentResolver = cr;
+        mAccount = account;
+    }
+
+    public FileDataStorageManager(Account account, ContentProviderClient cp) {
+        mContentProvider = cp;
+        mContentResolver = null;
+        mAccount = account;
+    }
+
+    @Override
+    public OCFile getFileByPath(String path) {
+        Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
+        OCFile file = null;
+        if (c.moveToFirst()) {
+            file = createFileInstance(c);
+        }
+        c.close();
+        return file;
+    }
+
+    @Override
+    public OCFile getFileById(long id) {
+        Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
+        OCFile file = null;
+        if (c.moveToFirst()) {
+            file = createFileInstance(c);
+        }
+        c.close();
+        return file;
+    }
+
+    @Override
+    public boolean fileExists(long id) {
+        return fileExists(ProviderTableMeta._ID, String.valueOf(id));
+    }
+
+    @Override
+    public boolean fileExists(String path) {
+        return fileExists(ProviderTableMeta.FILE_PATH, path);
+    }
+
+    @Override
+    public boolean saveFile(OCFile file) {
+        boolean overriden = false;
+        ContentValues cv = new ContentValues();
+        cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
+        cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
+        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
+        cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
+        cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
+        if (file.getParentId() != 0)
+            cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+        cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
+        if (!file.isDirectory())
+            cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+        cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
+        cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
+        cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
+
+        if (fileExists(file.getRemotePath())) {
+            OCFile oldFile = getFileByPath(file.getRemotePath());
+            if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
+                file.setStoragePath(oldFile.getStoragePath());
+            if (!file.isDirectory());
+                cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+            file.setFileId(oldFile.getFileId());
+
+            overriden = true;
+            if (getContentResolver() != null) {
+                getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
+                        ProviderTableMeta._ID + "=?",
+                        new String[] { String.valueOf(file.getFileId()) });
+            } else {
+                try {
+                    getContentProvider().update(ProviderTableMeta.CONTENT_URI,
+                            cv, ProviderTableMeta._ID + "=?",
+                            new String[] { String.valueOf(file.getFileId()) });
+                } catch (RemoteException e) {
+                    Log.e(TAG,
+                            "Fail to insert insert file to database "
+                                    + e.getMessage());
+                }
+            }
+        } else {
+            Uri result_uri = null;
+            if (getContentResolver() != null) {
+                result_uri = getContentResolver().insert(
+                        ProviderTableMeta.CONTENT_URI_FILE, cv);
+            } else {
+                try {
+                    result_uri = getContentProvider().insert(
+                            ProviderTableMeta.CONTENT_URI_FILE, cv);
+                } catch (RemoteException e) {
+                    Log.e(TAG,
+                            "Fail to insert insert file to database "
+                                    + e.getMessage());
+                }
+            }
+            if (result_uri != null) {
+                long new_id = Long.parseLong(result_uri.getPathSegments()
+                        .get(1));
+                file.setFileId(new_id);
+            }
+        }
+
+        if (file.isDirectory() && file.needsUpdatingWhileSaving())
+            for (OCFile f : getDirectoryContent(file))
+                saveFile(f);
+
+        return overriden;
+    }
+
+
+    @Override
+    public void saveFiles(List<OCFile> files) {
+        
+        Iterator<OCFile> filesIt = files.iterator();
+        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(files.size());
+        OCFile file = null;
+
+        // prepare operations to perform
+        while (filesIt.hasNext()) {
+            file = filesIt.next();
+            ContentValues cv = new ContentValues();
+            cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
+            cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
+            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
+            cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
+            cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
+            if (file.getParentId() != 0)
+                cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
+            cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
+            if (!file.isDirectory())
+                cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+            cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
+            cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
+            cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
+
+            if (fileExists(file.getRemotePath())) {
+                OCFile tmpfile = getFileByPath(file.getRemotePath());
+                file.setStoragePath(tmpfile.getStoragePath());
+                if (!file.isDirectory());
+                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
+                file.setFileId(tmpfile.getFileId());
+
+                operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                        withValues(cv).
+                        withSelection(  ProviderTableMeta._ID + "=?", 
+                                        new String[] { String.valueOf(file.getFileId()) })
+                        .build());
+                
+            } else {
+                operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
+            }
+        }
+        
+        // apply operations in batch
+        ContentProviderResult[] results = null;
+        try {
+            if (getContentResolver() != null) {
+                results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
+            
+            } else {
+                results = getContentProvider().applyBatch(operations);
+            }
+            
+        } catch (OperationApplicationException e) {
+            Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
+            
+        } catch (RemoteException e) {
+            Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
+        }
+        
+        // update new id in file objects for insertions
+        if (results != null) {
+            long newId;
+            for (int i=0; i<results.length; i++) {
+                if (results[i].uri != null) {
+                    newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
+                    files.get(i).setFileId(newId);
+                    //Log.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
+                }
+            }
+        }
+
+        for (OCFile aFile : files) {
+            if (aFile.isDirectory() && aFile.needsUpdatingWhileSaving())
+                saveFiles(getDirectoryContent(aFile));
+        }
+
+    }
+    
+    public void setAccount(Account account) {
+        mAccount = account;
+    }
+
+    public Account getAccount() {
+        return mAccount;
+    }
+
+    public void setContentResolver(ContentResolver cr) {
+        mContentResolver = cr;
+    }
+
+    public ContentResolver getContentResolver() {
+        return mContentResolver;
+    }
+
+    public void setContentProvider(ContentProviderClient cp) {
+        mContentProvider = cp;
+    }
+
+    public ContentProviderClient getContentProvider() {
+        return mContentProvider;
+    }
+
+    public Vector<OCFile> getDirectoryContent(OCFile f) {
+        if (f != null && f.isDirectory() && f.getFileId() != -1) {
+            Vector<OCFile> ret = new Vector<OCFile>();
+
+            Uri req_uri = Uri.withAppendedPath(
+                    ProviderTableMeta.CONTENT_URI_DIR,
+                    String.valueOf(f.getFileId()));
+            Cursor c = null;
+
+            if (getContentProvider() != null) {
+                try {
+                    c = getContentProvider().query(req_uri, null,
+                            ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                            new String[] { mAccount.name }, null);
+                } catch (RemoteException e) {
+                    Log.e(TAG, e.getMessage());
+                    return ret;
+                }
+            } else {
+                c = getContentResolver().query(req_uri, null,
+                        ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                        new String[] { mAccount.name }, null);
+            }
+
+            if (c.moveToFirst()) {
+                do {
+                    OCFile child = createFileInstance(c);
+                    ret.add(child);
+                } while (c.moveToNext());
+            }
+
+            c.close();
+            
+            Collections.sort(ret);
+            
+            return ret;
+        }
+        return null;
+    }
+
+    private boolean fileExists(String cmp_key, String value) {
+        Cursor c;
+        if (getContentResolver() != null) {
+            c = getContentResolver()
+                    .query(ProviderTableMeta.CONTENT_URI,
+                            null,
+                            cmp_key + "=? AND "
+                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER
+                                    + "=?",
+                            new String[] { value, mAccount.name }, null);
+        } else {
+            try {
+                c = getContentProvider().query(
+                        ProviderTableMeta.CONTENT_URI,
+                        null,
+                        cmp_key + "=? AND "
+                                + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                        new String[] { value, mAccount.name }, null);
+            } catch (RemoteException e) {
+                Log.e(TAG,
+                        "Couldn't determine file existance, assuming non existance: "
+                                + e.getMessage());
+                return false;
+            }
+        }
+        boolean retval = c.moveToFirst();
+        c.close();
+        return retval;
+    }
+
+    private Cursor getCursorForValue(String key, String value) {
+        Cursor c = null;
+        if (getContentResolver() != null) {
+            c = getContentResolver()
+                    .query(ProviderTableMeta.CONTENT_URI,
+                            null,
+                            key + "=? AND "
+                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER
+                                    + "=?",
+                            new String[] { value, mAccount.name }, null);
+        } else {
+            try {
+                c = getContentProvider().query(
+                        ProviderTableMeta.CONTENT_URI,
+                        null,
+                        key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
+                                + "=?", new String[] { value, mAccount.name },
+                        null);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Could not get file details: " + e.getMessage());
+                c = null;
+            }
+        }
+        return c;
+    }
+
+    private OCFile createFileInstance(Cursor c) {
+        OCFile file = null;
+        if (c != null) {
+            file = new OCFile(c.getString(c
+                    .getColumnIndex(ProviderTableMeta.FILE_PATH)));
+            file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
+            file.setParentId(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
+            file.setMimetype(c.getString(c
+                    .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
+            if (!file.isDirectory()) {
+                file.setStoragePath(c.getString(c
+                        .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
+                if (file.getStoragePath() == null) {
+                    // try to find existing file and bind it with current account
+                    File f = new File(FileDownloader.getSavePath(mAccount.name) + file.getRemotePath());
+                    if (f.exists())
+                        file.setStoragePath(f.getAbsolutePath());
+                }
+            }
+            file.setFileLength(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
+            file.setCreationTimestamp(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
+            file.setModificationTimestamp(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
+            file.setLastSyncDate(c.getLong(c
+                    .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
+            file.setKeepInSync(c.getInt(
+                                c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
+        }
+        return file;
+    }
+    
+    public void removeFile(OCFile file) {
+        Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
+        if (getContentProvider() != null) {
+            try {
+                getContentProvider().delete(file_uri,
+                                            ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
+                                            new String[]{mAccount.name});
+            } catch (RemoteException e) {
+                e.printStackTrace();
+            }
+        } else {
+            getContentResolver().delete(file_uri,
+                                        ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
+                                        new String[]{mAccount.name});
+        }
+        if (file.isDown()) {
+            new File(file.getStoragePath()).delete();
+        }
+    }
+
+}
diff --git a/src/com/owncloud/android/datamodel/OCFile.java b/src/com/owncloud/android/datamodel/OCFile.java
new file mode 100644 (file)
index 0000000..f50a86f
--- /dev/null
@@ -0,0 +1,382 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.datamodel;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import com.owncloud.android.files.services.FileDownloader;
+
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class OCFile implements Parcelable, Comparable<OCFile> {
+
+    public static final Parcelable.Creator<OCFile> CREATOR = new Parcelable.Creator<OCFile>() {
+        @Override
+        public OCFile createFromParcel(Parcel source) {
+            return new OCFile(source);
+        }
+
+        @Override
+        public OCFile[] newArray(int size) {
+            return new OCFile[size];
+        }
+    };
+
+    public static final String PATH_SEPARATOR = "/";
+    
+    private long mId;
+    private long mParentId;
+    private long mLength;
+    private long mCreationTimestamp;
+    private long mModifiedTimestamp;
+    private String mRemotePath;
+    private String mLocalPath;
+    private String mMimeType;
+    private boolean mNeedsUpdating;
+    private long mLastSyncDate;
+    private boolean mKeepInSync;
+
+    /**
+     * Create new {@link OCFile} with given path.
+     * 
+     * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
+     * 
+     * @param path The remote path of the file.
+     */
+    public OCFile(String path) {
+        resetData();
+        mNeedsUpdating = false;
+        if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) {
+            throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
+        }
+        mRemotePath = path;
+    }
+
+    /**
+     * Reconstruct from parcel
+     * 
+     * @param source The source parcel
+     */
+    private OCFile(Parcel source) {
+        mId = source.readLong();
+        mParentId = source.readLong();
+        mLength = source.readLong();
+        mCreationTimestamp = source.readLong();
+        mModifiedTimestamp = source.readLong();
+        mRemotePath = source.readString();
+        mLocalPath = source.readString();
+        mMimeType = source.readString();
+        mNeedsUpdating = source.readInt() == 0;
+        mKeepInSync = source.readInt() == 1;
+        mLastSyncDate = source.readLong();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeLong(mId);
+        dest.writeLong(mParentId);
+        dest.writeLong(mLength);
+        dest.writeLong(mCreationTimestamp);
+        dest.writeLong(mModifiedTimestamp);
+        dest.writeString(mRemotePath);
+        dest.writeString(mLocalPath);
+        dest.writeString(mMimeType);
+        dest.writeInt(mNeedsUpdating ? 1 : 0);
+        dest.writeInt(mKeepInSync ? 1 : 0);
+        dest.writeLong(mLastSyncDate);
+    }
+    
+    /**
+     * Gets the ID of the file
+     * 
+     * @return the file ID
+     */
+    public long getFileId() {
+        return mId;
+    }
+
+    /**
+     * Returns the remote path of the file on ownCloud
+     * 
+     * @return The remote path to the file
+     */
+    public String getRemotePath() {
+        return mRemotePath;
+    }
+
+    /**
+     * Can be used to check, whether or not this file exists in the database
+     * already
+     * 
+     * @return true, if the file exists in the database
+     */
+    public boolean fileExists() {
+        return mId != -1;
+    }
+
+    /**
+     * Use this to find out if this file is a Directory
+     * 
+     * @return true if it is a directory
+     */
+    public boolean isDirectory() {
+        return mMimeType != null && mMimeType.equals("DIR");
+    }
+
+    /**
+     * Use this to check if this file is available locally
+     * 
+     * @return true if it is
+     */
+    public boolean isDown() {
+        if (mLocalPath != null && mLocalPath.length() > 0) {
+            File file = new File(mLocalPath);
+            return (file.exists());
+        }
+        return false;
+    }
+    
+    /**
+     * The path, where the file is stored locally
+     * 
+     * @return The local path to the file
+     */
+    public String getStoragePath() {
+        return mLocalPath;
+    }
+
+    /**
+     * Can be used to set the path where the file is stored
+     * 
+     * @param storage_path to set
+     */
+    public void setStoragePath(String storage_path) {
+        mLocalPath = storage_path;
+    }
+
+    /**
+     * Get a UNIX timestamp of the file creation time
+     * 
+     * @return A UNIX timestamp of the time that file was created
+     */
+    public long getCreationTimestamp() {
+        return mCreationTimestamp;
+    }
+
+    /**
+     * Set a UNIX timestamp of the time the file was created
+     * 
+     * @param creation_timestamp to set
+     */
+    public void setCreationTimestamp(long creation_timestamp) {
+        mCreationTimestamp = creation_timestamp;
+    }
+
+    /**
+     * Get a UNIX timestamp of the file modification time
+     * 
+     * @return A UNIX timestamp of the modification time
+     */
+    public long getModificationTimestamp() {
+        return mModifiedTimestamp;
+    }
+
+    /**
+     * Set a UNIX timestamp of the time the time the file was modified.
+     * 
+     * @param modification_timestamp to set
+     */
+    public void setModificationTimestamp(long modification_timestamp) {
+        mModifiedTimestamp = modification_timestamp;
+    }
+
+    /**
+     * Returns the filename and "/" for the root directory
+     * 
+     * @return The name of the file
+     */
+    public String getFileName() {
+        File f = new File(getRemotePath());
+        return f.getName().length() == 0 ? "/" : f.getName();
+    }
+
+    /**
+     * Can be used to get the Mimetype
+     * 
+     * @return the Mimetype as a String
+     */
+    public String getMimetype() {
+        return mMimeType;
+    }
+
+    /**
+     * Adds a file to this directory. If this file is not a directory, an
+     * exception gets thrown.
+     * 
+     * @param file to add
+     * @throws IllegalStateException if you try to add a something and this is
+     *             not a directory
+     */
+    public void addFile(OCFile file) throws IllegalStateException {
+        if (isDirectory()) {
+            file.mParentId = mId;
+            mNeedsUpdating = true;
+            return;
+        }
+        throw new IllegalStateException(
+                "This is not a directory where you can add stuff to!");
+    }
+
+    /**
+     * Used internally. Reset all file properties
+     */
+    private void resetData() {
+        mId = -1;
+        mRemotePath = null;
+        mParentId = 0;
+        mLocalPath = null;
+        mMimeType = null;
+        mLength = 0;
+        mCreationTimestamp = 0;
+        mModifiedTimestamp = 0;
+        mLastSyncDate = 0;
+        mKeepInSync = false;
+        mNeedsUpdating = false;
+    }
+
+    /**
+     * Sets the ID of the file
+     * 
+     * @param file_id to set
+     */
+    public void setFileId(long file_id) {
+        mId = file_id;
+    }
+
+    /**
+     * Sets the Mime-Type of the
+     * 
+     * @param mimetype to set
+     */
+    public void setMimetype(String mimetype) {
+        mMimeType = mimetype;
+    }
+
+    /**
+     * Sets the ID of the parent folder
+     * 
+     * @param parent_id to set
+     */
+    public void setParentId(long parent_id) {
+        mParentId = parent_id;
+    }
+
+    /**
+     * Sets the file size in bytes
+     * 
+     * @param file_len to set
+     */
+    public void setFileLength(long file_len) {
+        mLength = file_len;
+    }
+
+    /**
+     * Returns the size of the file in bytes
+     * 
+     * @return The filesize in bytes
+     */
+    public long getFileLength() {
+        return mLength;
+    }
+
+    /**
+     * Returns the ID of the parent Folder
+     * 
+     * @return The ID
+     */
+    public long getParentId() {
+        return mParentId;
+    }
+
+    /**
+     * Check, if this file needs updating
+     * 
+     * @return
+     */
+    public boolean needsUpdatingWhileSaving() {
+        return mNeedsUpdating;
+    }
+    
+    public long getLastSyncDate() {
+        return mLastSyncDate;
+    }
+    
+    public void setLastSyncDate(long lastSyncDate) {
+        mLastSyncDate = lastSyncDate;
+    }
+
+    public void setKeepInSync(boolean keepInSync) {
+        mKeepInSync = keepInSync;
+    }
+    
+    public boolean keepInSync() {
+        return mKeepInSync;
+    }
+    
+    @Override
+    public int describeContents() {
+        return this.hashCode();
+    }
+
+    @Override
+    public int compareTo(OCFile another) {
+        if (isDirectory() && another.isDirectory()) {
+            return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
+        } else if (isDirectory()) {
+            return -1;
+        } else if (another.isDirectory()) {
+            return 1;
+        }
+        return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
+    }
+
+    public boolean equals(Object o) {
+        if(o instanceof OCFile){
+            OCFile that = (OCFile) o;
+            if(that != null){
+                return this.mId == that.mId;
+            }
+        }
+        
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, parentId=%s, keepInSinc=%s]";
+        asString = String.format(asString, new Long(mId), getFileName(), mMimeType, isDown(), mLocalPath, mRemotePath, new Long(mParentId), new Boolean(mKeepInSync));
+        return asString;
+    }
+
+}
diff --git a/src/com/owncloud/android/db/DbHandler.java b/src/com/owncloud/android/db/DbHandler.java
new file mode 100644 (file)
index 0000000..61d5655
--- /dev/null
@@ -0,0 +1,87 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.db;\r
+\r
+import java.util.Vector;\r
+\r
+import com.owncloud.android.OwnCloudSession;\r
+\r
+\r
+import android.content.ContentValues;\r
+import android.content.Context;\r
+import android.database.Cursor;\r
+import android.database.sqlite.SQLiteDatabase;\r
+import android.database.sqlite.SQLiteOpenHelper;\r
+\r
+/**\r
+ * Custom database helper for ownCloud\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class DbHandler {\r
+    private SQLiteDatabase mDB;\r
+    private OpenerHepler mHelper;\r
+    private final String mDatabaseName = "ownCloud";\r
+    private final String TABLE_SESSIONS = "sessions";\r
+    private final int mDatabaseVersion = 1;\r
+    \r
+    private final String TABLE_INSTANT_UPLOAD = "instant_upload";\r
+\r
+    public DbHandler(Context context) {\r
+        mHelper = new OpenerHepler(context);\r
+        mDB = mHelper.getWritableDatabase();\r
+    }\r
+\r
+    public void close() {\r
+        mDB.close();\r
+    }\r
+\r
+    public boolean putFileForLater(String filepath, String account) {\r
+        ContentValues cv = new ContentValues();\r
+        cv.put("path", filepath);\r
+        cv.put("account", account);\r
+        return mDB.insert(TABLE_INSTANT_UPLOAD, null, cv) != -1;\r
+    }\r
+    \r
+    public Cursor getAwaitingFiles() {\r
+        return mDB.query(TABLE_INSTANT_UPLOAD, null, null, null, null, null, null);\r
+    }\r
+    \r
+    public void clearFiles() {\r
+        mDB.delete(TABLE_INSTANT_UPLOAD, null, null);\r
+    }\r
+    \r
+    private class OpenerHepler extends SQLiteOpenHelper {\r
+        public OpenerHepler(Context context) {\r
+            super(context, mDatabaseName, null, mDatabaseVersion);\r
+        }\r
+\r
+        @Override\r
+        public void onCreate(SQLiteDatabase db) {\r
+            db.execSQL("CREATE TABLE " + TABLE_INSTANT_UPLOAD + " ("\r
+                       + " _id INTEGET PRIMARY KEY, "\r
+                       + " path TEXT,"\r
+                       + " account TEXT);");\r
+        }\r
+\r
+        @Override\r
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
+        }\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/db/ProviderMeta.java b/src/com/owncloud/android/db/ProviderMeta.java
new file mode 100644 (file)
index 0000000..c7f86b6
--- /dev/null
@@ -0,0 +1,67 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.db;\r
+\r
+import android.net.Uri;\r
+import android.provider.BaseColumns;\r
+\r
+/**\r
+ * Meta-Class that holds various static field information\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class ProviderMeta {\r
+\r
+    public static final String AUTHORITY_FILES = "org.owncloud";\r
+    public static final String DB_FILE = "owncloud.db";\r
+    public static final String DB_NAME = "filelist";\r
+    public static final int DB_VERSION = 2;\r
+\r
+    private ProviderMeta() {\r
+    }\r
+\r
+    static public class ProviderTableMeta implements BaseColumns {\r
+        public static final String DB_NAME = "filelist";\r
+        public static final Uri CONTENT_URI = Uri.parse("content://"\r
+                + AUTHORITY_FILES + "/");\r
+        public static final Uri CONTENT_URI_FILE = Uri.parse("content://"\r
+                + AUTHORITY_FILES + "/file");\r
+        public static final Uri CONTENT_URI_DIR = Uri.parse("content://"\r
+                + AUTHORITY_FILES + "/dir");\r
+\r
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.owncloud.file";\r
+        public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.owncloud.file";\r
+\r
+        public static final String FILE_PARENT = "parent";\r
+        public static final String FILE_NAME = "filename";\r
+        public static final String FILE_CREATION = "created";\r
+        public static final String FILE_MODIFIED = "modified";\r
+        public static final String FILE_CONTENT_LENGTH = "content_length";\r
+        public static final String FILE_CONTENT_TYPE = "content_type";\r
+        public static final String FILE_STORAGE_PATH = "media_path";\r
+        public static final String FILE_PATH = "path";\r
+        public static final String FILE_ACCOUNT_OWNER = "file_owner";\r
+        public static final String FILE_LAST_SYNC_DATE = "last_sync_date";\r
+        public static final String FILE_KEEP_IN_SYNC = "keep_in_sync";\r
+\r
+        public static final String DEFAULT_SORT_ORDER = FILE_NAME\r
+                + " collate nocase asc";\r
+\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/extensions/ExtensionsAvailableActivity.java b/src/com/owncloud/android/extensions/ExtensionsAvailableActivity.java
new file mode 100644 (file)
index 0000000..e389fd3
--- /dev/null
@@ -0,0 +1,17 @@
+package com.owncloud.android.extensions;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentManager;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+public class ExtensionsAvailableActivity extends SherlockFragmentActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        FragmentManager fm = getSupportFragmentManager();
+        ExtensionsAvailableDialog ead = new ExtensionsAvailableDialog();
+        ead.show(fm, "extensions_available_dialog");
+    }
+}
diff --git a/src/com/owncloud/android/extensions/ExtensionsAvailableDialog.java b/src/com/owncloud/android/extensions/ExtensionsAvailableDialog.java
new file mode 100644 (file)
index 0000000..55483fa
--- /dev/null
@@ -0,0 +1,50 @@
+package com.owncloud.android.extensions;
+
+import com.owncloud.android.R;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+public class ExtensionsAvailableDialog extends DialogFragment implements
+        OnClickListener {
+
+    public ExtensionsAvailableDialog() {
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.extensions_available_dialog,
+                container);
+        Button btnYes = (Button) view.findViewById(R.id.buttonYes);
+        Button btnNo = (Button) view.findViewById(R.id.buttonNo);
+        btnYes.setOnClickListener(this);
+        btnNo.setOnClickListener(this);
+        getDialog().setTitle(R.string.extensions_avail_title);
+        return view;
+    }
+
+    @Override
+    public void onClick(View v) {
+        switch (v.getId()) {
+        case R.id.buttonYes: {
+            Intent i = new Intent(getActivity(), ExtensionsListActivity.class);
+            startActivity(i);
+            getActivity().finish();
+        }
+            break;
+        case R.id.buttonNo:
+            getActivity().finish();
+            break;
+        default:
+            Log.e("EAD", "Button with unknown id clicked " + v.getId());
+        }
+    }
+
+}
diff --git a/src/com/owncloud/android/extensions/ExtensionsListActivity.java b/src/com/owncloud/android/extensions/ExtensionsListActivity.java
new file mode 100644 (file)
index 0000000..44aa819
--- /dev/null
@@ -0,0 +1,134 @@
+package com.owncloud.android.extensions;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Vector;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import com.owncloud.android.utils.OwnCloudVersion;
+
+
+import android.R;
+import android.app.Activity;
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.widget.SimpleAdapter;
+
+public class ExtensionsListActivity extends ListActivity {
+
+    private static final String packages_url = "http://alefzero.eu/a/packages.php";
+
+    private Thread mGetterThread;
+    private final Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mGetterThread = new Thread(new JsonGetter());
+        mGetterThread.start();
+    }
+
+    public void done(JSONArray a) {
+        LinkedList<HashMap<String, String>> ll = new LinkedList<HashMap<String, String>>();
+        for (int i = 0; i < a.length(); ++i) {
+            try {
+                ExtensionApplicationEntry ela = new ExtensionApplicationEntry(
+                        ((JSONObject) a.get(i)));
+                HashMap<String, String> ss = new HashMap<String, String>();
+                ss.put("NAME", ela.getName());
+                ss.put("DESC", ela.getDescription());
+                ll.add(ss);
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+        setListAdapter(new SimpleAdapter(this, ll, R.layout.simple_list_item_2,
+                new String[] { "NAME", "DESC" }, new int[] {
+                        android.R.id.text1, android.R.id.text2 }));
+
+    }
+
+    private class JsonGetter implements Runnable {
+
+        @Override
+        public void run() {
+            HttpClient hc = new HttpClient();
+            GetMethod gm = new GetMethod(packages_url);
+            final JSONArray ar;
+            try {
+                hc.executeMethod(gm);
+                Log.e("ASD", gm.getResponseBodyAsString() + "");
+                ar = new JSONObject(gm.getResponseBodyAsString())
+                        .getJSONArray("apps");
+            } catch (Exception e) {
+                e.printStackTrace();
+                return;
+            }
+
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    done(ar);
+                }
+            });
+
+        }
+
+    }
+
+    private class ExtensionApplicationEntry {
+        private static final String APP_NAME = "name";
+        private static final String APP_VERSION = "version";
+        private static final String APP_DESC = "description";
+        private static final String APP_ICON = "icon";
+        private static final String APP_URL = "download";
+        private static final String APP_PLAYID = "play_id";
+
+        private String mName, mDescription, mIcon, mDownload, mPlayId;
+        private OwnCloudVersion mVersion;
+
+        public ExtensionApplicationEntry(JSONObject appentry) {
+            try {
+                mName = appentry.getString(APP_NAME);
+                mDescription = appentry.getString(APP_DESC);
+                mIcon = appentry.getString(APP_ICON);
+                mDownload = appentry.getString(APP_URL);
+                mPlayId = appentry.getString(APP_PLAYID);
+                mVersion = new OwnCloudVersion(appentry.getString(APP_VERSION));
+            } catch (JSONException e) {
+                e.printStackTrace();
+            }
+        }
+
+        public String getName() {
+            return mName;
+        }
+
+        public String getDescription() {
+            return mDescription;
+        }
+
+        public String getIcon() {
+            return mIcon;
+        }
+
+        public String getDownload() {
+            return mDownload;
+        }
+
+        public String getPlayId() {
+            return mPlayId;
+        }
+
+        public OwnCloudVersion getVersion() {
+            return mVersion;
+        }
+    }
+}
diff --git a/src/com/owncloud/android/files/PhotoTakenBroadcastReceiver.java b/src/com/owncloud/android/files/PhotoTakenBroadcastReceiver.java
new file mode 100644 (file)
index 0000000..ec313b6
--- /dev/null
@@ -0,0 +1,151 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.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.InstantUploadService;
+
+import com.owncloud.android.R;
+import android.accounts.Account;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore.Images.Media;
+import android.util.Log;
+import android.webkit.MimeTypeMap;
+
+public class PhotoTakenBroadcastReceiver extends BroadcastReceiver {
+
+    private static String TAG = "PhotoTakenBroadcastReceiver";
+    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) {
+        if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false)) {
+            Log.d(TAG, "Instant upload disabled, abording uploading");
+            return;
+        }
+        if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {
+            handleConnectivityAction(context, intent);
+        } else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
+            handleNewPhontoAction(context, intent);
+        } else {
+            Log.e(TAG, "Incorrect intent sent: " + intent.getAction());
+        }
+    }
+
+    private void handleNewPhontoAction(Context context, Intent intent) {
+        Account account = AccountUtils.getCurrentOwnCloudAccount(context);
+        if (account == null) {
+            Log.w(TAG, "No owncloud account found for instant upload, abording");
+            return;
+        }
+
+        Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
+        
+        if (!c.moveToFirst()) {
+            Log.e(TAG, "Couldn't resolve given uri!");
+            return;
+        }
+        
+        String file_path = c.getString(c.getColumnIndex(Media.DATA));
+        String file_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME));
+        String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE));
+        long file_size = c.getLong(c.getColumnIndex(Media.SIZE));
+
+        c.close();
+        
+        if (!isOnline(context)) {
+            DbHandler db = new DbHandler(context);
+            db.putFileForLater(file_path, account.name);
+            db.close();
+            return;
+        }
+        
+        Intent upload_intent = new Intent(context, InstantUploadService.class);
+        upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
+        upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
+        upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, file_name);
+        upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, file_size);
+        upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mime_type);
+        
+        context.startService(upload_intent);
+    }
+
+    private void handleConnectivityAction(Context context, Intent intent) {
+        if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY) ||
+            isOnline(context)) {
+            DbHandler db = new DbHandler(context);
+            Cursor c = db.getAwaitingFiles();
+            if (c.moveToFirst()) {
+                do {
+                    String account_name = c.getString(c.getColumnIndex("account"));
+                    String file_path = c.getString(c.getColumnIndex("path"));
+                    File f = new File(file_path);
+                    if (f.exists()) {
+                        Intent upload_intent = new Intent(context, InstantUploadService.class);
+                        Account account = new Account(account_name, AccountAuthenticator.ACCOUNT_TYPE);
+                        
+                        String mimeType = null;
+                        try {
+                            mimeType = MimeTypeMap.getSingleton()
+                                    .getMimeTypeFromExtension(
+                                            f.getName().substring(f.getName().lastIndexOf('.') + 1));
+                        
+                        } catch (IndexOutOfBoundsException e) {
+                            Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
+                        }
+                        if (mimeType == null)
+                            mimeType = "application/octet-stream";
+                        
+                        upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
+                        upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
+                        upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, f.getName());
+                        upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, f.length());
+                        upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mimeType);
+                        
+                        context.startService(upload_intent);
+                    } else {
+                        Log.w(TAG, "Instant upload file " + f.getName() + " dont exist anymore");
+                    }
+                } while(c.moveToNext());
+                c.close();
+            }
+            db.clearFiles();
+            db.close();
+        }
+        
+    }
+
+    private boolean isOnline(Context context) {
+        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
+    }
+    
+}
diff --git a/src/com/owncloud/android/files/interfaces/OnDatatransferProgressListener.java b/src/com/owncloud/android/files/interfaces/OnDatatransferProgressListener.java
new file mode 100644 (file)
index 0000000..f3ae82b
--- /dev/null
@@ -0,0 +1,6 @@
+package com.owncloud.android.files.interfaces;
+
+public interface OnDatatransferProgressListener {
+    void transferProgress(long progressRate);
+
+}
diff --git a/src/com/owncloud/android/files/managers/OCNotificationManager.java b/src/com/owncloud/android/files/managers/OCNotificationManager.java
new file mode 100644 (file)
index 0000000..851a8f8
--- /dev/null
@@ -0,0 +1,154 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.files.managers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.widget.RemoteViews;
+
+import com.owncloud.android.R;
+
+public class OCNotificationManager {
+
+    enum NotificationType {
+        NOTIFICATION_SIMPLE,
+        NOTIFICATION_PROGRESS
+    }
+    
+    static public class NotificationData {
+        private String mText, mSubtitle;
+        private int mPercent;
+        private boolean mOngoing;
+
+        public NotificationData(String text, String subtitle, boolean ongoing) {
+            this(text, subtitle, -1, ongoing);
+        }
+        
+        public NotificationData(int percent, boolean ongoing) {
+            this(null, null, percent, ongoing);
+        }
+        
+        public NotificationData(String text, int percent, boolean ongoing) {
+            this(text, null, percent, ongoing);
+        }
+        
+        public NotificationData(String text, String subtitle, int percent, boolean ongoing) {
+            mText = text;
+            mPercent = percent;
+            mSubtitle = subtitle;
+            mOngoing = ongoing;
+        }
+        
+        public String getText() { return mText; }
+        public int getPercent() { return mPercent; }
+        public String getSubtitle() { return mSubtitle; }
+        public boolean getOngoing() { return mOngoing; }
+    }
+    
+    static private OCNotificationManager mInstance = null;
+
+    private class NotificationTypePair {
+        public Notification mNotificaiton;
+        public NotificationType mType;
+        public NotificationTypePair(Notification n, NotificationType type) {
+            mNotificaiton = n;
+            mType = type;
+        }
+    }
+    
+    private Context mContext;
+    private Map<Integer, NotificationTypePair> mNotificationMap;
+    private int mNotificationCounter;
+    NotificationManager mNM;
+    
+    static OCNotificationManager getInstance(Context context) {
+        if (mInstance == null)
+            mInstance = new OCNotificationManager(context);
+        return mInstance;
+    }
+    
+    OCNotificationManager(Context context) {
+        mContext = context;
+        mNotificationMap = new HashMap<Integer, NotificationTypePair>();
+        mNM = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        mNotificationCounter = 0;
+    }
+    
+    public int postNotification(NotificationType type, NotificationData data) {
+        mNotificationCounter++;
+        Notification notification = null;
+        
+        switch (type) {
+            case NOTIFICATION_SIMPLE:
+                notification = new Notification(R.drawable.icon, data.getText(), System.currentTimeMillis());
+                break;
+            case NOTIFICATION_PROGRESS:
+                notification = new Notification();
+                notification.contentView = new RemoteViews(mContext.getPackageName(), R.layout.progressbar_layout);
+                notification.contentView.setTextViewText(R.id.status_text,
+                                                         data.getText());
+                notification.contentView.setImageViewResource(R.id.status_icon,
+                                                              R.id.icon);
+                notification.contentView.setProgressBar(R.id.status_progress,
+                                                        100,
+                                                        data.getPercent(),
+                                                        false);
+                break;
+            default:
+                return -1;
+        }
+        if (data.getOngoing()) {
+            notification.flags |= notification.flags | Notification.FLAG_ONGOING_EVENT;
+        }
+        
+        mNotificationMap.put(mNotificationCounter, new NotificationTypePair(notification, type));
+        return mNotificationCounter;
+    }
+    
+    public boolean updateNotification(int notification_id, NotificationData data) {
+        if (!mNotificationMap.containsKey(notification_id)) {
+            return false;
+        }
+        NotificationTypePair pair = mNotificationMap.get(notification_id);
+        switch (pair.mType) {
+            case NOTIFICATION_PROGRESS:
+                pair.mNotificaiton.contentView.setProgressBar(R.id.status_text,
+                                                              100,
+                                                              data.getPercent(),
+                                                              false);
+                return true;
+            case NOTIFICATION_SIMPLE:
+                pair.mNotificaiton = new Notification(R.drawable.icon,
+                                                      data.getText(), System.currentTimeMillis());
+                mNM.notify(notification_id, pair.mNotificaiton);
+                return true;
+            default:
+                return false;
+        }
+    }
+    
+    public void discardNotification(int notification_id) {
+        mNM.cancel(notification_id);
+        mNotificationMap.remove(notification_id);
+    }
+}
diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java
new file mode 100644 (file)
index 0000000..4aafcce
--- /dev/null
@@ -0,0 +1,253 @@
+package com.owncloud.android.files.services;\r
+\r
+import java.io.File;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;\r
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.Notification;\r
+import android.app.NotificationManager;\r
+import android.app.PendingIntent;\r
+import android.app.Service;\r
+import android.content.ContentValues;\r
+import android.content.Intent;\r
+import android.net.Uri;\r
+import android.os.Environment;\r
+import android.os.Handler;\r
+import android.os.HandlerThread;\r
+import android.os.IBinder;\r
+import android.os.Looper;\r
+import android.os.Message;\r
+import android.os.Process;\r
+import android.util.Log;\r
+import android.widget.RemoteViews;\r
+import com.owncloud.android.R;\r
+import eu.alefzero.webdav.WebdavClient;\r
+\r
+public class FileDownloader extends Service implements OnDatatransferProgressListener {\r
+    public static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";\r
+    public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";    \r
+    public static final String EXTRA_ACCOUNT = "ACCOUNT";\r
+    public static final String EXTRA_FILE_PATH = "FILE_PATH";\r
+    public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";\r
+    public static final String EXTRA_FILE_SIZE = "FILE_SIZE";\r
+    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";\r
+    \r
+    private static final String TAG = "FileDownloader";\r
+\r
+    private NotificationManager mNotificationMngr;\r
+    private Looper mServiceLooper;\r
+    private ServiceHandler mServiceHandler;\r
+    private Account mAccount;\r
+    private String mFilePath;\r
+    private String mRemotePath;\r
+    private int mLastPercent;\r
+    private long mTotalDownloadSize;\r
+    private long mCurrentDownloadSize;\r
+    private Notification mNotification;\r
+    \r
+    /**\r
+     * Static map with the files being download and the path to the temporal file were are download\r
+     */\r
+    private static Map<String, String> mDownloadsInProgress = Collections.synchronizedMap(new HashMap<String, String>());\r
+    \r
+    /**\r
+     * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading\r
+     */\r
+    public static boolean isDownloading(Account account, String remotePath) {\r
+        return (mDownloadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);\r
+    }\r
+    \r
+    /**\r
+     * Builds a key for mDownloadsInProgress from the accountName and remotePath\r
+     */\r
+    private static String buildRemoteName(String accountName, String remotePath) {\r
+        return accountName + remotePath;\r
+    }\r
+\r
+    \r
+    private final class ServiceHandler extends Handler {\r
+        public ServiceHandler(Looper looper) {\r
+            super(looper);\r
+        }\r
+\r
+        @Override\r
+        public void handleMessage(Message msg) {\r
+            downloadFile();\r
+            stopSelf(msg.arg1);\r
+        }\r
+    }\r
+    \r
+    public static final String getSavePath(String accountName) {\r
+        File sdCard = Environment.getExternalStorageDirectory();\r
+        return sdCard.getAbsolutePath() + "/owncloud/" + Uri.encode(accountName, "@");   \r
+            // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B\r
+    }\r
+    \r
+    public static final String getTemporalPath(String accountName) {\r
+        File sdCard = Environment.getExternalStorageDirectory();\r
+        return sdCard.getAbsolutePath() + "/owncloud/tmp/" + Uri.encode(accountName, "@");\r
+            // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B\r
+    }\r
+\r
+    @Override\r
+    public void onCreate() {\r
+        super.onCreate();\r
+        mNotificationMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
+        HandlerThread thread = new HandlerThread("FileDownladerThread",\r
+                Process.THREAD_PRIORITY_BACKGROUND);\r
+        thread.start();\r
+        mServiceLooper = thread.getLooper();\r
+        mServiceHandler = new ServiceHandler(mServiceLooper);\r
+    }\r
+\r
+    @Override\r
+    public IBinder onBind(Intent arg0) {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public int onStartCommand(Intent intent, int flags, int startId) {\r
+        if (    !intent.hasExtra(EXTRA_ACCOUNT) ||\r
+                !intent.hasExtra(EXTRA_FILE_PATH) ||\r
+                !intent.hasExtra(EXTRA_REMOTE_PATH)\r
+           ) {\r
+            Log.e(TAG, "Not enough information provided in intent");\r
+            return START_NOT_STICKY;\r
+        }\r
+        mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);\r
+        mFilePath = intent.getStringExtra(EXTRA_FILE_PATH);\r
+        mRemotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);\r
+        mTotalDownloadSize = intent.getLongExtra(EXTRA_FILE_SIZE, -1);\r
+        mCurrentDownloadSize = mLastPercent = 0;\r
+\r
+        Message msg = mServiceHandler.obtainMessage();\r
+        msg.arg1 = startId;\r
+        mServiceHandler.sendMessage(msg);\r
+\r
+        return START_NOT_STICKY;\r
+    }\r
+\r
+    /**\r
+     * Core download method: requests the file to download and stores it.\r
+     */\r
+    private void downloadFile() {\r
+        boolean downloadResult = false;\r
+\r
+        /// prepare client object to send the request to the ownCloud server\r
+        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);\r
+        WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());\r
+        String username = mAccount.name.split("@")[0];\r
+        String password = null;\r
+        try {\r
+            password = am.blockingGetAuthToken(mAccount,\r
+                    AccountAuthenticator.AUTH_TOKEN_TYPE, true);\r
+        } catch (Exception e) {\r
+            Log.e(TAG, "Access to account credentials failed", e);\r
+            sendFinalBroadcast(downloadResult, null);\r
+            return;\r
+        }\r
+        wdc.setCredentials(username, password);\r
+        wdc.allowSelfsignedCertificates();\r
+        wdc.setDataTransferProgressListener(this);\r
+\r
+        \r
+        /// download will be in a temporal file\r
+        File tmpFile = new File(getTemporalPath(mAccount.name) + mFilePath);\r
+        \r
+        /// create status notification to show the download progress\r
+        mNotification = new Notification(R.drawable.icon, getString(R.string.downloader_download_in_progress_ticker), System.currentTimeMillis());\r
+        mNotification.flags |= Notification.FLAG_ONGOING_EVENT;\r
+        mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);\r
+        mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, mTotalDownloadSize == -1);\r
+        mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), 0, tmpFile.getName()));\r
+        mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);\r
+        // TODO put something smart in the contentIntent below\r
+        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);\r
+        mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);\r
+        \r
+\r
+        /// perform the download\r
+        tmpFile.getParentFile().mkdirs();\r
+        mDownloadsInProgress.put(buildRemoteName(mAccount.name, mRemotePath), tmpFile.getAbsolutePath());\r
+        File newFile = null;\r
+        try {\r
+            if (wdc.downloadFile(mRemotePath, tmpFile)) {\r
+                newFile = new File(getSavePath(mAccount.name) + mFilePath);\r
+                newFile.getParentFile().mkdirs();\r
+                boolean moved = tmpFile.renameTo(newFile);\r
+            \r
+                if (moved) {\r
+                    ContentValues cv = new ContentValues();\r
+                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());\r
+                    getContentResolver().update(\r
+                            ProviderTableMeta.CONTENT_URI,\r
+                            cv,\r
+                            ProviderTableMeta.FILE_NAME + "=? AND "\r
+                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
+                            new String[] {\r
+                                mFilePath.substring(mFilePath.lastIndexOf('/') + 1),\r
+                                mAccount.name });\r
+                    downloadResult = true;\r
+                }\r
+            }\r
+        } finally {\r
+            mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));\r
+        }\r
+\r
+        \r
+        /// notify result\r
+        mNotificationMngr.cancel(R.string.downloader_download_in_progress_ticker);\r
+        int tickerId = (downloadResult) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker;\r
+        int contentId = (downloadResult) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;\r
+        Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());\r
+        finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;\r
+        // TODO put something smart in the contentIntent below\r
+        finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);\r
+        finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), tmpFile.getName()), finalNotification.contentIntent);\r
+        mNotificationMngr.notify(tickerId, finalNotification);\r
+            \r
+        sendFinalBroadcast(downloadResult, (downloadResult)?newFile.getAbsolutePath():null);\r
+    }\r
+\r
+    /**\r
+     * Callback method to update the progress bar in the status notification.\r
+     */\r
+    @Override\r
+    public void transferProgress(long progressRate) {\r
+        mCurrentDownloadSize += progressRate;\r
+        int percent = (int)(100.0*((double)mCurrentDownloadSize)/((double)mTotalDownloadSize));\r
+        if (percent != mLastPercent) {\r
+          mNotification.contentView.setProgressBar(R.id.status_progress, 100, (int)(100*mCurrentDownloadSize/mTotalDownloadSize), mTotalDownloadSize == -1);\r
+          mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), percent, new File(mFilePath).getName()));\r
+          mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);\r
+        }\r
+        \r
+        mLastPercent = percent;\r
+    }\r
+    \r
+\r
+    /**\r
+     * Sends a broadcast in order to the interested activities can update their view\r
+     * \r
+     * @param downloadResult        'True' if the download was successful\r
+     * @param newFilePath           Absolute path to the download file\r
+     */\r
+    private void sendFinalBroadcast(boolean downloadResult, String newFilePath) {\r
+        Intent end = new Intent(DOWNLOAD_FINISH_MESSAGE);\r
+        end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult);\r
+        end.putExtra(ACCOUNT_NAME, mAccount.name);\r
+        end.putExtra(EXTRA_REMOTE_PATH, mRemotePath);\r
+        if (downloadResult) {\r
+            end.putExtra(EXTRA_FILE_PATH, newFilePath);\r
+        }\r
+        sendBroadcast(end);\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/files/services/FileOperation.java b/src/com/owncloud/android/files/services/FileOperation.java
new file mode 100644 (file)
index 0000000..bdb76cd
--- /dev/null
@@ -0,0 +1,54 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.files.services;
+
+import java.io.File;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.datamodel.OCFile;
+
+import android.accounts.Account;
+import android.content.Context;
+import eu.alefzero.webdav.WebdavClient;
+
+public class FileOperation {
+
+    Context mContext;
+    
+    public FileOperation(Context contex){
+        this.mContext = contex;
+    }
+    
+    /**
+     * Deletes a file from ownCloud - locally and remote.
+     * @param file The file to delete
+     * @return True on success, otherwise false
+     */
+    public boolean delete(OCFile file){
+        
+        Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
+        WebdavClient client = new WebdavClient(account, mContext);
+        if(client.deleteFile(file.getRemotePath())){
+            File localFile = new File(file.getStoragePath());
+            return localFile.delete();
+        }
+        
+        return false;
+    }
+    
+}
diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java
new file mode 100644 (file)
index 0000000..34d795b
--- /dev/null
@@ -0,0 +1,327 @@
+package com.owncloud.android.files.services;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.datamodel.OCFile;
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;
+
+import android.accounts.Account;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.util.Log;
+import android.webkit.MimeTypeMap;
+import android.widget.RemoteViews;
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavClient;
+
+public class FileUploader extends Service implements OnDatatransferProgressListener {
+
+    public static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
+    public static final String EXTRA_PARENT_DIR_ID = "PARENT_DIR_ID";
+    public static final String EXTRA_UPLOAD_RESULT = "RESULT";
+    public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
+    public static final String EXTRA_FILE_PATH = "FILE_PATH";
+    
+    public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
+    public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
+    public static final String KEY_ACCOUNT = "ACCOUNT";
+    public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
+    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";    
+
+    public static final int UPLOAD_SINGLE_FILE = 0;
+    public static final int UPLOAD_MULTIPLE_FILES = 1;
+
+    private static final String TAG = "FileUploader";
+    
+    private NotificationManager mNotificationManager;
+    private Looper mServiceLooper;
+    private ServiceHandler mServiceHandler;
+    private Account mAccount;
+    private String[] mLocalPaths, mRemotePaths;
+    private int mUploadType;
+    private Notification mNotification;
+    private long mTotalDataToSend, mSendData;
+    private int mCurrentIndexUpload, mPreviousPercent;
+    private int mSuccessCounter;
+    
+    /**
+     * Static map with the files being download and the path to the temporal file were are download
+     */
+    private static Map<String, String> mUploadsInProgress = Collections.synchronizedMap(new HashMap<String, String>());
+    
+    /**
+     * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading
+     */
+    public static boolean isUploading(Account account, String remotePath) {
+        return (mUploadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);
+    }
+    
+    /**
+     * Builds a key for mUplaodsInProgress from the accountName and remotePath
+     */
+    private static String buildRemoteName(String accountName, String remotePath) {
+        return accountName + remotePath;
+    }
+
+    
+    
+
+    @Override
+    public IBinder onBind(Intent arg0) {
+        return null;
+    }
+
+    private final class ServiceHandler extends Handler {
+        public ServiceHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            uploadFile();
+            stopSelf(msg.arg1);
+        }
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+        HandlerThread thread = new HandlerThread("FileUploaderThread",
+                Process.THREAD_PRIORITY_BACKGROUND);
+        thread.start();
+        mServiceLooper = thread.getLooper();
+        mServiceHandler = new ServiceHandler(mServiceLooper);
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (!intent.hasExtra(KEY_ACCOUNT) && !intent.hasExtra(KEY_UPLOAD_TYPE)) {
+            Log.e(TAG, "Not enough information provided in intent");
+            return Service.START_NOT_STICKY;
+        }
+        mAccount = intent.getParcelableExtra(KEY_ACCOUNT);
+        mUploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
+        if (mUploadType == -1) {
+            Log.e(TAG, "Incorrect upload type provided");
+            return Service.START_NOT_STICKY;
+        }
+        if (mUploadType == UPLOAD_SINGLE_FILE) {
+            mLocalPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
+            mRemotePaths = new String[] { intent
+                    .getStringExtra(KEY_REMOTE_FILE) };
+        } else { // mUploadType == UPLOAD_MULTIPLE_FILES
+            mLocalPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
+            mRemotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
+        }
+
+        if (mLocalPaths.length != mRemotePaths.length) {
+            Log.e(TAG, "Different number of remote paths and local paths!");
+            return Service.START_NOT_STICKY;
+        }
+
+        Message msg = mServiceHandler.obtainMessage();
+        msg.arg1 = startId;
+        mServiceHandler.sendMessage(msg);
+
+        return Service.START_NOT_STICKY;
+    }
+
+    
+    /**
+     * Core upload method: sends the file(s) to upload
+     */
+    public void uploadFile() {
+        FileDataStorageManager storageManager = new FileDataStorageManager(mAccount, getContentResolver());
+
+        mTotalDataToSend = mSendData = mPreviousPercent = 0;
+        
+        /// prepare client object to send the request to the ownCloud server
+        WebdavClient wc = new WebdavClient(mAccount, getApplicationContext());
+        wc.allowSelfsignedCertificates();
+        wc.setDataTransferProgressListener(this);
+
+        /// create status notification to show the upload progress
+        mNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_in_progress_ticker), System.currentTimeMillis());
+        mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
+        RemoteViews oldContentView = mNotification.contentView;
+        mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
+        mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
+        mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
+        // dvelasco ; contentIntent MUST be assigned to avoid app crashes in versions previous to Android 4.x ;
+        //              BUT an empty Intent is not a very elegant solution; something smart should happen when a user 'clicks' on an upload in the notification bar
+        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+        mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
+
+        
+        /// perform the upload
+        File [] localFiles = new File[mLocalPaths.length];
+        for (int i = 0; i < mLocalPaths.length; ++i) {
+            localFiles[i] = new File(mLocalPaths[i]);
+            mTotalDataToSend += localFiles[i].length();
+        }
+        Log.d(TAG, "Will upload " + mTotalDataToSend + " bytes, with " + mLocalPaths.length + " files");
+        mSuccessCounter = 0;
+        for (int i = 0; i < mLocalPaths.length; ++i) {
+            String mimeType = null;
+            try {
+                mimeType = MimeTypeMap.getSingleton()
+                        .getMimeTypeFromExtension(
+                                mLocalPaths[i].substring(mLocalPaths[i]
+                                    .lastIndexOf('.') + 1));
+            } catch (IndexOutOfBoundsException e) {
+                Log.e(TAG, "Trying to find out MIME type of a file without extension: " + mLocalPaths[i]);
+            }
+            if (mimeType == null)
+                mimeType = "application/octet-stream";
+            mCurrentIndexUpload = i;
+            long parentDirId = -1;
+            boolean uploadResult = false;
+            String availablePath = getAvailableRemotePath(wc, mRemotePaths[i]);
+            try {
+                File f = new File(mRemotePaths[i]);
+                parentDirId = storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId();
+                if(availablePath != null) {
+                    mRemotePaths[i] = availablePath;
+                    mUploadsInProgress.put(buildRemoteName(mAccount.name, mRemotePaths[i]), mLocalPaths[i]);
+                    if (wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) {
+                        OCFile new_file = new OCFile(mRemotePaths[i]);
+                        new_file.setMimetype(mimeType);
+                        new_file.setFileLength(localFiles[i].length());
+                        new_file.setModificationTimestamp(System.currentTimeMillis());
+                        new_file.setLastSyncDate(0);
+                        new_file.setStoragePath(mLocalPaths[i]);         
+                        new_file.setParentId(parentDirId);
+                        storageManager.saveFile(new_file);
+                        mSuccessCounter++;
+                        uploadResult = true;
+                    }
+                }
+            } finally {
+                mUploadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePaths[i]));
+                
+                /// notify upload (or fail) of EACH file to activities interested
+                Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
+                end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId);
+                end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult);
+                end.putExtra(EXTRA_REMOTE_PATH, mRemotePaths[i]);
+                end.putExtra(EXTRA_FILE_PATH, mLocalPaths[i]);
+                end.putExtra(ACCOUNT_NAME, mAccount.name);
+                sendBroadcast(end);
+            }
+            
+        }
+        
+        /// notify final result
+        if (mSuccessCounter == mLocalPaths.length) {    // success
+            //Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_succeeded_ticker), System.currentTimeMillis());
+            mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove the ongoing flag
+            mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
+            mNotification.contentView = oldContentView;
+            // TODO put something smart in the contentIntent below
+            mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+            if (mLocalPaths.length == 1) {
+                mNotification.setLatestEventInfo(   getApplicationContext(), 
+                                                    getString(R.string.uploader_upload_succeeded_ticker), 
+                                                    String.format(getString(R.string.uploader_upload_succeeded_content_single), localFiles[0].getName()), 
+                                                    mNotification.contentIntent);
+            } else {
+                mNotification.setLatestEventInfo(   getApplicationContext(), 
+                                                    getString(R.string.uploader_upload_succeeded_ticker), 
+                                                    String.format(getString(R.string.uploader_upload_succeeded_content_multiple), mSuccessCounter), 
+                                                    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
+            
+        } else {
+            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());
+            finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
+            // TODO put something smart in the contentIntent below
+            finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
+            if (mLocalPaths.length == 1) {
+                finalNotification.setLatestEventInfo(   getApplicationContext(), 
+                                                        getString(R.string.uploader_upload_failed_ticker), 
+                                                        String.format(getString(R.string.uploader_upload_failed_content_single), localFiles[0].getName()), 
+                                                        finalNotification.contentIntent);
+            } else {
+                finalNotification.setLatestEventInfo(   getApplicationContext(), 
+                                                        getString(R.string.uploader_upload_failed_ticker), 
+                                                        String.format(getString(R.string.uploader_upload_failed_content_multiple), mSuccessCounter, mLocalPaths.length), 
+                                                        finalNotification.contentIntent);
+            }                
+            mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
+        }
+        
+    }
+
+    /**
+     * Checks if remotePath does not exist in the server and returns it, or adds a suffix to it in order to avoid the server
+     * file is overwritten.
+     * 
+     * @param string
+     * @return
+     */
+    private String getAvailableRemotePath(WebdavClient wc, String remotePath) {
+        Boolean check = wc.existsFile(remotePath);
+        if (check == null) {    // null means fail
+            return null;
+        } else if (!check) {
+            return remotePath;
+        }
+    
+        int pos = remotePath.lastIndexOf(".");
+        String suffix = "";
+        String extension = "";
+        if (pos >= 0) {
+            extension = remotePath.substring(pos+1);
+            remotePath = remotePath.substring(0, pos);
+        }
+        int count = 2;
+        while (check != null && check) {
+            suffix = " (" + count + ")";
+            if (pos >= 0)
+                check = wc.existsFile(remotePath + suffix + "." + extension);
+            else
+                check = wc.existsFile(remotePath + suffix);
+            count++;
+        }
+        if (check == null) {
+            return null;
+        } else if (pos >=0) {
+            return remotePath + suffix + "." + extension;
+        } else {
+            return remotePath + suffix;
+        }
+    }
+    
+    
+    /**
+     * Callback method to update the progress bar in the status notification.
+     */
+    @Override
+    public void transferProgress(long progressRate) {
+        mSendData += progressRate;
+        int percent = (int)(100*((double)mSendData)/((double)mTotalDataToSend));
+        if (percent != mPreviousPercent) {
+            String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, new File(mLocalPaths[mCurrentIndexUpload]).getName());
+            mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, false);
+            mNotification.contentView.setTextViewText(R.id.status_text, text);
+            mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
+        }
+        mPreviousPercent = percent;
+    }
+}
diff --git a/src/com/owncloud/android/files/services/InstantUploadService.java b/src/com/owncloud/android/files/services/InstantUploadService.java
new file mode 100644 (file)
index 0000000..0324f59
--- /dev/null
@@ -0,0 +1,162 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.files.services;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.httpclient.HttpException;
+import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.utils.OwnCloudVersion;
+
+import eu.alefzero.webdav.WebdavClient;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.util.Log;
+
+public class InstantUploadService extends Service {
+
+    public static String KEY_FILE_PATH = "KEY_FILEPATH";
+    public static String KEY_FILE_SIZE = "KEY_FILESIZE";
+    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";
+    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)) {
+            Log.w(TAG, "Not all required information was provided, abording");
+            return Service.START_NOT_STICKY;
+        }
+        
+        if (mUploaderRunnable == null) {
+            mUploaderRunnable = new UploaderRunnable();
+        }
+        
+        String filename = intent.getStringExtra(KEY_DISPLAY_NAME);
+        String filepath = intent.getStringExtra(KEY_FILE_PATH);
+        String mimetype = intent.getStringExtra(KEY_MIME_TYPE);
+        Account account = intent.getParcelableExtra(KEY_ACCOUNT);
+        long filesize = intent.getLongExtra(KEY_FILE_SIZE, -1);
+        
+        mUploaderRunnable.addElementToQueue(filename, filepath, mimetype, filesize, account);
+        
+        // starting new thread for new download doesnt seems like a good idea
+        // maybe some thread pool or single background thread would be better
+        Log.d(TAG, "Starting instant upload thread");
+        new Thread(mUploaderRunnable).start();
+        
+        return Service.START_STICKY;
+    }
+    
+    private class UploaderRunnable implements Runnable {
+        
+        Object mLock;
+        List<HashMap<String, Object>> mHashMapList;
+        
+        public UploaderRunnable() {
+            mHashMapList = new LinkedList<HashMap<String, Object>>();
+            mLock = new Object();
+        }
+        
+        public void addElementToQueue(String filename,
+                                      String filepath,
+                                      String mimetype,
+                                      long length,
+                                      Account account) {
+            HashMap<String, Object> new_map = new HashMap<String, Object>();
+            new_map.put(KEY_ACCOUNT, account);
+            new_map.put(KEY_DISPLAY_NAME, filename);
+            new_map.put(KEY_FILE_PATH, filepath);
+            new_map.put(KEY_MIME_TYPE, mimetype);
+            new_map.put(KEY_FILE_SIZE, length);
+            
+            synchronized (mLock) {
+                mHashMapList.add(new_map);
+            }
+        }
+        
+        private HashMap<String, Object> getFirstObject() {
+            synchronized (mLock) {
+                if (mHashMapList.size() == 0)
+                    return null;
+                HashMap<String, Object> ret = mHashMapList.get(0);
+                mHashMapList.remove(0);
+                return ret;
+            }
+        }
+        
+        public void run() {
+            HashMap<String, Object> working_map;
+            AccountManager am = AccountManager.get(getApplicationContext());
+            
+            while ((working_map = getFirstObject()) != null) {
+                Account account = (Account) working_map.get(KEY_ACCOUNT);
+                String username = account.name.substring(0, account.name.lastIndexOf('@'));
+                String password = am.getPassword(account);
+                String filename = (String) working_map.get(KEY_DISPLAY_NAME);
+                String filepath = (String) working_map.get(KEY_FILE_PATH);
+                String mimetype = (String) working_map.get(KEY_MIME_TYPE);
+                
+                String oc_base_url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL);
+                String oc_version = am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION);
+                OwnCloudVersion ocv = new OwnCloudVersion(oc_version);
+                String webdav_path = AccountUtils.getWebdavPath(ocv);
+                WebdavClient wdc = new WebdavClient(account, getApplicationContext());
+                wdc.allowSelfsignedCertificates();
+                wdc.setCredentials(username, password);
+                
+                MkColMethod mkcol = new MkColMethod(oc_base_url+webdav_path+INSTANT_UPLOAD_DIR);
+                int status = 0;
+                try {
+                    status = wdc.executeMethod(mkcol);
+                    Log.e(TAG, "mkcol returned " + status);
+                    wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + filename, mimetype);
+                } catch (HttpException e) {
+                    e.printStackTrace();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    
+}
diff --git a/src/com/owncloud/android/files/services/OnUploadCompletedListener.java b/src/com/owncloud/android/files/services/OnUploadCompletedListener.java
new file mode 100644 (file)
index 0000000..80917dd
--- /dev/null
@@ -0,0 +1,8 @@
+package com.owncloud.android.files.services;
+
+public interface OnUploadCompletedListener extends Runnable {
+
+    public boolean getUploadResult();
+
+    public void setUploadResult(boolean result);
+}
diff --git a/src/com/owncloud/android/location/LocationServiceLauncherReciever.java b/src/com/owncloud/android/location/LocationServiceLauncherReciever.java
new file mode 100644 (file)
index 0000000..19efd7e
--- /dev/null
@@ -0,0 +1,87 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2011  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 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.location;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningServiceInfo;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+public class LocationServiceLauncherReciever extends BroadcastReceiver {
+
+    private final String TAG = getClass().getSimpleName();
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        Intent deviceTrackingIntent = new Intent();
+        deviceTrackingIntent
+                .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
+        SharedPreferences preferences = PreferenceManager
+                .getDefaultSharedPreferences(context);
+        boolean trackDevice = preferences.getBoolean("enable_devicetracking",
+                true);
+
+        // Used in Preferences activity so that tracking is disabled or
+        // reenabled
+        if (intent.hasExtra("TRACKING_SETTING")) {
+            trackDevice = intent.getBooleanExtra("TRACKING_SETTING", true);
+        }
+
+        startOrStopDeviceTracking(context, trackDevice);
+    }
+
+    /**
+     * Used internally. Starts or stops the device tracking service
+     * 
+     * @param trackDevice true to start the service, false to stop it
+     */
+    private void startOrStopDeviceTracking(Context context, boolean trackDevice) {
+        Intent deviceTrackingIntent = new Intent();
+        deviceTrackingIntent
+                .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
+        if (!isDeviceTrackingServiceRunning(context) && trackDevice) {
+            Log.d(TAG, "Starting device tracker service");
+            context.startService(deviceTrackingIntent);
+        } else if (isDeviceTrackingServiceRunning(context) && !trackDevice) {
+            Log.d(TAG, "Stopping device tracker service");
+            context.stopService(deviceTrackingIntent);
+        }
+    }
+
+    /**
+     * Checks to see whether or not the LocationUpdateService is running
+     * 
+     * @return true, if it is. Otherwise false
+     */
+    private boolean isDeviceTrackingServiceRunning(Context context) {
+        ActivityManager manager = (ActivityManager) context
+                .getSystemService(Context.ACTIVITY_SERVICE);
+        for (RunningServiceInfo service : manager
+                .getRunningServices(Integer.MAX_VALUE)) {
+            if (getClass().getName().equals(service.service.getClassName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/src/com/owncloud/android/location/LocationUpdateService.java b/src/com/owncloud/android/location/LocationUpdateService.java
new file mode 100644 (file)
index 0000000..6e3dfb8
--- /dev/null
@@ -0,0 +1,110 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2011  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 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.location;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.owncloud.android.R;
+
+public class LocationUpdateService extends IntentService implements
+        LocationListener {
+
+    public static final String TAG = "LocationUpdateService";
+
+    private LocationManager mLocationManager;
+    private LocationProvider mLocationProvider;
+    private SharedPreferences mPreferences;
+
+    public LocationUpdateService() {
+        super(TAG);
+    }
+
+    @Override
+    protected void onHandleIntent(Intent intent) {
+        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+        // Determine, how we can track the device
+        Criteria criteria = new Criteria();
+        criteria.setAccuracy(Criteria.ACCURACY_FINE);
+        criteria.setPowerRequirement(Criteria.POWER_LOW);
+        mLocationProvider = mLocationManager.getProvider(mLocationManager
+                .getBestProvider(criteria, true));
+
+        // Notify user if there is no way to track the device
+        if (mLocationProvider == null) {
+            Toast.makeText(this,
+                    R.string.location_no_provider,
+                    Toast.LENGTH_LONG);
+            stopSelf();
+            return;
+        }
+
+        // Get preferences for device tracking
+        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+        boolean trackDevice = mPreferences.getBoolean("enable_devicetracking",
+                true);
+        int updateIntervall = Integer.parseInt(mPreferences.getString(
+                "devicetracking_update_intervall", "30")) * 60 * 1000;
+        int distanceBetweenLocationChecks = 50;
+
+        // If we do shall track the device -> Stop
+        if (!trackDevice) {
+            Log.d(TAG, "Devicetracking is disabled");
+            stopSelf();
+            return;
+        }
+
+        mLocationManager.requestLocationUpdates(mLocationProvider.getName(),
+                updateIntervall, distanceBetweenLocationChecks, this);
+    }
+
+    @Override
+    public void onLocationChanged(Location location) {
+        Log.d(TAG, "Location changed: " + location);
+
+    }
+
+    @Override
+    public void onProviderDisabled(String arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void onProviderEnabled(String arg0) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Override
+    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
diff --git a/src/com/owncloud/android/providers/FileContentProvider.java b/src/com/owncloud/android/providers/FileContentProvider.java
new file mode 100644 (file)
index 0000000..6605d89
--- /dev/null
@@ -0,0 +1,238 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.providers;\r
+\r
+import java.util.HashMap;\r
+\r
+import com.owncloud.android.db.ProviderMeta;\r
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;\r
+\r
+\r
+import android.content.ContentProvider;\r
+import android.content.ContentUris;\r
+import android.content.ContentValues;\r
+import android.content.Context;\r
+import android.content.UriMatcher;\r
+import android.database.Cursor;\r
+import android.database.SQLException;\r
+import android.database.sqlite.SQLiteDatabase;\r
+import android.database.sqlite.SQLiteOpenHelper;\r
+import android.database.sqlite.SQLiteQueryBuilder;\r
+import android.net.Uri;\r
+import android.text.TextUtils;\r
+import android.util.Log;\r
+\r
+/**\r
+ * The ContentProvider for the ownCloud App.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class FileContentProvider extends ContentProvider {\r
+\r
+    private DataBaseHelper mDbHelper;\r
+\r
+    private static HashMap<String, String> mProjectionMap;\r
+    static {\r
+        mProjectionMap = new HashMap<String, String>();\r
+        mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_PARENT,\r
+                ProviderTableMeta.FILE_PARENT);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_PATH,\r
+                ProviderTableMeta.FILE_PATH);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_NAME,\r
+                ProviderTableMeta.FILE_NAME);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_CREATION,\r
+                ProviderTableMeta.FILE_CREATION);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,\r
+                ProviderTableMeta.FILE_MODIFIED);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,\r
+                ProviderTableMeta.FILE_CONTENT_LENGTH);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,\r
+                ProviderTableMeta.FILE_CONTENT_TYPE);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,\r
+                ProviderTableMeta.FILE_STORAGE_PATH);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,\r
+                ProviderTableMeta.FILE_LAST_SYNC_DATE);\r
+        mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,\r
+                ProviderTableMeta.FILE_KEEP_IN_SYNC);\r
+    }\r
+\r
+    private static final int SINGLE_FILE = 1;\r
+    private static final int DIRECTORY = 2;\r
+    private static final int ROOT_DIRECTORY = 3;\r
+    private static final UriMatcher mUriMatcher;\r
+    static {\r
+        mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);\r
+        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);\r
+        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);\r
+        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);\r
+        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);\r
+    }\r
+\r
+    @Override\r
+    public int delete(Uri uri, String where, String[] whereArgs) {\r
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();\r
+        int count = 0;\r
+        switch (mUriMatcher.match(uri)) {\r
+        case SINGLE_FILE:\r
+            count = db.delete(ProviderTableMeta.DB_NAME,\r
+                    ProviderTableMeta._ID\r
+                            + "="\r
+                            + uri.getPathSegments().get(1)\r
+                            + (!TextUtils.isEmpty(where) ? " AND (" + where\r
+                                    + ")" : ""), whereArgs);\r
+            break;\r
+        case ROOT_DIRECTORY:\r
+            count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);\r
+            break;\r
+        default:\r
+            throw new IllegalArgumentException("Unknown uri: " + uri.toString());\r
+        }\r
+        getContext().getContentResolver().notifyChange(uri, null);\r
+        return count;\r
+    }\r
+\r
+    @Override\r
+    public String getType(Uri uri) {\r
+        switch (mUriMatcher.match(uri)) {\r
+        case ROOT_DIRECTORY:\r
+            return ProviderTableMeta.CONTENT_TYPE;\r
+        case SINGLE_FILE:\r
+            return ProviderTableMeta.CONTENT_TYPE_ITEM;\r
+        default:\r
+            throw new IllegalArgumentException("Unknown Uri id."\r
+                    + uri.toString());\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public Uri insert(Uri uri, ContentValues values) {\r
+        if (mUriMatcher.match(uri) != SINGLE_FILE &&\r
+            mUriMatcher.match(uri) != ROOT_DIRECTORY) {\r
+            \r
+            throw new IllegalArgumentException("Unknown uri id: " + uri);\r
+        }\r
+\r
+        SQLiteDatabase db = mDbHelper.getWritableDatabase();\r
+        long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);\r
+        if (rowId > 0) {\r
+            Uri insertedFileUri = ContentUris.withAppendedId(\r
+                    ProviderTableMeta.CONTENT_URI_FILE, rowId);\r
+            getContext().getContentResolver().notifyChange(insertedFileUri,\r
+                    null);\r
+            return insertedFileUri;\r
+        }\r
+        throw new SQLException("ERROR " + uri);\r
+    }\r
+\r
+    @Override\r
+    public boolean onCreate() {\r
+        mDbHelper = new DataBaseHelper(getContext());\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public Cursor query(Uri uri, String[] projection, String selection,\r
+            String[] selectionArgs, String sortOrder) {\r
+        SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();\r
+\r
+        sqlQuery.setTables(ProviderTableMeta.DB_NAME);\r
+        sqlQuery.setProjectionMap(mProjectionMap);\r
+\r
+        switch (mUriMatcher.match(uri)) {\r
+        case ROOT_DIRECTORY:\r
+            break;\r
+        case DIRECTORY:\r
+            sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="\r
+                    + uri.getPathSegments().get(1));\r
+            break;\r
+        case SINGLE_FILE:\r
+            if (uri.getPathSegments().size() > 1) {\r
+                sqlQuery.appendWhere(ProviderTableMeta._ID + "="\r
+                        + uri.getPathSegments().get(1));\r
+            }\r
+            break;\r
+        default:\r
+            throw new IllegalArgumentException("Unknown uri id: " + uri);\r
+        }\r
+\r
+        String order;\r
+        if (TextUtils.isEmpty(sortOrder)) {\r
+            order = ProviderTableMeta.DEFAULT_SORT_ORDER;\r
+        } else {\r
+            order = sortOrder;\r
+        }\r
+\r
+        SQLiteDatabase db = mDbHelper.getReadableDatabase();\r
+        Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,\r
+                null, null, order);\r
+\r
+        c.setNotificationUri(getContext().getContentResolver(), uri);\r
+\r
+        return c;\r
+    }\r
+\r
+    @Override\r
+    public int update(Uri uri, ContentValues values, String selection,\r
+            String[] selectionArgs) {\r
+        return mDbHelper.getWritableDatabase().update(\r
+                ProviderTableMeta.DB_NAME, values, selection, selectionArgs);\r
+    }\r
+\r
+    class DataBaseHelper extends SQLiteOpenHelper {\r
+\r
+        public DataBaseHelper(Context context) {\r
+            super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);\r
+\r
+        }\r
+\r
+        @Override\r
+        public void onCreate(SQLiteDatabase db) {\r
+            // files table\r
+            Log.i("SQL", "Entering in onCreate");\r
+            db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("\r
+                    + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "\r
+                    + ProviderTableMeta.FILE_NAME + " TEXT, "\r
+                    + ProviderTableMeta.FILE_PATH + " TEXT, "\r
+                    + ProviderTableMeta.FILE_PARENT + " INTEGER, "\r
+                    + ProviderTableMeta.FILE_CREATION + " INTEGER, "\r
+                    + ProviderTableMeta.FILE_MODIFIED + " INTEGER, "\r
+                    + ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "\r
+                    + ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "\r
+                    + ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "\r
+                    + ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "\r
+                    + ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "\r
+                    + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER );");\r
+        }\r
+\r
+        @Override\r
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
+            Log.i("SQL", "Entering in onUpgrade");\r
+            if (oldVersion == 1 && newVersion >= 2) {\r
+                Log.i("SQL", "Entering in the ADD in onUpgrade");\r
+                db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +\r
+                           " ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC  + " INTEGER " +\r
+                           " DEFAULT 0");\r
+            } else Log.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);\r
+        }\r
+\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java b/src/com/owncloud/android/syncadapter/AbstractOwnCloudSyncAdapter.java
new file mode 100644 (file)
index 0000000..e8b1fcb
--- /dev/null
@@ -0,0 +1,164 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.syncadapter;\r
+\r
+import java.io.IOException;\r
+import java.net.UnknownHostException;\r
+import java.util.Date;\r
+\r
+import org.apache.http.HttpRequest;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.client.ClientProtocolException;\r
+import org.apache.http.conn.ConnectionKeepAliveStrategy;\r
+import org.apache.http.protocol.HttpContext;\r
+\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.datamodel.DataStorageManager;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.accounts.AuthenticatorException;\r
+import android.accounts.OperationCanceledException;\r
+import android.content.AbstractThreadedSyncAdapter;\r
+import android.content.ContentProviderClient;\r
+import android.content.Context;\r
+import android.net.Uri;\r
+import eu.alefzero.webdav.WebdavClient;\r
+\r
+/**\r
+ * Base SyncAdapter for OwnCloud Designed to be subclassed for the concrete\r
+ * SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..\r
+ * \r
+ * @author sassman\r
+ * \r
+ */\r
+public abstract class AbstractOwnCloudSyncAdapter extends\r
+        AbstractThreadedSyncAdapter {\r
+\r
+    private AccountManager accountManager;\r
+    private Account account;\r
+    private ContentProviderClient contentProvider;\r
+    private Date lastUpdated;\r
+    private DataStorageManager mStoreManager;\r
+\r
+    private WebdavClient mClient = null;\r
+\r
+    public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {\r
+        super(context, autoInitialize);\r
+        this.setAccountManager(AccountManager.get(context));\r
+    }\r
+\r
+    public AccountManager getAccountManager() {\r
+        return accountManager;\r
+    }\r
+\r
+    public void setAccountManager(AccountManager accountManager) {\r
+        this.accountManager = accountManager;\r
+    }\r
+\r
+    public Account getAccount() {\r
+        return account;\r
+    }\r
+\r
+    public void setAccount(Account account) {\r
+        this.account = account;\r
+    }\r
+\r
+    public ContentProviderClient getContentProvider() {\r
+        return contentProvider;\r
+    }\r
+\r
+    public void setContentProvider(ContentProviderClient contentProvider) {\r
+        this.contentProvider = contentProvider;\r
+    }\r
+\r
+    public Date getLastUpdated() {\r
+        return lastUpdated;\r
+    }\r
+\r
+    public void setLastUpdated(Date lastUpdated) {\r
+        this.lastUpdated = lastUpdated;\r
+    }\r
+\r
+    public void setStorageManager(DataStorageManager storage_manager) {\r
+        mStoreManager = storage_manager;\r
+    }\r
+\r
+    public DataStorageManager getStorageManager() {\r
+        return mStoreManager;\r
+    }\r
+\r
+    protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {\r
+        return new ConnectionKeepAliveStrategy() {\r
+            public long getKeepAliveDuration(HttpResponse response,\r
+                    HttpContext context) {\r
+                // Change keep alive straategy basing on response: ie\r
+                // forbidden/not found/etc\r
+                // should have keep alive 0\r
+                // default return: 5s\r
+                int statusCode = response.getStatusLine().getStatusCode();\r
+\r
+                // HTTP 400, 500 Errors as well as HTTP 118 - Connection timed\r
+                // out\r
+                if ((statusCode >= 400 && statusCode <= 418)\r
+                        || (statusCode >= 421 && statusCode <= 426)\r
+                        || (statusCode >= 500 && statusCode <= 510)\r
+                        || statusCode == 118) {\r
+                    return 0;\r
+                }\r
+\r
+                return 5 * 1000;\r
+            }\r
+        };\r
+    }\r
+\r
+    protected HttpResponse fireRawRequest(HttpRequest query)\r
+            throws ClientProtocolException, OperationCanceledException,\r
+            AuthenticatorException, IOException {\r
+        /*\r
+         * BasicHttpContext httpContext = new BasicHttpContext(); BasicScheme\r
+         * basicAuth = new BasicScheme();\r
+         * httpContext.setAttribute("preemptive-auth", basicAuth);\r
+         * \r
+         * HttpResponse response = getClient().execute(mHost, query,\r
+         * httpContext);\r
+         */\r
+        return null;\r
+    }\r
+\r
+    protected Uri getUri() {\r
+        return Uri.parse(this.getAccountManager().getUserData(getAccount(),\r
+                AccountAuthenticator.KEY_OC_URL));\r
+    }\r
+\r
+    protected WebdavClient getClient() throws OperationCanceledException,\r
+            AuthenticatorException, IOException {\r
+        if (mClient == null) {\r
+            if (this.getAccountManager().getUserData(getAccount(),\r
+                    AccountAuthenticator.KEY_OC_URL) == null) {\r
+                throw new UnknownHostException();\r
+            }\r
+            mClient = new WebdavClient(account, getContext());\r
+            mClient.allowSelfsignedCertificates();\r
+            // mHost = mClient.getTargetHost();\r
+        }\r
+\r
+        return mClient;\r
+    }\r
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java b/src/com/owncloud/android/syncadapter/ContactSyncAdapter.java
new file mode 100644 (file)
index 0000000..2508dcd
--- /dev/null
@@ -0,0 +1,107 @@
+package com.owncloud.android.syncadapter;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.entity.ByteArrayEntity;
+
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.ProviderMeta;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.content.ContentProviderClient;
+import android.content.Context;
+import android.content.SyncResult;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter {
+    private String mAddrBookUri;
+
+    public ContactSyncAdapter(Context context, boolean autoInitialize) {
+        super(context, autoInitialize);
+        mAddrBookUri = null;
+    }
+
+    @Override
+    public void onPerformSync(Account account, Bundle extras, String authority,
+            ContentProviderClient provider, SyncResult syncResult) {
+        setAccount(account);
+        setContentProvider(provider);
+        Cursor c = getLocalContacts(false);
+        if (c.moveToFirst()) {
+            do {
+                String lookup = c.getString(c
+                        .getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
+                String a = getAddressBookUri();
+                String uri = a + lookup + ".vcf";
+                FileInputStream f;
+                try {
+                    f = getContactVcard(lookup);
+                    HttpPut query = new HttpPut(uri);
+                    byte[] b = new byte[f.available()];
+                    f.read(b);
+                    query.setEntity(new ByteArrayEntity(b));
+                    HttpResponse response = fireRawRequest(query);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    return;
+                } catch (OperationCanceledException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                } catch (AuthenticatorException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            } while (c.moveToNext());
+            // } while (c.moveToNext());
+        }
+
+    }
+
+    private String getAddressBookUri() {
+        if (mAddrBookUri != null)
+            return mAddrBookUri;
+
+        AccountManager am = getAccountManager();
+        String uri = am.getUserData(getAccount(),
+                AccountAuthenticator.KEY_OC_URL).replace(
+                AccountUtils.WEBDAV_PATH_2_0, AccountUtils.CARDDAV_PATH_2_0);
+        uri += "/addressbooks/"
+                + getAccount().name.substring(0,
+                        getAccount().name.lastIndexOf('@')) + "/default/";
+        mAddrBookUri = uri;
+        return uri;
+    }
+
+    private FileInputStream getContactVcard(String lookupKey)
+            throws IOException {
+        Uri uri = Uri.withAppendedPath(
+                ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
+        AssetFileDescriptor fd = getContext().getContentResolver()
+                .openAssetFileDescriptor(uri, "r");
+        return fd.createInputStream();
+    }
+
+    private Cursor getLocalContacts(boolean include_hidden_contacts) {
+        return getContext().getContentResolver().query(
+                ContactsContract.Contacts.CONTENT_URI,
+                new String[] { ContactsContract.Contacts._ID,
+                        ContactsContract.Contacts.LOOKUP_KEY },
+                ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?",
+                new String[] { (include_hidden_contacts ? "0" : "1") },
+                ContactsContract.Contacts._ID + " DESC");
+    }
+
+}
diff --git a/src/com/owncloud/android/syncadapter/ContactSyncService.java b/src/com/owncloud/android/syncadapter/ContactSyncService.java
new file mode 100644 (file)
index 0000000..3016c85
--- /dev/null
@@ -0,0 +1,26 @@
+package com.owncloud.android.syncadapter;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class ContactSyncService extends Service {
+    private static final Object syncAdapterLock = new Object();
+    private static AbstractOwnCloudSyncAdapter mSyncAdapter = null;
+
+    @Override
+    public void onCreate() {
+        synchronized (syncAdapterLock) {
+            if (mSyncAdapter == null) {
+                mSyncAdapter = new ContactSyncAdapter(getApplicationContext(),
+                        true);
+            }
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent arg0) {
+        return mSyncAdapter.getSyncAdapterBinder();
+    }
+
+}
diff --git a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java
new file mode 100644 (file)
index 0000000..f7bfa43
--- /dev/null
@@ -0,0 +1,294 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.syncadapter;\r
+\r
+import java.io.IOException;\r
+import java.util.List;\r
+import java.util.Vector;\r
+\r
+import org.apache.jackrabbit.webdav.DavException;\r
+import org.apache.jackrabbit.webdav.MultiStatus;\r
+import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;\r
+\r
+import com.owncloud.android.datamodel.FileDataStorageManager;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.files.services.FileDownloader;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AuthenticatorException;\r
+import android.accounts.OperationCanceledException;\r
+import android.content.ContentProviderClient;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.content.SyncResult;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+import eu.alefzero.webdav.WebdavEntry;\r
+import eu.alefzero.webdav.WebdavUtils;\r
+\r
+/**\r
+ * SyncAdapter implementation for syncing sample SyncAdapter contacts to the\r
+ * platform ContactOperations provider.\r
+ * \r
+ * @author Bartek Przybylski\r
+ */\r
+public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {\r
+\r
+    private final static String TAG = "FileSyncAdapter"; \r
+    \r
+    /*  Commented code for ugly performance tests\r
+    private final static int MAX_DELAYS = 100;\r
+    private static long[] mResponseDelays = new long[MAX_DELAYS]; \r
+    private static long[] mSaveDelays = new long[MAX_DELAYS];\r
+    private int mDelaysIndex = 0;\r
+    private int mDelaysCount = 0;\r
+    */\r
+    \r
+    private long mCurrentSyncTime;\r
+    private boolean mCancellation;\r
+    private Account mAccount;\r
+    \r
+    public FileSyncAdapter(Context context, boolean autoInitialize) {\r
+        super(context, autoInitialize);\r
+    }\r
+\r
+    @Override\r
+    public synchronized void onPerformSync(Account account, Bundle extras,\r
+            String authority, ContentProviderClient provider,\r
+            SyncResult syncResult) {\r
+\r
+        mCancellation = false;\r
+        mAccount = account;\r
+        \r
+        this.setAccount(mAccount);\r
+        this.setContentProvider(provider);\r
+        this.setStorageManager(new FileDataStorageManager(mAccount,\r
+                getContentProvider()));\r
+        \r
+        /*  Commented code for ugly performance tests\r
+        mDelaysIndex = 0;\r
+        mDelaysCount = 0;\r
+        */\r
+        \r
+        \r
+        Log.d(TAG, "syncing owncloud account " + mAccount.name);\r
+\r
+        sendStickyBroadcast(true, null);  // message to signal the start to the UI\r
+\r
+        PropFindMethod query;\r
+        try {\r
+            mCurrentSyncTime = System.currentTimeMillis();\r
+            query = new PropFindMethod(getUri().toString() + "/");\r
+            getClient().executeMethod(query);\r
+            MultiStatus resp = null;\r
+            resp = query.getResponseBodyAsMultiStatus();\r
+\r
+            if (resp.getResponses().length > 0) {\r
+                WebdavEntry we = new WebdavEntry(resp.getResponses()[0], getUri().getPath());\r
+                OCFile file = fillOCFile(we);\r
+                file.setParentId(0);\r
+                getStorageManager().saveFile(file);\r
+                if (!mCancellation) {\r
+                    fetchData(getUri().toString(), syncResult, file.getFileId());\r
+                }\r
+            }\r
+        } catch (OperationCanceledException e) {\r
+            e.printStackTrace();\r
+        } catch (AuthenticatorException e) {\r
+            syncResult.stats.numAuthExceptions++;\r
+            e.printStackTrace();\r
+        } catch (IOException e) {\r
+            syncResult.stats.numIoExceptions++;\r
+            e.printStackTrace();\r
+        } catch (DavException e) {\r
+            syncResult.stats.numIoExceptions++;\r
+            e.printStackTrace();\r
+        } catch (Throwable t) {\r
+            // TODO update syncResult\r
+            Log.e(TAG, "problem while synchronizing owncloud account " + account.name, t);\r
+            t.printStackTrace();\r
+        }\r
+        \r
+        /*  Commented code for ugly performance tests\r
+        long sum = 0, mean = 0, max = 0, min = Long.MAX_VALUE;\r
+        for (int i=0; i<MAX_DELAYS && i<mDelaysCount; i++) {\r
+            sum += mResponseDelays[i];\r
+            max = Math.max(max, mResponseDelays[i]);\r
+            min = Math.min(min, mResponseDelays[i]);\r
+        }\r
+        mean = sum / mDelaysCount;\r
+        Log.e(TAG, "SYNC STATS - response: mean time = " + mean + " ; max time = " + max + " ; min time = " + min);\r
+        \r
+        sum = 0; max = 0; min = Long.MAX_VALUE;\r
+        for (int i=0; i<MAX_DELAYS && i<mDelaysCount; i++) {\r
+            sum += mSaveDelays[i];\r
+            max = Math.max(max, mSaveDelays[i]);\r
+            min = Math.min(min, mSaveDelays[i]);\r
+        }\r
+        mean = sum / mDelaysCount;\r
+        Log.e(TAG, "SYNC STATS - save:     mean time = " + mean + " ; max time = " + max + " ; min time = " + min);\r
+        Log.e(TAG, "SYNC STATS - folders measured: " + mDelaysCount);\r
+        */\r
+        \r
+        sendStickyBroadcast(false, null);        \r
+    }\r
+\r
+    private void fetchData(String uri, SyncResult syncResult, long parentId) {\r
+        try {\r
+            Log.d(TAG, "fetching " + uri);\r
+            \r
+            // remote request \r
+            PropFindMethod query = new PropFindMethod(uri);\r
+            /*  Commented code for ugly performance tests\r
+            long responseDelay = System.currentTimeMillis();\r
+            */\r
+            getClient().executeMethod(query);\r
+            /*  Commented code for ugly performance tests\r
+            responseDelay = System.currentTimeMillis() - responseDelay;\r
+            Log.e(TAG, "syncing: RESPONSE TIME for " + uri + " contents, " + responseDelay + "ms");\r
+            */\r
+            MultiStatus resp = null;\r
+            resp = query.getResponseBodyAsMultiStatus();\r
+            \r
+            // insertion or update of files\r
+            List<OCFile> updatedFiles = new Vector<OCFile>(resp.getResponses().length - 1);\r
+            for (int i = 1; i < resp.getResponses().length; ++i) {\r
+                WebdavEntry we = new WebdavEntry(resp.getResponses()[i], getUri().getPath());\r
+                OCFile file = fillOCFile(we);\r
+                file.setParentId(parentId);\r
+                if (getStorageManager().getFileByPath(file.getRemotePath()) != null &&\r
+                    getStorageManager().getFileByPath(file.getRemotePath()).keepInSync() &&\r
+                    file.getModificationTimestamp() > getStorageManager().getFileByPath(file.getRemotePath())\r
+                                                                         .getModificationTimestamp()) {\r
+                    Intent intent = new Intent(this.getContext(), FileDownloader.class);\r
+                    intent.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());\r
+                    intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getRemotePath());\r
+                    intent.putExtra(FileDownloader.EXTRA_REMOTE_PATH, file.getRemotePath());\r
+                    intent.putExtra(FileDownloader.EXTRA_FILE_SIZE, file.getFileLength());\r
+                    file.setKeepInSync(true);\r
+                    getContext().startService(intent);\r
+                }\r
+                if (getStorageManager().getFileByPath(file.getRemotePath()) != null)\r
+                    file.setKeepInSync(getStorageManager().getFileByPath(file.getRemotePath()).keepInSync());\r
+                \r
+                //Log.v(TAG, "adding file: " + file);\r
+                updatedFiles.add(file);\r
+                if (parentId == 0)\r
+                    parentId = file.getFileId();\r
+            }\r
+            /*  Commented code for ugly performance tests\r
+            long saveDelay = System.currentTimeMillis();\r
+            */            \r
+            getStorageManager().saveFiles(updatedFiles);    // all "at once" ; trying to get a best performance in database update\r
+            /*  Commented code for ugly performance tests\r
+            saveDelay = System.currentTimeMillis() - saveDelay;\r
+            Log.e(TAG, "syncing: SAVE TIME for " + uri + " contents, " + mSaveDelays[mDelaysIndex] + "ms");\r
+            */\r
+            \r
+            // removal of obsolete files\r
+            Vector<OCFile> files = getStorageManager().getDirectoryContent(\r
+                    getStorageManager().getFileById(parentId));\r
+            OCFile file;\r
+            for (int i=0; i < files.size(); ) {\r
+                file = files.get(i);\r
+                if (file.getLastSyncDate() != mCurrentSyncTime) {\r
+                    Log.v(TAG, "removing file: " + file);\r
+                    getStorageManager().removeFile(file);\r
+                    files.remove(i);\r
+                } else {\r
+                    i++;\r
+                }\r
+            }\r
+            \r
+            // synchronized folder -> notice to UI\r
+            sendStickyBroadcast(true, getStorageManager().getFileById(parentId).getRemotePath());\r
+\r
+            // recursive fetch\r
+            for (int i=0; i < files.size() && !mCancellation; i++) {\r
+                OCFile newFile = files.get(i);\r
+                if (newFile.getMimetype().equals("DIR")) {\r
+                    fetchData(getUri().toString() + WebdavUtils.encodePath(newFile.getRemotePath()), syncResult, newFile.getFileId());\r
+                }\r
+            }\r
+            if (mCancellation) Log.d(TAG, "Leaving " + uri + " because cancelation request");\r
+                \r
+            /*  Commented code for ugly performance tests\r
+            mResponseDelays[mDelaysIndex] = responseDelay;\r
+            mSaveDelays[mDelaysIndex] = saveDelay;\r
+            mDelaysCount++;\r
+            mDelaysIndex++;\r
+            if (mDelaysIndex >= MAX_DELAYS)\r
+                mDelaysIndex = 0;\r
+             */\r
+            \r
+\r
+\r
+        } catch (OperationCanceledException e) {\r
+            e.printStackTrace();\r
+        } catch (AuthenticatorException e) {\r
+            syncResult.stats.numAuthExceptions++;\r
+            e.printStackTrace();\r
+        } catch (IOException e) {\r
+            syncResult.stats.numIoExceptions++;\r
+            e.printStackTrace();\r
+        } catch (DavException e) {\r
+            syncResult.stats.numIoExceptions++;\r
+            e.printStackTrace();\r
+        } catch (Throwable t) {\r
+            // TODO update syncResult\r
+            Log.e(TAG, "problem while synchronizing owncloud account " + mAccount.name, t);\r
+            t.printStackTrace();\r
+        }\r
+    }\r
+\r
+    private OCFile fillOCFile(WebdavEntry we) {\r
+        OCFile file = new OCFile(we.decodedPath());\r
+        file.setCreationTimestamp(we.createTimestamp());\r
+        file.setFileLength(we.contentLength());\r
+        file.setMimetype(we.contentType());\r
+        file.setModificationTimestamp(we.modifiedTimesamp());\r
+        file.setLastSyncDate(mCurrentSyncTime);\r
+        return file;\r
+    }\r
+    \r
+    \r
+    private void sendStickyBroadcast(boolean inProgress, String dirRemotePath) {\r
+        Intent i = new Intent(FileSyncService.SYNC_MESSAGE);\r
+        i.putExtra(FileSyncService.IN_PROGRESS, inProgress);\r
+        i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);\r
+        if (dirRemotePath != null) {\r
+            i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);\r
+        }\r
+        getContext().sendStickyBroadcast(i);\r
+    }\r
+    \r
+    /**\r
+     * Called by system SyncManager when a synchronization is required to be cancelled.\r
+     * \r
+     * Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder\r
+     * fetched will be still saved in the database. See onPerformSync implementation.\r
+     */\r
+    @Override\r
+    public void onSyncCanceled() {\r
+        Log.d(TAG, "Synchronization of " + mAccount.name + " has been requested to cancell");\r
+        mCancellation = true;\r
+        super.onSyncCanceled();\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/syncadapter/FileSyncService.java b/src/com/owncloud/android/syncadapter/FileSyncService.java
new file mode 100644 (file)
index 0000000..74c7fa6
--- /dev/null
@@ -0,0 +1,50 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.syncadapter;\r
+\r
+import android.app.Service;\r
+import android.content.Intent;\r
+import android.os.IBinder;\r
+\r
+/**\r
+ * Background service for syncing files to our local Database\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class FileSyncService extends Service {\r
+    public static final String SYNC_MESSAGE = "ACCOUNT_SYNC";\r
+    public static final String SYNC_FOLDER_REMOTE_PATH = "SYNC_FOLDER_REMOTE_PATH";\r
+    public static final String IN_PROGRESS = "SYNC_IN_PROGRESS";\r
+    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";\r
+\r
+    /*\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onCreate() {\r
+    }\r
+\r
+    /*\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public IBinder onBind(Intent intent) {\r
+       return new FileSyncAdapter(getApplicationContext(), true).getSyncAdapterBinder();\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/ui/ActionItem.java b/src/com/owncloud/android/ui/ActionItem.java
new file mode 100644 (file)
index 0000000..b2be702
--- /dev/null
@@ -0,0 +1,61 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui;\r
+\r
+import android.graphics.drawable.Drawable;\r
+import android.view.View.OnClickListener;\r
+\r
+/**\r
+ * Represents an Item on the ActionBar.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class ActionItem {\r
+    private Drawable mIcon;\r
+    private String mTitle;\r
+    private OnClickListener mClickListener;\r
+\r
+    public ActionItem() {\r
+    }\r
+\r
+    public void setTitle(String title) {\r
+        mTitle = title;\r
+    }\r
+\r
+    public String getTitle() {\r
+        return mTitle;\r
+    }\r
+\r
+    public void setIcon(Drawable icon) {\r
+        mIcon = icon;\r
+    }\r
+\r
+    public Drawable getIcon() {\r
+        return mIcon;\r
+    }\r
+\r
+    public void setOnClickListener(OnClickListener listener) {\r
+        mClickListener = listener;\r
+    }\r
+\r
+    public OnClickListener getOnClickListerner() {\r
+        return mClickListener;\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/CustomPopup.java b/src/com/owncloud/android/ui/CustomPopup.java
new file mode 100644 (file)
index 0000000..b7ce426
--- /dev/null
@@ -0,0 +1,154 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui;\r
+\r
+import android.content.Context;\r
+import android.graphics.Rect;\r
+import android.graphics.drawable.BitmapDrawable;\r
+import android.graphics.drawable.Drawable;\r
+import android.view.Gravity;\r
+import android.view.LayoutInflater;\r
+import android.view.MotionEvent;\r
+import android.view.View;\r
+import android.view.WindowManager;\r
+import android.view.View.OnTouchListener;\r
+import android.view.ViewGroup.LayoutParams;\r
+import android.widget.PopupWindow;\r
+\r
+/**\r
+ * Represents a custom PopupWindows\r
+ * \r
+ * @author Lorensius. W. T\r
+ * \r
+ */\r
+public class CustomPopup {\r
+    protected final View mAnchor;\r
+    protected final PopupWindow mWindow;\r
+    private View root;\r
+    private Drawable background = null;\r
+    protected final WindowManager mWManager;\r
+\r
+    public CustomPopup(View anchor) {\r
+        mAnchor = anchor;\r
+        mWindow = new PopupWindow(anchor.getContext());\r
+\r
+        mWindow.setTouchInterceptor(new OnTouchListener() {\r
+\r
+            public boolean onTouch(View v, MotionEvent event) {\r
+                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {\r
+                    CustomPopup.this.dismiss();\r
+                    return true;\r
+                }\r
+                return false;\r
+            }\r
+        });\r
+\r
+        mWManager = (WindowManager) anchor.getContext().getSystemService(\r
+                Context.WINDOW_SERVICE);\r
+        onCreate();\r
+    }\r
+\r
+    public void onCreate() {\r
+    }\r
+\r
+    public void onShow() {\r
+    }\r
+\r
+    public void preShow() {\r
+        if (root == null) {\r
+            throw new IllegalStateException(\r
+                    "setContentView called with a view to display");\r
+        }\r
+\r
+        onShow();\r
+\r
+        if (background == null) {\r
+            mWindow.setBackgroundDrawable(new BitmapDrawable());\r
+        } else {\r
+            mWindow.setBackgroundDrawable(background);\r
+        }\r
+\r
+        mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);\r
+        mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);\r
+        mWindow.setTouchable(true);\r
+        mWindow.setFocusable(true);\r
+        mWindow.setOutsideTouchable(true);\r
+\r
+        mWindow.setContentView(root);\r
+    }\r
+\r
+    public void setBackgroundDrawable(Drawable background) {\r
+        this.background = background;\r
+    }\r
+\r
+    public void setContentView(View root) {\r
+        this.root = root;\r
+        mWindow.setContentView(root);\r
+    }\r
+\r
+    public void setContentView(int layoutResId) {\r
+        LayoutInflater inflater = (LayoutInflater) mAnchor.getContext()\r
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+        setContentView(inflater.inflate(layoutResId, null));\r
+    }\r
+\r
+    public void showDropDown() {\r
+        showDropDown(0, 0);\r
+    }\r
+\r
+    public void showDropDown(int x, int y) {\r
+        preShow();\r
+        mWindow.setAnimationStyle(android.R.style.Animation_Dialog);\r
+        mWindow.showAsDropDown(mAnchor, x, y);\r
+    }\r
+\r
+    public void showLikeQuickAction() {\r
+        showLikeQuickAction(0, 0);\r
+    }\r
+\r
+    public void showLikeQuickAction(int x, int y) {\r
+        preShow();\r
+\r
+        mWindow.setAnimationStyle(android.R.style.Animation_Dialog);\r
+        int[] location = new int[2];\r
+        mAnchor.getLocationOnScreen(location);\r
+\r
+        Rect anchorRect = new Rect(location[0], location[1], location[0]\r
+                + mAnchor.getWidth(), location[1] + mAnchor.getHeight());\r
+\r
+        root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,\r
+                LayoutParams.WRAP_CONTENT));\r
+        root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
+\r
+        int rootW = root.getWidth(), rootH = root.getHeight();\r
+        int screenW = mWManager.getDefaultDisplay().getWidth();\r
+\r
+        int xpos = ((screenW - rootW) / 2) + x;\r
+        int ypos = anchorRect.top - rootH + y;\r
+\r
+        if (rootH > anchorRect.top) {\r
+            ypos = anchorRect.bottom + y;\r
+        }\r
+        mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);\r
+    }\r
+\r
+    public void dismiss() {\r
+        mWindow.dismiss();\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/FragmentListView.java b/src/com/owncloud/android/ui/FragmentListView.java
new file mode 100644 (file)
index 0000000..98ac000
--- /dev/null
@@ -0,0 +1,52 @@
+package com.owncloud.android.ui;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.AdapterView.OnItemClickListener;
+
+public class FragmentListView extends SherlockFragment implements
+        OnItemClickListener, OnItemLongClickListener {
+    ListView mList;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    public void setListAdapter(ListAdapter listAdapter) {
+        mList.setAdapter(listAdapter);
+        mList.invalidate();
+    }
+
+    public ListView getListView() {
+        return mList;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        mList = new ListView(getActivity());
+        mList.setOnItemClickListener(this);
+        mList.setOnItemLongClickListener(this);
+        return mList;
+        // return super.onCreateView(inflater, container, savedInstanceState);
+    }
+
+    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
+    }
+
+    @Override
+    public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
+            long arg3) {
+        return false;
+    }
+
+}
diff --git a/src/com/owncloud/android/ui/QuickAction.java b/src/com/owncloud/android/ui/QuickAction.java
new file mode 100644 (file)
index 0000000..122792d
--- /dev/null
@@ -0,0 +1,305 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui;\r
+\r
+import android.content.Context;\r
+\r
+import android.graphics.Rect;\r
+import android.graphics.drawable.Drawable;\r
+\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import android.widget.LinearLayout;\r
+import android.widget.ScrollView;\r
+\r
+import android.view.Gravity;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+import android.view.ViewGroup.LayoutParams;\r
+import android.view.ViewGroup;\r
+\r
+import java.util.ArrayList;\r
+\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * Popup window, shows action list as icon and text like the one in Gallery3D\r
+ * app.\r
+ * \r
+ * @author Lorensius. W. T\r
+ */\r
+public class QuickAction extends CustomPopup {\r
+    private final View root;\r
+    private final ImageView mArrowUp;\r
+    private final ImageView mArrowDown;\r
+    private final LayoutInflater inflater;\r
+    private final Context context;\r
+\r
+    protected static final int ANIM_GROW_FROM_LEFT = 1;\r
+    protected static final int ANIM_GROW_FROM_RIGHT = 2;\r
+    protected static final int ANIM_GROW_FROM_CENTER = 3;\r
+    protected static final int ANIM_REFLECT = 4;\r
+    protected static final int ANIM_AUTO = 5;\r
+\r
+    private int animStyle;\r
+    private ViewGroup mTrack;\r
+    private ScrollView scroller;\r
+    private ArrayList<ActionItem> actionList;\r
+\r
+    /**\r
+     * Constructor\r
+     * \r
+     * @param anchor {@link View} on where the popup window should be displayed\r
+     */\r
+    public QuickAction(View anchor) {\r
+        super(anchor);\r
+\r
+        actionList = new ArrayList<ActionItem>();\r
+        context = anchor.getContext();\r
+        inflater = (LayoutInflater) context\r
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+\r
+        root = (ViewGroup) inflater.inflate(R.layout.popup, null);\r
+\r
+        mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);\r
+        mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);\r
+\r
+        setContentView(root);\r
+\r
+        mTrack = (ViewGroup) root.findViewById(R.id.tracks);\r
+        scroller = (ScrollView) root.findViewById(R.id.scroller);\r
+        animStyle = ANIM_AUTO;\r
+    }\r
+\r
+    /**\r
+     * Set animation style\r
+     * \r
+     * @param animStyle animation style, default is set to ANIM_AUTO\r
+     */\r
+    public void setAnimStyle(int animStyle) {\r
+        this.animStyle = animStyle;\r
+    }\r
+\r
+    /**\r
+     * Add action item\r
+     * \r
+     * @param action {@link ActionItem} object\r
+     */\r
+    public void addActionItem(ActionItem action) {\r
+        actionList.add(action);\r
+    }\r
+\r
+    /**\r
+     * Show popup window. Popup is automatically positioned, on top or bottom of\r
+     * anchor view.\r
+     * \r
+     */\r
+    public void show() {\r
+        preShow();\r
+\r
+        int xPos, yPos;\r
+\r
+        int[] location = new int[2];\r
+\r
+        mAnchor.getLocationOnScreen(location);\r
+\r
+        Rect anchorRect = new Rect(location[0], location[1], location[0]\r
+                + mAnchor.getWidth(), location[1] + mAnchor.getHeight());\r
+\r
+        createActionList();\r
+\r
+        root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,\r
+                LayoutParams.WRAP_CONTENT));\r
+        root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
+\r
+        int rootHeight = root.getMeasuredHeight();\r
+        int rootWidth = root.getMeasuredWidth();\r
+\r
+        int screenWidth = mWManager.getDefaultDisplay().getWidth();\r
+        int screenHeight = mWManager.getDefaultDisplay().getHeight();\r
+\r
+        // automatically get X coord of popup (top left)\r
+        if ((anchorRect.left + rootWidth) > screenWidth) {\r
+            xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());\r
+        } else {\r
+            if (mAnchor.getWidth() > rootWidth) {\r
+                xPos = anchorRect.centerX() - (rootWidth / 2);\r
+            } else {\r
+                xPos = anchorRect.left;\r
+            }\r
+        }\r
+\r
+        int dyTop = anchorRect.top;\r
+        int dyBottom = screenHeight - anchorRect.bottom;\r
+\r
+        boolean onTop = (dyTop > dyBottom) ? true : false;\r
+\r
+        if (onTop) {\r
+            if (rootHeight > dyTop) {\r
+                yPos = 15;\r
+                LayoutParams l = scroller.getLayoutParams();\r
+                l.height = dyTop - mAnchor.getHeight();\r
+            } else {\r
+                yPos = anchorRect.top - rootHeight;\r
+            }\r
+        } else {\r
+            yPos = anchorRect.bottom;\r
+\r
+            if (rootHeight > dyBottom) {\r
+                LayoutParams l = scroller.getLayoutParams();\r
+                l.height = dyBottom;\r
+            }\r
+        }\r
+\r
+        showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),\r
+                anchorRect.centerX() - xPos);\r
+\r
+        setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);\r
+\r
+        mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);\r
+    }\r
+\r
+    /**\r
+     * Set animation style\r
+     * \r
+     * @param screenWidth screen width\r
+     * @param requestedX distance from left edge\r
+     * @param onTop flag to indicate where the popup should be displayed. Set\r
+     *            TRUE if displayed on top of anchor view and vice versa\r
+     */\r
+    private void setAnimationStyle(int screenWidth, int requestedX,\r
+            boolean onTop) {\r
+        int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;\r
+\r
+        switch (animStyle) {\r
+        case ANIM_GROW_FROM_LEFT:\r
+            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left\r
+                    : R.style.Animations_PopDownMenu_Left);\r
+            break;\r
+\r
+        case ANIM_GROW_FROM_RIGHT:\r
+            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right\r
+                    : R.style.Animations_PopDownMenu_Right);\r
+            break;\r
+\r
+        case ANIM_GROW_FROM_CENTER:\r
+            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center\r
+                    : R.style.Animations_PopDownMenu_Center);\r
+            break;\r
+\r
+        case ANIM_REFLECT:\r
+            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect\r
+                    : R.style.Animations_PopDownMenu_Reflect);\r
+            break;\r
+\r
+        case ANIM_AUTO:\r
+            if (arrowPos <= screenWidth / 4) {\r
+                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left\r
+                        : R.style.Animations_PopDownMenu_Left);\r
+            } else if (arrowPos > screenWidth / 4\r
+                    && arrowPos < 3 * (screenWidth / 4)) {\r
+                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center\r
+                        : R.style.Animations_PopDownMenu_Center);\r
+            } else {\r
+                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right\r
+                        : R.style.Animations_PopDownMenu_Right);\r
+            }\r
+\r
+            break;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Create action list\r
+     */\r
+    private void createActionList() {\r
+        View view;\r
+        String title;\r
+        Drawable icon;\r
+        OnClickListener listener;\r
+\r
+        for (int i = 0; i < actionList.size(); i++) {\r
+            title = actionList.get(i).getTitle();\r
+            icon = actionList.get(i).getIcon();\r
+            listener = actionList.get(i).getOnClickListerner();\r
+\r
+            view = getActionItem(title, icon, listener);\r
+\r
+            view.setFocusable(true);\r
+            view.setClickable(true);\r
+\r
+            mTrack.addView(view);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Get action item {@link View}\r
+     * \r
+     * @param title action item title\r
+     * @param icon {@link Drawable} action item icon\r
+     * @param listener {@link View.OnClickListener} action item listener\r
+     * @return action item {@link View}\r
+     */\r
+    private View getActionItem(String title, Drawable icon,\r
+            OnClickListener listener) {\r
+        LinearLayout container = (LinearLayout) inflater.inflate(\r
+                R.layout.action_item, null);\r
+\r
+        ImageView img = (ImageView) container.findViewById(R.id.icon);\r
+        TextView text = (TextView) container.findViewById(R.id.title);\r
+\r
+        if (icon != null) {\r
+            img.setImageDrawable(icon);\r
+        }\r
+\r
+        if (title != null) {\r
+            text.setText(title);\r
+        }\r
+\r
+        if (listener != null) {\r
+            container.setOnClickListener(listener);\r
+        }\r
+\r
+        return container;\r
+    }\r
+\r
+    /**\r
+     * Show arrow\r
+     * \r
+     * @param whichArrow arrow type resource id\r
+     * @param requestedX distance from left screen\r
+     */\r
+    private void showArrow(int whichArrow, int requestedX) {\r
+        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp\r
+                : mArrowDown;\r
+        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown\r
+                : mArrowUp;\r
+\r
+        final int arrowWidth = mArrowUp.getMeasuredWidth();\r
+\r
+        showArrow.setVisibility(View.VISIBLE);\r
+\r
+        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow\r
+                .getLayoutParams();\r
+\r
+        param.leftMargin = requestedX - arrowWidth / 2;\r
+\r
+        hideArrow.setVisibility(View.INVISIBLE);\r
+    }\r
+}
\ No newline at end of file
diff --git a/src/com/owncloud/android/ui/activity/AccountSelectActivity.java b/src/com/owncloud/android/ui/activity/AccountSelectActivity.java
new file mode 100644 (file)
index 0000000..78ec8c0
--- /dev/null
@@ -0,0 +1,189 @@
+package com.owncloud.android.ui.activity;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+import android.widget.AdapterView.OnItemLongClickListener;
+import android.widget.CheckedTextView;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+
+import com.actionbarsherlock.app.ActionBar;
+import com.actionbarsherlock.app.SherlockListActivity;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+import com.owncloud.android.AccountUtils;
+import com.owncloud.android.authenticator.AccountAuthenticator;
+
+import com.owncloud.android.R;
+
+public class AccountSelectActivity extends SherlockListActivity implements
+        AccountManagerCallback<Boolean> {
+
+    private final Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        ActionBar action_bar = getSupportActionBar();
+        action_bar.setDisplayShowTitleEnabled(true);
+        action_bar.setDisplayHomeAsUpEnabled(false);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        populateAccountList();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getSherlock().getMenuInflater();
+        inflater.inflate(R.menu.account_picker, menu);
+        return true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        getMenuInflater().inflate(R.menu.account_picker_long_click, menu);
+        super.onCreateContextMenu(menu, v, menuInfo);
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        String accountName = ((TextView) v.findViewById(android.R.id.text1))
+                .getText().toString();
+        AccountUtils.setCurrentOwnCloudAccount(this, accountName);
+
+        // trigger synchronization when current account is changed
+        ContentResolver.cancelSync(null, "org.owncloud");
+        Bundle bundle = new Bundle();
+        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+        ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this), "org.owncloud", bundle);
+        
+        Intent i = new Intent(this, FileDisplayActivity.class);
+        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        startActivity(i);
+        finish();
+    }
+
+    @Override
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        if (item.getItemId() == R.id.createAccount) {
+            Intent intent = new Intent(
+                    android.provider.Settings.ACTION_ADD_ACCOUNT);
+            intent.putExtra("authorities",
+                    new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
+            startActivity(intent);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onContextItemSelected(android.view.MenuItem item) {
+        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
+                .getMenuInfo();
+        int index = info.position;
+        HashMap<String, String> map = (HashMap<String, String>) getListAdapter()
+                .getItem(index);
+        String accountName = map.get("NAME");
+        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+        Account accounts[] = am
+                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+        for (Account a : accounts) {
+            if (a.name.equals(accountName)) {
+                am.removeAccount(a, this, mHandler);
+            }
+        }
+
+        return false;
+    }
+
+    private void populateAccountList() {
+        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+        Account accounts[] = am
+                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+        LinkedList<HashMap<String, String>> ll = new LinkedList<HashMap<String, String>>();
+        for (Account a : accounts) {
+            HashMap<String, String> h = new HashMap<String, String>();
+            h.put("NAME", a.name);
+            h.put("VER",
+                    "ownCloud version: "
+                            + am.getUserData(a,
+                                    AccountAuthenticator.KEY_OC_VERSION));
+            ll.add(h);
+        }
+
+        setListAdapter(new AccountCheckedSimpleAdepter(this, ll,
+                android.R.layout.simple_list_item_single_choice,
+                new String[] { "NAME" }, new int[] { android.R.id.text1 }));
+        registerForContextMenu(getListView());
+    }
+
+    @Override
+    public void run(AccountManagerFuture<Boolean> future) {
+        if (future.isDone()) {
+            Account a = AccountUtils.getCurrentOwnCloudAccount(this);
+            String accountName = "";
+            if (a == null) {
+                Account[] accounts = AccountManager.get(this)
+                        .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
+                if (accounts.length != 0)
+                    accountName = accounts[0].name;
+                AccountUtils.setCurrentOwnCloudAccount(this, accountName);
+            }
+            populateAccountList();
+        }
+    }
+
+    private class AccountCheckedSimpleAdepter extends SimpleAdapter {
+        private Account mCurrentAccount;
+        private List<? extends Map<String, ?>> mPrivateData;
+
+        public AccountCheckedSimpleAdepter(Context context,
+                List<? extends Map<String, ?>> data, int resource,
+                String[] from, int[] to) {
+            super(context, data, resource, from, to);
+            mCurrentAccount = AccountUtils
+                    .getCurrentOwnCloudAccount(AccountSelectActivity.this);
+            mPrivateData = data;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View v = super.getView(position, convertView, parent);
+            CheckedTextView ctv = (CheckedTextView) v
+                    .findViewById(android.R.id.text1);
+            if (mPrivateData.get(position).get("NAME")
+                    .equals(mCurrentAccount.name)) {
+                ctv.setChecked(true);
+            }
+            return v;
+        }
+
+    }
+
+}
diff --git a/src/com/owncloud/android/ui/activity/AuthenticatorActivity.java b/src/com/owncloud/android/ui/activity/AuthenticatorActivity.java
new file mode 100644 (file)
index 0000000..4aa7cdd
--- /dev/null
@@ -0,0 +1,399 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2012  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.ui.activity;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+import java.net.URLEncoder;\r
+\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.authenticator.AuthenticationRunnable;\r
+import com.owncloud.android.authenticator.ConnectionCheckerRunnable;\r
+import com.owncloud.android.authenticator.OnAuthenticationResultListener;\r
+import com.owncloud.android.authenticator.OnConnectCheckListener;\r
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;\r
+import com.owncloud.android.extensions.ExtensionsAvailableActivity;\r
+import com.owncloud.android.utils.OwnCloudVersion;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountAuthenticatorActivity;\r
+import android.accounts.AccountManager;\r
+import android.app.Dialog;\r
+import android.app.ProgressDialog;\r
+import android.content.ContentResolver;\r
+import android.content.DialogInterface;\r
+import android.content.Intent;\r
+import android.content.SharedPreferences;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.preference.PreferenceManager;\r
+import android.text.InputType;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+import android.view.View.OnFocusChangeListener;\r
+import android.view.Window;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * This Activity is used to add an ownCloud account to the App\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
+        implements OnAuthenticationResultListener, OnConnectCheckListener,\r
+        OnFocusChangeListener, OnClickListener {\r
+    private static final int DIALOG_LOGIN_PROGRESS = 0;\r
+\r
+    private static final String TAG = "AuthActivity";\r
+\r
+    private Thread mAuthThread;\r
+    private AuthenticationRunnable mAuthRunnable;\r
+    private ConnectionCheckerRunnable mConnChkRunnable;\r
+    private final Handler mHandler = new Handler();\r
+    private String mBaseUrl;\r
+\r
+    private static final String STATUS_TEXT = "STATUS_TEXT";\r
+    private static final String STATUS_ICON = "STATUS_ICON";\r
+    private static final String STATUS_CORRECT = "STATUS_CORRECT";\r
+    private static final String IS_SSL_CONN = "IS_SSL_CONN";\r
+    private int mStatusText, mStatusIcon;\r
+    private boolean mStatusCorrect, mIsSslConn;\r
+\r
+    public static final String PARAM_USERNAME = "param_Username";\r
+    public static final String PARAM_HOSTNAME = "param_Hostname";\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+        setContentView(R.layout.account_setup);\r
+        ImageView iv = (ImageView) findViewById(R.id.refreshButton);\r
+        ImageView iv2 = (ImageView) findViewById(R.id.viewPassword);\r
+        TextView tv = (TextView) findViewById(R.id.host_URL);\r
+        TextView tv2 = (TextView) findViewById(R.id.account_password);\r
+\r
+        if (savedInstanceState != null) {\r
+            mStatusIcon = savedInstanceState.getInt(STATUS_ICON);\r
+            mStatusText = savedInstanceState.getInt(STATUS_TEXT);\r
+            mStatusCorrect = savedInstanceState.getBoolean(STATUS_CORRECT);\r
+            mIsSslConn = savedInstanceState.getBoolean(IS_SSL_CONN);\r
+            setResultIconAndText(mStatusIcon, mStatusText);\r
+            findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);\r
+            if (!mStatusCorrect)\r
+                iv.setVisibility(View.VISIBLE);\r
+            else\r
+                iv.setVisibility(View.INVISIBLE);\r
+\r
+        } else {\r
+            mStatusText = mStatusIcon = 0;\r
+            mStatusCorrect = false;\r
+            mIsSslConn = false;\r
+        }\r
+        iv.setOnClickListener(this);\r
+        iv2.setOnClickListener(this);\r
+        tv.setOnFocusChangeListener(this);\r
+        tv2.setOnFocusChangeListener(this);\r
+    }\r
+\r
+    @Override\r
+    protected void onSaveInstanceState(Bundle outState) {\r
+        outState.putInt(STATUS_ICON, mStatusIcon);\r
+        outState.putInt(STATUS_TEXT, mStatusText);\r
+        outState.putBoolean(STATUS_CORRECT, mStatusCorrect);\r
+        super.onSaveInstanceState(outState);\r
+    }\r
+\r
+    @Override\r
+    protected Dialog onCreateDialog(int id) {\r
+        Dialog dialog = null;\r
+        switch (id) {\r
+        case DIALOG_LOGIN_PROGRESS: {\r
+            ProgressDialog working_dialog = new ProgressDialog(this);\r
+            working_dialog.setMessage(getResources().getString(\r
+                    R.string.auth_trying_to_login));\r
+            working_dialog.setIndeterminate(true);\r
+            working_dialog.setCancelable(true);\r
+            working_dialog\r
+                    .setOnCancelListener(new DialogInterface.OnCancelListener() {\r
+                        @Override\r
+                        public void onCancel(DialogInterface dialog) {\r
+                            Log.i(TAG, "Login canceled");\r
+                            if (mAuthThread != null) {\r
+                                mAuthThread.interrupt();\r
+                                finish();\r
+                            }\r
+                        }\r
+                    });\r
+            dialog = working_dialog;\r
+            break;\r
+        }\r
+        default:\r
+            Log.e(TAG, "Incorrect dialog called with id = " + id);\r
+        }\r
+        return dialog;\r
+    }\r
+\r
+    public void onAuthenticationResult(boolean success, String message) {\r
+        if (success) {\r
+            TextView username_text = (TextView) findViewById(R.id.account_username), password_text = (TextView) findViewById(R.id.account_password);\r
+\r
+            URL url;\r
+            try {\r
+                url = new URL(message);\r
+            } catch (MalformedURLException e) {\r
+                // should never happen\r
+                Log.e(getClass().getName(), "Malformed URL: " + message);\r
+                return;\r
+            }\r
+\r
+            String username = username_text.getText().toString().trim();\r
+            String accountName = username + "@" + url.getHost();\r
+            if (url.getPort() >= 0) {\r
+                accountName += ":" + url.getPort();\r
+            }\r
+            Account account = new Account(accountName,\r
+                    AccountAuthenticator.ACCOUNT_TYPE);\r
+            AccountManager accManager = AccountManager.get(this);\r
+            accManager.addAccountExplicitly(account, password_text.getText()\r
+                    .toString(), null);\r
+\r
+            // Add this account as default in the preferences, if there is none\r
+            // already\r
+            Account defaultAccount = AccountUtils\r
+                    .getCurrentOwnCloudAccount(this);\r
+            if (defaultAccount == null) {\r
+                SharedPreferences.Editor editor = PreferenceManager\r
+                        .getDefaultSharedPreferences(this).edit();\r
+                editor.putString("select_oc_account", accountName);\r
+                editor.commit();\r
+            }\r
+\r
+            final Intent intent = new Intent();\r
+            intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,\r
+                    AccountAuthenticator.ACCOUNT_TYPE);\r
+            intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);\r
+            intent.putExtra(AccountManager.KEY_AUTHTOKEN,\r
+                    AccountAuthenticator.ACCOUNT_TYPE);\r
+            intent.putExtra(AccountManager.KEY_USERDATA, username);\r
+\r
+            accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,\r
+                    url.toString());\r
+            accManager.setUserData(account,\r
+                    AccountAuthenticator.KEY_OC_VERSION, mConnChkRunnable\r
+                            .getDiscoveredVersion().toString());\r
+            accManager.setUserData(account,\r
+                    AccountAuthenticator.KEY_OC_BASE_URL, mBaseUrl);\r
+\r
+            setAccountAuthenticatorResult(intent.getExtras());\r
+            setResult(RESULT_OK, intent);\r
+            Bundle bundle = new Bundle();\r
+            bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
+            //getContentResolver().startSync(ProviderTableMeta.CONTENT_URI,\r
+            //        bundle);\r
+            ContentResolver.requestSync(account, "org.owncloud", bundle);\r
+\r
+            /*\r
+             * if\r
+             * (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion\r
+             * .owncloud_v2) >= 0) { Intent i = new Intent(this,\r
+             * ExtensionsAvailableActivity.class); startActivity(i); }\r
+             */\r
+\r
+            finish();\r
+        } else {\r
+            dismissDialog(DIALOG_LOGIN_PROGRESS);\r
+            TextView tv = (TextView) findViewById(R.id.account_username);\r
+            tv.setError(message);\r
+        }\r
+    }\r
+    public void onCancelClick(View view) {\r
+        finish();\r
+    }\r
+    \r
+    public void onOkClick(View view) {\r
+        String prefix = "";\r
+        String url = ((TextView) findViewById(R.id.host_URL)).getText()\r
+                .toString();\r
+        if (mIsSslConn) {\r
+            prefix = "https://";\r
+        } else {\r
+            prefix = "http://";\r
+        }\r
+        if (url.toLowerCase().startsWith("http://")\r
+                || url.toLowerCase().startsWith("https://")) {\r
+            prefix = "";\r
+        }\r
+        continueConnection(prefix);\r
+    }\r
+\r
+    private void continueConnection(String prefix) {\r
+        String url = ((TextView) findViewById(R.id.host_URL)).getText()\r
+                .toString();\r
+        String username = ((TextView) findViewById(R.id.account_username))\r
+                .getText().toString();\r
+        String password = ((TextView) findViewById(R.id.account_password))\r
+                .getText().toString();\r
+        if (url.endsWith("/"))\r
+            url = url.substring(0, url.length() - 1);\r
+\r
+        URL uri = null;\r
+        String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable\r
+                .getDiscoveredVersion());\r
+\r
+        try {\r
+            mBaseUrl = prefix + url;\r
+            String url_str = prefix + url + webdav_path;\r
+            uri = new URL(url_str);\r
+        } catch (MalformedURLException e) {\r
+            // should not happend\r
+            e.printStackTrace();\r
+        }\r
+\r
+        showDialog(DIALOG_LOGIN_PROGRESS);\r
+        mAuthRunnable = new AuthenticationRunnable(uri, username, password);\r
+        mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);\r
+        mAuthThread = new Thread(mAuthRunnable);\r
+        mAuthThread.start();\r
+    }\r
+\r
+    @Override\r
+    public void onConnectionCheckResult(ResultType type) {\r
+        mStatusText = mStatusIcon = 0;\r
+        mStatusCorrect = false;\r
+        String t_url = ((TextView) findViewById(R.id.host_URL)).getText()\r
+                .toString().toLowerCase();\r
+\r
+        switch (type) {\r
+        case OK_SSL:\r
+            mIsSslConn = true;\r
+            mStatusIcon = android.R.drawable.ic_secure;\r
+            mStatusText = R.string.auth_secure_connection;\r
+            mStatusCorrect = true;\r
+            break;\r
+        case OK_NO_SSL:\r
+            mIsSslConn = false;\r
+            mStatusCorrect = true;\r
+            if (t_url.startsWith("http://") ) {\r
+                mStatusText = R.string.auth_connection_established;\r
+                mStatusIcon = R.drawable.ic_ok;\r
+            } else {\r
+                mStatusText = R.string.auth_nossl_plain_ok_title;\r
+                mStatusIcon = android.R.drawable.ic_partial_secure;\r
+            }\r
+            break;\r
+        case TIMEOUT:\r
+        case INORRECT_ADDRESS:\r
+        case SSL_INIT_ERROR:\r
+        case HOST_NOT_AVAILABLE:\r
+            mStatusIcon = R.drawable.common_error;\r
+            mStatusText = R.string.auth_unknow_host_title;\r
+            break;\r
+        case NO_NETWORK_CONNECTION:\r
+            mStatusIcon = R.drawable.no_network;\r
+            mStatusText = R.string.auth_no_net_conn_title;\r
+            break;\r
+        case INSTANCE_NOT_CONFIGURED:\r
+            mStatusIcon = R.drawable.common_error;\r
+            mStatusText = R.string.auth_not_configured_title;\r
+            break;\r
+        case UNKNOWN_ERROR:\r
+            mStatusIcon = R.drawable.common_error;\r
+            mStatusText = R.string.auth_unknow_error;\r
+            break;\r
+        case FILE_NOT_FOUND:\r
+            mStatusIcon = R.drawable.common_error;\r
+            mStatusText = R.string.auth_incorrect_path_title;\r
+            break;\r
+        default:\r
+            Log.e(TAG, "Incorrect connection checker result type: " + type);\r
+        }\r
+        setResultIconAndText(mStatusIcon, mStatusText);\r
+        if (!mStatusCorrect)\r
+            findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);\r
+        else\r
+            findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);\r
+        findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);\r
+    }\r
+\r
+    @Override\r
+    public void onFocusChange(View view, boolean hasFocus) {\r
+        if (view.getId() == R.id.host_URL) {\r
+            if (!hasFocus) {\r
+                TextView tv = ((TextView) findViewById(R.id.host_URL));\r
+                String uri = tv.getText().toString();\r
+                if (uri.length() != 0) {\r
+                    setResultIconAndText(R.drawable.progress_small,\r
+                            R.string.auth_testing_connection);\r
+                    findViewById(R.id.buttonOK).setEnabled(false);  // avoid connect can be clicked if the test was previously passed\r
+                    mConnChkRunnable = new ConnectionCheckerRunnable(uri, this);\r
+                    mConnChkRunnable.setListener(this, mHandler);\r
+                    mAuthThread = new Thread(mConnChkRunnable);\r
+                    mAuthThread.start();\r
+                } else {\r
+                    findViewById(R.id.refreshButton).setVisibility(\r
+                            View.INVISIBLE);\r
+                    setResultIconAndText(0, 0);\r
+                }\r
+            }\r
+        } else if (view.getId() == R.id.account_password) {\r
+            ImageView iv = (ImageView) findViewById(R.id.viewPassword);\r
+            if (hasFocus) {\r
+                iv.setVisibility(View.VISIBLE);\r
+            } else {\r
+                TextView v = (TextView) findViewById(R.id.account_password);\r
+                int input_type = InputType.TYPE_CLASS_TEXT\r
+                        | InputType.TYPE_TEXT_VARIATION_PASSWORD;\r
+                v.setInputType(input_type);\r
+                iv.setVisibility(View.INVISIBLE);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void setResultIconAndText(int drawable_id, int text_id) {\r
+        ImageView iv = (ImageView) findViewById(R.id.action_indicator);\r
+        TextView tv = (TextView) findViewById(R.id.status_text);\r
+\r
+        if (drawable_id == 0 && text_id == 0) {\r
+            iv.setVisibility(View.INVISIBLE);\r
+            tv.setVisibility(View.INVISIBLE);\r
+        } else {\r
+            iv.setImageResource(drawable_id);\r
+            tv.setText(text_id);\r
+            iv.setVisibility(View.VISIBLE);\r
+            tv.setVisibility(View.VISIBLE);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void onClick(View v) {\r
+        if (v.getId() == R.id.refreshButton) {\r
+            onFocusChange(findViewById(R.id.host_URL), false);\r
+        } else if (v.getId() == R.id.viewPassword) {\r
+            TextView view = (TextView) findViewById(R.id.account_password);\r
+            int input_type = InputType.TYPE_CLASS_TEXT\r
+                    | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;\r
+            view.setInputType(input_type);\r
+        }\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/ui/activity/FileDetailActivity.java b/src/com/owncloud/android/ui/activity/FileDetailActivity.java
new file mode 100644 (file)
index 0000000..3c80a48
--- /dev/null
@@ -0,0 +1,144 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.activity;\r
+\r
+import android.accounts.Account;\r
+import android.app.Dialog;\r
+import android.app.ProgressDialog;\r
+import android.content.Intent;\r
+import android.content.res.Configuration;\r
+import android.os.Bundle;\r
+import android.support.v4.app.FragmentTransaction;\r
+\r
+import com.actionbarsherlock.app.ActionBar;\r
+import com.actionbarsherlock.app.SherlockFragmentActivity;\r
+import com.actionbarsherlock.view.MenuItem;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.files.services.FileDownloader;\r
+import com.owncloud.android.ui.fragment.FileDetailFragment;\r
+\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * This activity displays the details of a file like its name, its size and so\r
+ * on.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class FileDetailActivity extends SherlockFragmentActivity implements FileDetailFragment.ContainerActivity {\r
+    \r
+    public static final int DIALOG_SHORT_WAIT = 0;\r
+    \r
+    private boolean mConfigurationChangedToLandscape = false;\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+\r
+        // check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity \r
+        Configuration conf = getResources().getConfiguration();\r
+        mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE && \r
+                                                (conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE\r
+                                           );\r
+\r
+        if (!mConfigurationChangedToLandscape) {\r
+            setContentView(R.layout.file_activity_details);\r
+        \r
+            ActionBar actionBar = getSupportActionBar();\r
+            actionBar.setDisplayHomeAsUpEnabled(true);\r
+        \r
+            OCFile file = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);\r
+            Account account = getIntent().getParcelableExtra(FileDownloader.EXTRA_ACCOUNT);\r
+            FileDetailFragment mFileDetail = new FileDetailFragment(file, account);\r
+        \r
+            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
+            ft.replace(R.id.fragment, mFileDetail, FileDetailFragment.FTAG);\r
+            ft.commit();\r
+            \r
+        }  else {\r
+            backToDisplayActivity();   // the 'back' won't be effective until this.onStart() and this.onResume() are completed;\r
+        }\r
+        \r
+        \r
+    }\r
+\r
+    @Override\r
+    public boolean onOptionsItemSelected(MenuItem item) {\r
+        boolean returnValue = false;\r
+        \r
+        switch(item.getItemId()){\r
+        case android.R.id.home:\r
+            backToDisplayActivity();\r
+            returnValue = true;\r
+        }\r
+        \r
+        return returnValue;\r
+    }\r
+\r
+\r
+\r
+    @Override\r
+    protected void onResume() {\r
+        \r
+        super.onResume();\r
+        if (!mConfigurationChangedToLandscape) { \r
+            FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);\r
+            fragment.updateFileDetails();\r
+        }\r
+    }\r
+    \r
+\r
+    private void backToDisplayActivity() {\r
+        Intent intent = new Intent(this, FileDisplayActivity.class);\r
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);\r
+        intent.putExtra(FileDetailFragment.EXTRA_FILE, getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE));\r
+        startActivity(intent);\r
+        finish();\r
+    }\r
+    \r
+    \r
+    @Override\r
+    protected Dialog onCreateDialog(int id) {\r
+        Dialog dialog = null;\r
+        switch (id) {\r
+        case DIALOG_SHORT_WAIT: {\r
+            ProgressDialog working_dialog = new ProgressDialog(this);\r
+            working_dialog.setMessage(getResources().getString(\r
+                    R.string.wait_a_moment));\r
+            working_dialog.setIndeterminate(true);\r
+            working_dialog.setCancelable(false);\r
+            dialog = working_dialog;\r
+            break;\r
+        }\r
+        default:\r
+            dialog = null;\r
+        }\r
+        return dialog;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onFileStateChanged() {\r
+        // nothing to do here!\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/activity/FileDisplayActivity.java b/src/com/owncloud/android/ui/activity/FileDisplayActivity.java
new file mode 100644 (file)
index 0000000..54c99e6
--- /dev/null
@@ -0,0 +1,886 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package com.owncloud.android.ui.activity;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.ProgressDialog;\r
+import android.app.AlertDialog.Builder;\r
+import android.app.Dialog;\r
+import android.content.BroadcastReceiver;\r
+import android.content.ContentResolver;\r
+import android.content.Context;\r
+import android.content.DialogInterface;\r
+import android.content.DialogInterface.OnClickListener;\r
+import android.content.Intent;\r
+import android.content.IntentFilter;\r
+import android.content.SharedPreferences;\r
+import android.content.pm.PackageInfo;\r
+import android.content.pm.PackageManager.NameNotFoundException;\r
+import android.content.res.Resources.NotFoundException;\r
+import android.database.Cursor;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.preference.PreferenceManager;\r
+import android.provider.MediaStore;\r
+import android.support.v4.app.FragmentTransaction;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.ArrayAdapter;\r
+import android.widget.EditText;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+\r
+import com.actionbarsherlock.app.ActionBar;\r
+import com.actionbarsherlock.app.ActionBar.OnNavigationListener;\r
+import com.actionbarsherlock.app.SherlockFragmentActivity;\r
+import com.actionbarsherlock.view.Menu;\r
+import com.actionbarsherlock.view.MenuInflater;\r
+import com.actionbarsherlock.view.MenuItem;\r
+import com.actionbarsherlock.view.Window;\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.CrashHandler;\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.datamodel.DataStorageManager;\r
+import com.owncloud.android.datamodel.FileDataStorageManager;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.files.services.FileDownloader;\r
+import com.owncloud.android.files.services.FileUploader;\r
+import com.owncloud.android.syncadapter.FileSyncService;\r
+import com.owncloud.android.ui.fragment.FileDetailFragment;\r
+import com.owncloud.android.ui.fragment.FileListFragment;\r
+\r
+import com.owncloud.android.R;\r
+import eu.alefzero.webdav.WebdavClient;\r
+\r
+/**\r
+ * Displays, what files the user has available in his ownCloud.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+\r
+public class FileDisplayActivity extends SherlockFragmentActivity implements\r
+    FileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener  {\r
+    \r
+    private ArrayAdapter<String> mDirectories;\r
+    private OCFile mCurrentDir;\r
+    private String[] mDirs = null;\r
+\r
+    private DataStorageManager mStorageManager;\r
+    private SyncBroadcastReceiver mSyncBroadcastReceiver;\r
+    private UploadFinishReceiver mUploadFinishReceiver;\r
+    private DownloadFinishReceiver mDownloadFinishReceiver;\r
+    \r
+    private View mLayoutView = null;\r
+    private FileListFragment mFileList;\r
+    \r
+    private boolean mDualPane;\r
+    \r
+    private boolean mForcedLoginToCreateFirstAccount = false;\r
+    \r
+    private static final String KEY_DIR_ARRAY = "DIR_ARRAY";\r
+    private static final String KEY_CURRENT_DIR = "DIR";\r
+    \r
+    private static final int DIALOG_SETUP_ACCOUNT = 0;\r
+    private static final int DIALOG_CREATE_DIR = 1;\r
+    private static final int DIALOG_ABOUT_APP = 2;\r
+    public static final int DIALOG_SHORT_WAIT = 3;\r
+    \r
+    private static final int ACTION_SELECT_FILE = 1;\r
+    \r
+    private static final String TAG = "FileDisplayActivity";\r
+    \r
+    \r
+    @Override\r
+    public void onCreate(Bundle savedInstanceState) {\r
+        Log.i(getClass().toString(), "onCreate() start");\r
+        super.onCreate(savedInstanceState);\r
+\r
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);\r
+\r
+        Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext()));\r
+\r
+        if(savedInstanceState != null) {\r
+            mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);\r
+            mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);\r
+            mDirectories.add(OCFile.PATH_SEPARATOR);\r
+            if (mDirs != null)\r
+                for (String s : mDirs)\r
+                    mDirectories.insert(s, 0);\r
+            mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);\r
+        }\r
+        \r
+        mLayoutView = getLayoutInflater().inflate(R.layout.files, null);  // always inflate this at onCreate() ; just once!\r
+        \r
+        if (AccountUtils.accountsAreSetup(this)) {\r
+            \r
+            initDelayedTilAccountAvailabe();\r
+            \r
+            // PIN CODE request ;  best location is to decide, let's try this first\r
+            //if (savedInstanceState == null) {\r
+            if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {\r
+                requestPinCode();\r
+            }\r
+            \r
+            \r
+        } else {\r
+            \r
+            setContentView(R.layout.no_account_available);\r
+            getSupportActionBar().setNavigationMode(ActionBar.DISPLAY_SHOW_TITLE);\r
+            findViewById(R.id.setup_account).setOnClickListener(this);\r
+\r
+            setSupportProgressBarIndeterminateVisibility(false);\r
+\r
+            Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);\r
+            intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+            startActivity(intent);  // although the code is here, the activity won't be created until this.onStart() and this.onResume() are finished;\r
+            mForcedLoginToCreateFirstAccount = true;\r
+        }\r
+        \r
+        Log.i(getClass().toString(), "onCreate() end");\r
+    }\r
+\r
+    @Override\r
+    public boolean onCreateOptionsMenu(Menu menu) {\r
+        MenuInflater inflater = getSherlock().getMenuInflater();\r
+            inflater.inflate(R.menu.menu, menu);\r
+            return true;\r
+    }\r
+\r
+    @Override\r
+    public boolean onOptionsItemSelected(MenuItem item) {\r
+        boolean retval = true;\r
+        switch (item.getItemId()) {\r
+            case R.id.createDirectoryItem: {\r
+                showDialog(DIALOG_CREATE_DIR);\r
+                break;\r
+            }\r
+            case R.id.startSync: {\r
+                ContentResolver.cancelSync(null, "org.owncloud");   // cancel the current synchronizations of any ownCloud account\r
+                Bundle bundle = new Bundle();\r
+                bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
+                ContentResolver.requestSync(\r
+                        AccountUtils.getCurrentOwnCloudAccount(this),\r
+                        "org.owncloud", bundle);\r
+                break;\r
+            }\r
+            case R.id.action_upload: {\r
+                Intent action = new Intent(Intent.ACTION_GET_CONTENT);\r
+                action = action.setType("*/*")\r
+                        .addCategory(Intent.CATEGORY_OPENABLE);\r
+                startActivityForResult(\r
+                        Intent.createChooser(action, getString(R.string.upload_chooser_title)),\r
+                        ACTION_SELECT_FILE);\r
+                break;\r
+            }\r
+            case R.id.action_settings: {\r
+                Intent settingsIntent = new Intent(this, Preferences.class);\r
+                startActivity(settingsIntent);\r
+                break;\r
+            }\r
+            case R.id.about_app : {\r
+                showDialog(DIALOG_ABOUT_APP);\r
+                break;\r
+            }\r
+            case android.R.id.home: {\r
+                if(mCurrentDir != null && mCurrentDir.getParentId() != 0){\r
+                    onBackPressed(); \r
+                }\r
+                break;\r
+            }\r
+            default:\r
+                retval = false;\r
+        }\r
+        return retval;\r
+    }\r
+\r
+    @Override\r
+    public boolean onNavigationItemSelected(int itemPosition, long itemId) {\r
+        int i = itemPosition;\r
+        while (i-- != 0) {\r
+            onBackPressed();\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Called, when the user selected something for uploading\r
+     */\r
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        if (requestCode == ACTION_SELECT_FILE) {\r
+            if (resultCode == RESULT_OK) {\r
+                String filepath = null;\r
+                try {\r
+                    Uri selectedImageUri = data.getData();\r
+    \r
+                    String filemanagerstring = selectedImageUri.getPath();\r
+                    String selectedImagePath = getPath(selectedImageUri);\r
+    \r
+                    if (selectedImagePath != null)\r
+                        filepath = selectedImagePath;\r
+                    else\r
+                        filepath = filemanagerstring;\r
+                    \r
+                } catch (Exception e) {\r
+                    Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);\r
+                    e.printStackTrace();\r
+                    \r
+                } finally {\r
+                    if (filepath == null) {\r
+                        Log.e("FileDisplay", "Couldnt resolve path to file");\r
+                        Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);\r
+                        t.show();\r
+                        return;\r
+                    }\r
+                }\r
+    \r
+                Intent i = new Intent(this, FileUploader.class);\r
+                i.putExtra(FileUploader.KEY_ACCOUNT,\r
+                        AccountUtils.getCurrentOwnCloudAccount(this));\r
+                String remotepath = new String();\r
+                for (int j = mDirectories.getCount() - 2; j >= 0; --j) {\r
+                    remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);\r
+                }\r
+                if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))\r
+                    remotepath += OCFile.PATH_SEPARATOR;\r
+                remotepath += new File(filepath).getName();\r
+    \r
+                i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);\r
+                i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);\r
+                i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);\r
+                startService(i);\r
+            }\r
+            \r
+        }/* dvelasco: WIP - not working as expected ... yet :)\r
+             else if (requestCode == ACTION_CREATE_FIRST_ACCOUNT) {\r
+            if (resultCode != RESULT_OK) {\r
+                finish();   // the user cancelled the AuthenticatorActivity\r
+            }\r
+        }*/\r
+    }\r
+\r
+    @Override\r
+    public void onBackPressed() {\r
+        if (mDirectories == null || mDirectories.getCount() <= 1) {\r
+            finish();\r
+            return;\r
+        }\r
+        popDirname();\r
+        mFileList.onNavigateUp();\r
+        mCurrentDir = mFileList.getCurrentFile();\r
+        \r
+        if(mCurrentDir.getParentId() == 0){\r
+            ActionBar actionBar = getSupportActionBar(); \r
+            actionBar.setDisplayHomeAsUpEnabled(false);\r
+        } \r
+    }\r
+\r
+    @Override\r
+    protected void onSaveInstanceState(Bundle outState) {\r
+        // responsability of restore is prefered in onCreate() before than in onRestoreInstanceState when there are Fragments involved\r
+        Log.i(getClass().toString(), "onSaveInstanceState() start");\r
+        super.onSaveInstanceState(outState);\r
+        if(mDirectories != null && mDirectories.getCount() != 0){\r
+            mDirs = new String[mDirectories.getCount()-1];\r
+            for (int j = mDirectories.getCount() - 2, i = 0; j >= 0; --j, ++i) {\r
+                mDirs[i] = mDirectories.getItem(j);\r
+            }\r
+        }\r
+        outState.putStringArray(KEY_DIR_ARRAY, mDirs);\r
+        outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);\r
+        Log.i(getClass().toString(), "onSaveInstanceState() end");\r
+    }\r
+\r
+    @Override\r
+    protected void onResume() {\r
+        Log.i(getClass().toString(), "onResume() start");\r
+        super.onResume();\r
+\r
+        if (AccountUtils.accountsAreSetup(this)) {\r
+         // at least an account exist: normal operation\r
+            \r
+            // set the layout only if it couldn't be set in onCreate\r
+            if (mForcedLoginToCreateFirstAccount) {\r
+                initDelayedTilAccountAvailabe();\r
+                mForcedLoginToCreateFirstAccount = false;\r
+            }\r
+\r
+            // Listen for sync messages\r
+            IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);\r
+            mSyncBroadcastReceiver = new SyncBroadcastReceiver();\r
+            registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);\r
+            \r
+            // Listen for upload messages\r
+            IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);\r
+            mUploadFinishReceiver = new UploadFinishReceiver();\r
+            registerReceiver(mUploadFinishReceiver, uploadIntentFilter);\r
+            \r
+            // Listen for download messages\r
+            IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);\r
+            mDownloadFinishReceiver = new DownloadFinishReceiver();\r
+            registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);\r
+        \r
+            // Storage manager initialization\r
+            mStorageManager = new FileDataStorageManager(\r
+                    AccountUtils.getCurrentOwnCloudAccount(this),\r
+                    getContentResolver());\r
+        \r
+            // File list fragments   \r
+            mFileList = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
+            \r
+            \r
+            // Figure out what directory to list. \r
+            // Priority: Intent (here), savedInstanceState (onCreate), root dir (dir is null)\r
+            if(getIntent().hasExtra(FileDetailFragment.EXTRA_FILE)){\r
+                mCurrentDir = (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);\r
+                if(mCurrentDir != null && !mCurrentDir.isDirectory()){\r
+                    mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());\r
+                }\r
+            \r
+                // Clear intent extra, so rotating the screen will not return us to this directory\r
+                getIntent().removeExtra(FileDetailFragment.EXTRA_FILE);\r
+            }\r
+            \r
+            if (mCurrentDir == null)\r
+                mCurrentDir = mStorageManager.getFileByPath("/");\r
+                \r
+            // Drop-Down navigation and file list restore\r
+            mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);\r
+        \r
+        \r
+            // Given the case we have a file to display:\r
+            if(mCurrentDir != null){\r
+                ArrayList<OCFile> files = new ArrayList<OCFile>();\r
+                OCFile currFile = mCurrentDir;\r
+                while(currFile != null){\r
+                    files.add(currFile);\r
+                    currFile = mStorageManager.getFileById(currFile.getParentId());\r
+                }\r
+            \r
+                // Insert in mDirs\r
+                mDirs = new String[files.size()];\r
+                for(int i = files.size() - 1; i >= 0; i--){\r
+                    mDirs[i] = files.get(i).getFileName();\r
+                }\r
+            }\r
+        \r
+            if (mDirs != null) {\r
+                for (String s : mDirs)\r
+                    mDirectories.add(s);\r
+            } else {\r
+                mDirectories.add(OCFile.PATH_SEPARATOR);\r
+            }\r
+               \r
+            // Actionbar setup\r
+            ActionBar action_bar = getSupportActionBar();\r
+            action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);\r
+            action_bar.setDisplayShowTitleEnabled(false);\r
+            action_bar.setListNavigationCallbacks(mDirectories, this);\r
+            if(mCurrentDir != null && mCurrentDir.getParentId() != 0){\r
+                action_bar.setDisplayHomeAsUpEnabled(true);\r
+            } else {\r
+                action_bar.setDisplayHomeAsUpEnabled(false);\r
+            }\r
+        \r
+            // List dir here\r
+            mFileList.listDirectory(mCurrentDir);\r
+        }\r
+        Log.i(getClass().toString(), "onResume() end");\r
+    }\r
+\r
+    @Override\r
+    protected void onPause() {\r
+        Log.i(getClass().toString(), "onPause() start");\r
+        super.onPause();\r
+        if (mSyncBroadcastReceiver != null) {\r
+            unregisterReceiver(mSyncBroadcastReceiver);\r
+            mSyncBroadcastReceiver = null;\r
+        }\r
+        if (mUploadFinishReceiver != null) {\r
+            unregisterReceiver(mUploadFinishReceiver);\r
+            mUploadFinishReceiver = null;\r
+        }\r
+        if (mDownloadFinishReceiver != null) {\r
+            unregisterReceiver(mDownloadFinishReceiver);\r
+            mDownloadFinishReceiver = null;\r
+        }\r
+        \r
+        getIntent().putExtra(FileDetailFragment.EXTRA_FILE, mCurrentDir);\r
+        Log.i(getClass().toString(), "onPause() end");\r
+    }\r
+\r
+    @Override\r
+    protected Dialog onCreateDialog(int id) {\r
+        Dialog dialog = null;\r
+        AlertDialog.Builder builder;\r
+        switch (id) {\r
+        case DIALOG_SETUP_ACCOUNT:\r
+            builder = new AlertDialog.Builder(this);\r
+            builder.setTitle(R.string.main_tit_accsetup);\r
+            builder.setMessage(R.string.main_wrn_accsetup);\r
+            builder.setCancelable(false);\r
+            builder.setPositiveButton(android.R.string.ok, this);\r
+            builder.setNegativeButton(android.R.string.cancel, this);\r
+            dialog = builder.create();\r
+            break;\r
+        case DIALOG_ABOUT_APP: {\r
+            builder = new AlertDialog.Builder(this);\r
+            builder.setTitle(getString(R.string.about_title));\r
+            PackageInfo pkg;\r
+            try {\r
+                pkg = getPackageManager().getPackageInfo(getPackageName(), 0);\r
+                builder.setMessage("ownCloud android client\n\nversion: " + pkg.versionName );\r
+                builder.setIcon(android.R.drawable.ic_menu_info_details);\r
+                dialog = builder.create();\r
+            } catch (NameNotFoundException e) {\r
+                builder = null;\r
+                dialog = null;\r
+                Log.e(TAG, "Error while showing about dialog", e);\r
+            }\r
+            break;\r
+        }\r
+        case DIALOG_CREATE_DIR: {\r
+            builder = new Builder(this);\r
+            final EditText dirNameInput = new EditText(getBaseContext());\r
+            final Account a = AccountUtils.getCurrentOwnCloudAccount(this);\r
+            builder.setView(dirNameInput);\r
+            builder.setTitle(R.string.uploader_info_dirname);\r
+            int typed_color = getResources().getColor(R.color.setup_text_typed);\r
+            dirNameInput.setTextColor(typed_color);\r
+            builder.setPositiveButton(android.R.string.ok,\r
+                    new OnClickListener() {\r
+                        public void onClick(DialogInterface dialog, int which) {\r
+                            String directoryName = dirNameInput.getText().toString();\r
+                            if (directoryName.trim().length() == 0) {\r
+                                dialog.cancel();\r
+                                return;\r
+                            }\r
+    \r
+                            // Figure out the path where the dir needs to be created\r
+                            String path;\r
+                            if (mCurrentDir == null) {\r
+                                // this is just a patch; we should ensure that mCurrentDir never is null\r
+                                if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {\r
+                                    OCFile file = new OCFile(OCFile.PATH_SEPARATOR);\r
+                                    mStorageManager.saveFile(file);\r
+                                }\r
+                                mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);\r
+                            }\r
+                            path = FileDisplayActivity.this.mCurrentDir.getRemotePath();\r
+                            \r
+                            // Create directory\r
+                            path += directoryName + OCFile.PATH_SEPARATOR;\r
+                            Thread thread = new Thread(new DirectoryCreator(path, a, new Handler()));\r
+                            thread.start();\r
+                            \r
+                            dialog.dismiss();\r
+                            \r
+                            showDialog(DIALOG_SHORT_WAIT);\r
+                        }\r
+                    });\r
+            builder.setNegativeButton(R.string.common_cancel,\r
+                    new OnClickListener() {\r
+                        public void onClick(DialogInterface dialog, int which) {\r
+                            dialog.cancel();\r
+                        }\r
+                    });\r
+            dialog = builder.create();\r
+            break;\r
+        }\r
+        case DIALOG_SHORT_WAIT: {\r
+            ProgressDialog working_dialog = new ProgressDialog(this);\r
+            working_dialog.setMessage(getResources().getString(\r
+                    R.string.wait_a_moment));\r
+            working_dialog.setIndeterminate(true);\r
+            working_dialog.setCancelable(false);\r
+            dialog = working_dialog;\r
+            break;\r
+        }\r
+        default:\r
+            dialog = null;\r
+        }\r
+    \r
+        return dialog;\r
+    }\r
+\r
+    \r
+    /**\r
+     * Responds to the "There are no ownCloud Accounts setup" dialog\r
+     * TODO: Dialog is 100% useless -> Remove\r
+     */\r
+    @Override\r
+    public void onClick(DialogInterface dialog, int which) {\r
+        // In any case - we won't need it anymore\r
+        dialog.dismiss();\r
+        switch (which) {\r
+        case DialogInterface.BUTTON_POSITIVE:\r
+            Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+            intent.putExtra("authorities",\r
+                    new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+            startActivity(intent);\r
+            break;\r
+        case DialogInterface.BUTTON_NEGATIVE:\r
+            finish();\r
+        }\r
+    \r
+    }\r
+\r
+    /**\r
+     * Translates a content URI of an image to a physical path\r
+     * on the disk\r
+     * @param uri The URI to resolve\r
+     * @return The path to the image or null if it could not be found\r
+     */\r
+    public String getPath(Uri uri) {\r
+        String[] projection = { MediaStore.Images.Media.DATA };\r
+        Cursor cursor = managedQuery(uri, projection, null, null, null);\r
+        if (cursor != null) {\r
+            int column_index = cursor\r
+                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);\r
+            cursor.moveToFirst();\r
+            return cursor.getString(column_index);\r
+        } \r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * Pushes a directory to the drop down list\r
+     * @param directory to push\r
+     * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.\r
+     */\r
+    public void pushDirname(OCFile directory) {\r
+        if(!directory.isDirectory()){\r
+            throw new IllegalArgumentException("Only directories may be pushed!");\r
+        }\r
+        mDirectories.insert(directory.getFileName(), 0);\r
+        mCurrentDir = directory;\r
+    }\r
+\r
+    /**\r
+     * Pops a directory name from the drop down list\r
+     * @return True, unless the stack is empty\r
+     */\r
+    public boolean popDirname() {\r
+        mDirectories.remove(mDirectories.getItem(0));\r
+        return !mDirectories.isEmpty();\r
+    }\r
+\r
+    private class DirectoryCreator implements Runnable {\r
+        private String mTargetPath;\r
+        private Account mAccount;\r
+        private AccountManager mAm;\r
+        private Handler mHandler; \r
+    \r
+        public DirectoryCreator(String targetPath, Account account, Handler handler) {\r
+            mTargetPath = targetPath;\r
+            mAccount = account;\r
+            mAm = (AccountManager) getSystemService(ACCOUNT_SERVICE);\r
+            mHandler = handler;\r
+        }\r
+    \r
+        @Override\r
+        public void run() {\r
+            WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());\r
+            \r
+            String username = mAccount.name.substring(0,\r
+                    mAccount.name.lastIndexOf('@'));\r
+            String password = mAm.getPassword(mAccount);\r
+    \r
+            wdc.setCredentials(username, password);\r
+            wdc.allowSelfsignedCertificates();\r
+            boolean created = wdc.createDirectory(mTargetPath);\r
+            if (created) {\r
+                mHandler.post(new Runnable() {\r
+                    @Override\r
+                    public void run() { \r
+                        dismissDialog(DIALOG_SHORT_WAIT);\r
+                        \r
+                        // Save new directory in local database\r
+                        OCFile newDir = new OCFile(mTargetPath);\r
+                        newDir.setMimetype("DIR");\r
+                        newDir.setParentId(mCurrentDir.getFileId());\r
+                        mStorageManager.saveFile(newDir);\r
+    \r
+                        // Display the new folder right away\r
+                        mFileList.listDirectory(mCurrentDir);\r
+                    }\r
+                });\r
+                \r
+            } else {\r
+                mHandler.post(new Runnable() {\r
+                    @Override\r
+                    public void run() {\r
+                        dismissDialog(DIALOG_SHORT_WAIT);\r
+                        try {\r
+                            Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG); \r
+                            msg.show();\r
+                        \r
+                        } catch (NotFoundException e) {\r
+                            Log.e(TAG, "Error while trying to show fail message " , e);\r
+                        }\r
+                    }\r
+                });\r
+            }\r
+        }\r
+    \r
+    }\r
+\r
+    // Custom array adapter to override text colors\r
+    private class CustomArrayAdapter<T> extends ArrayAdapter<T> {\r
+    \r
+        public CustomArrayAdapter(FileDisplayActivity ctx, int view) {\r
+            super(ctx, view);\r
+        }\r
+    \r
+        public View getView(int position, View convertView, ViewGroup parent) {\r
+            View v = super.getView(position, convertView, parent);\r
+    \r
+            ((TextView) v).setTextColor(getResources().getColorStateList(\r
+                    android.R.color.white));\r
+            return v;\r
+        }\r
+    \r
+        public View getDropDownView(int position, View convertView,\r
+                ViewGroup parent) {\r
+            View v = super.getDropDownView(position, convertView, parent);\r
+    \r
+            ((TextView) v).setTextColor(getResources().getColorStateList(\r
+                    android.R.color.white));\r
+    \r
+            return v;\r
+        }\r
+    \r
+    }\r
+\r
+    private class SyncBroadcastReceiver extends BroadcastReceiver {\r
+        /**\r
+         * {@link BroadcastReceiver} to enable syncing feedback in UI\r
+         */\r
+        @Override\r
+        public void onReceive(Context context, Intent intent) {\r
+            boolean inProgress = intent.getBooleanExtra(\r
+                    FileSyncService.IN_PROGRESS, false);\r
+            String accountName = intent\r
+                    .getStringExtra(FileSyncService.ACCOUNT_NAME);\r
+\r
+            Log.d("FileDisplay", "sync of account " + accountName\r
+                    + " is in_progress: " + inProgress);\r
+\r
+            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {  \r
+            \r
+                String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH); \r
+                 \r
+                boolean fillBlankRoot = false;\r
+                if (mCurrentDir == null) {\r
+                    mCurrentDir = mStorageManager.getFileByPath("/");\r
+                    fillBlankRoot = (mCurrentDir != null);\r
+                }\r
+\r
+                if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath().equals(synchFolderRemotePath)))\r
+                        || fillBlankRoot ) {\r
+                    if (!fillBlankRoot) \r
+                        mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);\r
+                    FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager()\r
+                            .findFragmentById(R.id.fileList);\r
+                    if (fileListFragment != null) {\r
+                        fileListFragment.listDirectory(mCurrentDir);  \r
+                    }\r
+                }\r
+                \r
+                setSupportProgressBarIndeterminateVisibility(inProgress);\r
+                \r
+            }\r
+        }\r
+    }\r
+    \r
+\r
+    private class UploadFinishReceiver extends BroadcastReceiver {\r
+        /**\r
+         * Once the file upload has finished -> update view\r
+         *  @author David A. Velasco\r
+         * {@link BroadcastReceiver} to enable upload feedback in UI\r
+         */\r
+        @Override\r
+        public void onReceive(Context context, Intent intent) {\r
+            long parentDirId = intent.getLongExtra(FileUploader.EXTRA_PARENT_DIR_ID, -1);\r
+            OCFile parentDir = mStorageManager.getFileById(parentDirId);\r
+            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);\r
+\r
+            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&\r
+                    parentDir != null && \r
+                    (   (mCurrentDir == null && parentDir.getFileName().equals("/")) ||\r
+                            parentDir.equals(mCurrentDir)\r
+                    )\r
+                ) {\r
+                FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
+                if (fileListFragment != null) { \r
+                    fileListFragment.listDirectory();\r
+                }\r
+            }\r
+        }\r
+        \r
+    }\r
+    \r
+    \r
+    /**\r
+     * Once the file download has finished -> update view\r
+     */\r
+    private class DownloadFinishReceiver extends BroadcastReceiver {\r
+        @Override\r
+        public void onReceive(Context context, Intent intent) {\r
+            String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);\r
+            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);\r
+\r
+            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&\r
+                     mCurrentDir != null && mCurrentDir.getFileId() == mStorageManager.getFileByPath(downloadedRemotePath).getParentId()) {\r
+                FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
+                if (fileListFragment != null) { \r
+                    fileListFragment.listDirectory();\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    \r
+    @Override\r
+    public void onClick(View v) {\r
+        if (v.getId() == R.id.setup_account) {\r
+            Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);\r
+            intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+            startActivity(intent); \r
+            mForcedLoginToCreateFirstAccount = true;\r
+        }\r
+    }\r
+\r
+    \r
+    \r
+    \r
+    \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public DataStorageManager getStorageManager() {\r
+        return mStorageManager;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onDirectoryClick(OCFile directory) {\r
+        pushDirname(directory);\r
+        ActionBar actionBar = getSupportActionBar();\r
+        actionBar.setDisplayHomeAsUpEnabled(true);\r
+        \r
+        if (mDualPane) {\r
+            // Resets the FileDetailsFragment on Tablets so that it always displays\r
+            FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);\r
+            if (fileDetails != null) {\r
+                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\r
+                transaction.remove(fileDetails);\r
+                transaction.add(R.id.file_details_container, new FileDetailFragment(null, null));\r
+                transaction.commit();\r
+            }\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onFileClick(OCFile file) {\r
+        \r
+        // If we are on a large device -> update fragment\r
+        if (mDualPane) {\r
+            // 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'\r
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\r
+            transaction.replace(R.id.file_details_container, new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG);\r
+            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);\r
+            transaction.commit();\r
+            \r
+        } else {    // small or medium screen device -> new Activity\r
+            Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);\r
+            showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);\r
+            showDetailsIntent.putExtra(FileDownloader.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));\r
+            startActivity(showDetailsIntent);\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onFileStateChanged() {\r
+        FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
+        if (fileListFragment != null) { \r
+            fileListFragment.listDirectory();\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     *  Operations in this method should be preferably performed in onCreate to have a lighter onResume method. \r
+     * \r
+     *  But we need to delay them to onResume for the first start of the application, when no account exists and the login activity must be shown; and \r
+     *  put instead the ugly view that shows the 'Setup' button to restart the login activity.   \r
+     *  \r
+     *  In other way, if the users cancels or presses BACK in the login page that first time (users can be cruel sometimes) would show a blank view (the \r
+     *  FragmentList view empty).\r
+     *  \r
+     *  This is temporal, until we found out how to get a result in this activity after launching the ADD_ACCOUNT Intent with startActivityForResult (not trivial)\r
+     */\r
+    private void initDelayedTilAccountAvailabe() {\r
+        setContentView(mLayoutView);    \r
+        mDualPane = (findViewById(R.id.file_details_container) != null);\r
+        if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {\r
+            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\r
+            transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment\r
+            transaction.commit();\r
+        }\r
+        setSupportProgressBarIndeterminateVisibility(false);\r
+    }\r
+    \r
+\r
+    /**\r
+     * Launch an intent to request the PIN code to the user before letting him use the app\r
+     */\r
+    private void requestPinCode() {\r
+        boolean pinStart = false;\r
+        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());\r
+        pinStart = appPrefs.getBoolean("set_pincode", false);\r
+        if (pinStart) {\r
+            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);\r
+            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");\r
+            startActivity(i);\r
+        }\r
+    }\r
+\r
+    \r
+}\r
diff --git a/src/com/owncloud/android/ui/activity/LandingActivity.java b/src/com/owncloud/android/ui/activity/LandingActivity.java
new file mode 100644 (file)
index 0000000..ce7ff2f
--- /dev/null
@@ -0,0 +1,158 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011 Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.activity;\r
+\r
+import com.actionbarsherlock.app.SherlockFragmentActivity;\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.ui.adapter.LandingScreenAdapter;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.content.DialogInterface;\r
+import android.content.DialogInterface.OnClickListener;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.view.View;\r
+import android.widget.AdapterView;\r
+import android.widget.AdapterView.OnItemClickListener;\r
+import android.widget.GridView;\r
+import android.widget.Toast;\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * This activity is used as a landing page when the user first opens this app.\r
+ * \r
+ * @author Lennart Rosam\r
+ * \r
+ */\r
+public class LandingActivity extends SherlockFragmentActivity implements\r
+        OnClickListener, OnItemClickListener {\r
+\r
+    public static final int DIALOG_SETUP_ACCOUNT = 1;\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        setContentView(R.layout.main);\r
+\r
+        // Fill the grid view of the landing screen with icons\r
+        GridView landingScreenItems = (GridView) findViewById(R.id.homeScreenGrid);\r
+        landingScreenItems.setAdapter(new LandingScreenAdapter(this));\r
+        landingScreenItems.setOnItemClickListener(this);\r
+\r
+        // Check, if there are ownCloud accounts\r
+        if (!accountsAreSetup()) {\r
+            showDialog(DIALOG_SETUP_ACCOUNT);\r
+        } else {\r
+            // Start device tracking service\r
+            Intent locationServiceIntent = new Intent();\r
+            locationServiceIntent\r
+                    .setAction("eu.alefzero.owncloud.location.LocationLauncher");\r
+            sendBroadcast(locationServiceIntent);\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    protected void onRestart() {\r
+        super.onRestart();\r
+        // Check, if there are ownCloud accounts\r
+        if (!accountsAreSetup()) {\r
+            showDialog(DIALOG_SETUP_ACCOUNT);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {\r
+        super.onRestoreInstanceState(savedInstanceState);\r
+        // Check, if there are ownCloud accounts\r
+        if (!accountsAreSetup()) {\r
+            showDialog(DIALOG_SETUP_ACCOUNT);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected Dialog onCreateDialog(int id) {\r
+        Dialog dialog;\r
+        switch (id) {\r
+        case DIALOG_SETUP_ACCOUNT:\r
+            AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
+            builder.setTitle(R.string.main_tit_accsetup);\r
+            builder.setMessage(R.string.main_wrn_accsetup);\r
+            builder.setCancelable(false);\r
+            builder.setPositiveButton(R.string.common_ok, this);\r
+            builder.setNegativeButton(R.string.common_cancel, this);\r
+            dialog = builder.create();\r
+            break;\r
+        default:\r
+            dialog = null;\r
+        }\r
+\r
+        return dialog;\r
+    }\r
+\r
+    public void onClick(DialogInterface dialog, int which) {\r
+        // In any case - we won't need it anymore\r
+        dialog.dismiss();\r
+        switch (which) {\r
+        case DialogInterface.BUTTON_POSITIVE:\r
+            Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+            intent.putExtra("authorities",\r
+                    new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+            startActivity(intent);\r
+            break;\r
+        case DialogInterface.BUTTON_NEGATIVE:\r
+            finish();\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    /**\r
+     * Start an activity based on the selection\r
+     * the user made\r
+     */\r
+    public void onItemClick(AdapterView<?> parent, View view, int position,\r
+            long id) {\r
+        Intent intent;\r
+        intent = (Intent) parent.getAdapter().getItem(position);\r
+        if (intent != null) {\r
+            startActivity(intent);\r
+        } else {\r
+            // TODO: Implement all of this and make this text go away ;-)\r
+            Toast toast = Toast.makeText(this, "Not yet implemented!",\r
+                    Toast.LENGTH_SHORT);\r
+            toast.show();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Checks, whether or not there are any ownCloud accounts setup.\r
+     * \r
+     * @return true, if there is at least one account.\r
+     */\r
+    private boolean accountsAreSetup() {\r
+        AccountManager accMan = AccountManager.get(this);\r
+        Account[] accounts = accMan\r
+                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
+        return accounts.length > 0;\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/activity/PinCodeActivity.java b/src/com/owncloud/android/ui/activity/PinCodeActivity.java
new file mode 100644 (file)
index 0000000..fc3926d
--- /dev/null
@@ -0,0 +1,652 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2011 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 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.Arrays;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+import com.owncloud.android.R;
+
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Typeface;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceManager;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.text.method.PasswordTransformationMethod;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.View.OnKeyListener;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+
+public class PinCodeActivity extends SherlockFragmentActivity {
+
+  
+    public final static String EXTRA_ACTIVITY = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.ACTIVITY";
+    public final static String EXTRA_NEW_STATE = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.NEW_STATE";
+    
+    Button bCancel;
+    TextView mPinHdr;
+    EditText mText1;
+    EditText mText2;
+    EditText mText3;
+    EditText mText4;
+    
+    String [] tempText ={"","","",""};
+    
+    String activity;
+    
+    boolean confirmingPinCode = false;
+    boolean pinCodeChecked = false;
+    boolean newPasswordEntered = false;
+    boolean bChange = true; // to control that only one blocks jump
+    int tCounter ; // Count the number of attempts an user could introduce the PIN code
+
+    
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pincodelock); 
+        
+        Intent intent = getIntent();
+        activity = intent.getStringExtra(EXTRA_ACTIVITY);
+     
+        bCancel = (Button) findViewById(R.id.cancel);
+        mPinHdr = (TextView) findViewById(R.id.pinHdr);
+        mText1 = (EditText) findViewById(R.id.txt1);
+        mText1.requestFocus();
+        getWindow().setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+        mText2 = (EditText) findViewById(R.id.txt2);
+        mText3 = (EditText) findViewById(R.id.txt3);
+        mText4 = (EditText) findViewById(R.id.txt4);
+        
+        
+        
+        SharedPreferences appPrefs = PreferenceManager
+                .getDefaultSharedPreferences(getApplicationContext());
+        
+        // Not PIN Code defined yet.
+        // In a previous version settings is allow from start
+        if ( (appPrefs.getString("PrefPinCode1", null) == null ) ){
+            setChangePincodeView(true);
+            pinCodeChecked = true; 
+            newPasswordEntered = true;
+            
+        }else{ 
+            
+            if (appPrefs.getBoolean("set_pincode", false)){
+               // pincode activated
+               if (activity.equals("preferences")){
+                // PIN has been activated yet
+                 mPinHdr.setText(R.string.pincode_configure_your_pin);
+                 pinCodeChecked = true ; // No need to check it 
+                 setChangePincodeView(true);
+               }else{
+                // PIN active
+                 bCancel.setVisibility(View.INVISIBLE);
+                 bCancel.setVisibility(View.GONE);
+                 mPinHdr.setText(R.string.pincode_enter_pin_code);
+                 setChangePincodeView(false);
+              }
+            
+           }else {
+            // pincode removal
+              mPinHdr.setText(R.string.pincode_remove_your_pincode);
+              pinCodeChecked = false;
+              setChangePincodeView(true); 
+           }
+           
+        }
+        setTextListeners();
+        
+        
+    }
+    
+
+     
+    protected void setInitVars(){
+        confirmingPinCode = false;
+        pinCodeChecked = false;
+        newPasswordEntered = false;
+
+    }
+    
+    protected void setInitView(){
+        bCancel.setVisibility(View.INVISIBLE);
+        bCancel.setVisibility(View.GONE);
+        mPinHdr.setText(R.string.pincode_enter_pin_code);
+    }
+    
+   
+    protected void setChangePincodeView(boolean state){
+       
+        if(state){
+        bCancel.setVisibility(View.VISIBLE);
+        bCancel.setOnClickListener(new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            
+            SharedPreferences.Editor appPrefsE = PreferenceManager
+                    .getDefaultSharedPreferences(getApplicationContext()).edit();
+            
+            SharedPreferences appPrefs = PreferenceManager
+                    .getDefaultSharedPreferences(getApplicationContext());
+            
+            boolean state = appPrefs.getBoolean("set_pincode", false);
+            appPrefsE.putBoolean("set_pincode",!state); 
+            appPrefsE.commit();
+            setInitVars();
+            finish();
+            }
+        });
+        }  
+    
+    }
+    
+    
+    
+    /*
+     *  
+     */
+    protected void setTextListeners(){
+    
+        /*------------------------------------------------
+         *  FIRST BOX
+         -------------------------------------------------*/
+        
+        mText1.addTextChangedListener(new TextWatcher() {
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before,
+                    int count) {
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count,
+                    int after) {
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                if (s.length() > 0) {
+                    if (!confirmingPinCode){
+                       tempText[0] = mText1.getText().toString();
+                       
+                    }
+                    mText2.requestFocus();
+                 }
+            }
+        });
+        
+        
+
+        /*------------------------------------------------
+         *  SECOND BOX 
+         -------------------------------------------------*/
+        mText2.addTextChangedListener(new TextWatcher() {
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before,
+                    int count) {
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count,
+                    int after) {
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                if (s.length() > 0) {
+                    if (!confirmingPinCode){
+                        tempText[1] = mText2.getText().toString();
+                    }
+                    
+                    mText3.requestFocus();
+                }
+            }
+        });
+        mText2.setOnKeyListener(new OnKeyListener() {
+
+            @Override
+            public boolean onKey(View v, int keyCode, KeyEvent event) {
+                // TODO Auto-generated method stub
+
+                if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
+
+                    mText1.setText("");
+                    mText1.requestFocus();
+                    if (!confirmingPinCode)
+                       tempText[0] = "";
+                    bChange= false;
+                
+                }else if(!bChange){
+                    bChange=true;
+                    
+                }
+                return false;
+            }
+        });        
+        mText2.setOnFocusChangeListener(new OnFocusChangeListener() {
+               
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                // TODO Auto-generated method stub
+                
+                mText2.setCursorVisible(true);
+                if (mText1.getText().toString().equals("")){
+                    mText2.setSelected(false);
+                    mText2.setCursorVisible(false);
+                    mText1.requestFocus(); 
+                    mText1.setSelected(true);
+                    mText1.setSelection(0);
+                }
+                
+            }
+        });
+        
+        
+        /*------------------------------------------------
+         *  THIRD BOX
+         -------------------------------------------------*/
+        mText3.addTextChangedListener(new TextWatcher() {
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before,
+                    int count) {
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count,
+                    int after) {
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                if (s.length() > 0) {
+                    if (!confirmingPinCode){
+                        tempText[2] = mText3.getText().toString();
+                    }
+                    mText4.requestFocus();
+                }
+            }
+        });
+        
+        mText3.setOnKeyListener(new OnKeyListener() {
+
+            @Override
+            public boolean onKey(View v, int keyCode, KeyEvent event) {
+                // TODO Auto-generated method stub
+
+                if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
+                    mText2.requestFocus();
+                    if (!confirmingPinCode)
+                        tempText[1] = "";
+                    mText2.setText("");
+                    bChange= false;
+                    
+                }else if(!bChange){
+                    bChange=true;                        
+                    
+                }
+                return false;
+            }
+        });
+        
+        mText3.setOnFocusChangeListener(new OnFocusChangeListener() {
+            
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                // TODO Auto-generated method stub
+                mText3.setCursorVisible(true);
+                if (mText1.getText().toString().equals("")){
+                    mText3.setSelected(false);
+                    mText3.setCursorVisible(false);
+                    mText1.requestFocus();
+                    mText1.setSelected(true);
+                    mText1.setSelection(0);
+                }else if (mText2.getText().toString().equals("")){
+                    mText3.setSelected(false);
+                    mText3.setCursorVisible(false);
+                    mText2.requestFocus();
+                    mText2.setSelected(true);
+                    mText2.setSelection(0);
+                }
+                
+            }
+        });
+        
+        /*------------------------------------------------
+         *  FOURTH BOX
+         -------------------------------------------------*/
+        mText4.addTextChangedListener(new TextWatcher() {
+
+            @Override
+            public void onTextChanged(CharSequence s, int start, int before,
+                    int count) {
+            }
+
+            @Override
+            public void beforeTextChanged(CharSequence s, int start, int count,
+                    int after) {
+            }
+
+            @Override
+            public void afterTextChanged(Editable s) {
+                if (s.length() > 0) {
+                    
+                    if (!confirmingPinCode){
+                       tempText[3] = mText4.getText().toString();
+                    }
+                    mText1.requestFocus();
+
+                    if (!pinCodeChecked){
+                        pinCodeChecked = checkPincode();
+                    }
+                    
+                    if (pinCodeChecked && activity.equals("FileDisplayActivity")){
+                        finish();
+                    } else if (pinCodeChecked){
+                        
+                        Intent intent = getIntent();
+                        String newState = intent.getStringExtra(EXTRA_NEW_STATE);
+                        
+                        if (newState.equals("false")){
+                            SharedPreferences.Editor appPrefs = PreferenceManager
+                                    .getDefaultSharedPreferences(getApplicationContext()).edit();
+                            appPrefs.putBoolean("set_pincode",false);
+                            appPrefs.commit();
+                            
+                            setInitVars();
+                            pinCodeEnd(false);
+                            
+                        }else{
+                        
+                            if (!confirmingPinCode){
+                                pinCodeChangeRequest();
+                             
+                            } else {
+                                confirmPincode();
+                            }
+                        }
+                   
+                        
+                    }    
+                }
+            }
+        });
+
+        
+        
+        mText4.setOnKeyListener(new OnKeyListener() {
+
+            @Override
+            public boolean onKey(View v, int keyCode, KeyEvent event) {
+                // TODO Auto-generated method stub
+
+                if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
+                    mText3.requestFocus();
+                    if (!confirmingPinCode)
+                        tempText[2]="";
+                    mText3.setText("");
+                    bChange= false;
+                    
+                }else if(!bChange){
+                    bChange=true;    
+                }
+                return false;
+            }
+        });
+        
+       mText4.setOnFocusChangeListener(new OnFocusChangeListener() {
+            
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                // TODO Auto-generated method stub
+                
+                mText4.setCursorVisible(true);
+                
+                if (mText1.getText().toString().equals("")){
+                    mText4.setSelected(false);
+                    mText4.setCursorVisible(false);
+                    mText1.requestFocus();
+                    mText1.setSelected(true);
+                    mText1.setSelection(0);
+                }else if (mText2.getText().toString().equals("")){
+                    mText4.setSelected(false);
+                    mText4.setCursorVisible(false);
+                    mText2.requestFocus();
+                    mText2.setSelected(true);
+                    mText2.setSelection(0);
+                }else if (mText3.getText().toString().equals("")){
+                    mText4.setSelected(false);
+                    mText4.setCursorVisible(false);
+                    mText3.requestFocus();
+                    mText3.setSelected(true);
+                    mText3.setSelection(0);
+                }
+                
+            }
+        });
+        
+        
+        
+    } // end setTextListener
+    
+    
+    protected void pinCodeChangeRequest(){
+    
+        clearBoxes(); 
+        mPinHdr.setText(R.string.pincode_reenter_your_pincode); 
+        confirmingPinCode =true;
+        
+    }
+    
+    
+    protected boolean checkPincode(){
+        
+        
+        SharedPreferences appPrefs = PreferenceManager
+                .getDefaultSharedPreferences(getApplicationContext());
+        
+       String pText1 = appPrefs.getString("PrefPinCode1", null);
+        String pText2 = appPrefs.getString("PrefPinCode2", null);
+        String pText3 = appPrefs.getString("PrefPinCode3", null);
+        String pText4 = appPrefs.getString("PrefPinCode4", null);
+
+        if ( tempText[0].equals(pText1) && 
+             tempText[1].equals(pText2) &&
+             tempText[2].equals(pText3) &&
+             tempText[3].equals(pText4) ) {
+            
+            return true;
+        
+        
+        }else {
+            Arrays.fill(tempText, null);
+            AlertDialog aDialog = new AlertDialog.Builder(this).create();
+            CharSequence errorSeq = getString(R.string.common_error);
+            aDialog.setTitle(errorSeq);
+            CharSequence cseq = getString(R.string.pincode_wrong);
+            aDialog.setMessage(cseq);
+            CharSequence okSeq = getString(R.string.common_ok);
+            aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
+
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    // TODO Auto-generated method stub("");
+                   return; 
+                }
+                
+            });
+            aDialog.show();
+            clearBoxes(); 
+            mPinHdr.setText(R.string.pincode_enter_pin_code);
+            newPasswordEntered = true;
+            confirmingPinCode = false;
+            
+        }
+     
+        
+        return false;
+    }
+    
+    protected void confirmPincode(){
+        
+        confirmingPinCode = false;
+        
+        String rText1 = mText1.getText().toString();
+        String rText2 = mText2.getText().toString();
+        String rText3 = mText3.getText().toString();
+        String rText4 = mText4.getText().toString();
+        
+        if ( tempText[0].equals(rText1) && 
+             tempText[1].equals(rText2) &&
+             tempText[2].equals(rText3) &&
+             tempText[3].equals(rText4) ) {
+                        
+            savePincodeAndExit();
+            
+        } else {
+            
+            Arrays.fill(tempText, null);
+            AlertDialog aDialog = new AlertDialog.Builder(this).create();
+            CharSequence errorSeq = getString(R.string.common_error);
+            aDialog.setTitle(errorSeq);
+            CharSequence cseq = getString(R.string.pincode_mismatch);
+            aDialog.setMessage(cseq);
+            CharSequence okSeq = getString(R.string.common_ok);
+            aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
+
+                @Override
+                public void onClick(DialogInterface dialog, int which) {
+                    // TODO Auto-generated method stub("");
+                   return; 
+                }
+                
+            });
+            aDialog.show();
+            mPinHdr.setText(R.string.pincode_configure_your_pin);
+            clearBoxes();
+        }
+    
+    }
+   
+    
+    protected void pinCodeEnd(boolean state){
+        AlertDialog aDialog = new AlertDialog.Builder(this).create();
+        
+        if (state){
+            CharSequence saveSeq = getString(R.string.common_save_exit);
+            aDialog.setTitle(saveSeq);
+            CharSequence cseq = getString(R.string.pincode_stored);
+            aDialog.setMessage(cseq);
+            
+        }else{
+            CharSequence saveSeq = getString(R.string.common_save_exit);
+            aDialog.setTitle(saveSeq);
+            CharSequence cseq = getString(R.string.pincode_removed);
+            aDialog.setMessage(cseq);
+            
+        }
+        CharSequence okSeq = getString(R.string.common_ok);
+        aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
+
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+                // TODO Auto-generated method stub("");
+                finish();
+                return; 
+            }
+            
+        });
+        aDialog.show(); 
+    }
+    
+    protected void savePincodeAndExit(){
+        SharedPreferences.Editor appPrefs = PreferenceManager
+                .getDefaultSharedPreferences(getApplicationContext()).edit();
+        
+        appPrefs.putString("PrefPinCode1", tempText[0]);
+        appPrefs.putString("PrefPinCode2",tempText[1]);
+        appPrefs.putString("PrefPinCode3", tempText[2]);
+        appPrefs.putString("PrefPinCode4", tempText[3]);
+        appPrefs.putBoolean("set_pincode",true);
+        appPrefs.commit();
+        
+        pinCodeEnd(true);
+        
+        
+        
+    }
+    
+    
+    protected void clearBoxes(){
+        
+        mText1.setText("");
+        mText2.setText("");
+        mText3.setText("");
+        mText4.setText("");
+        mText1.requestFocus(); 
+    }
+    
+    
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event){
+        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
+            
+            if (activity.equals("preferences")){
+                SharedPreferences.Editor appPrefsE = PreferenceManager
+            
+                    .getDefaultSharedPreferences(getApplicationContext()).edit();
+            
+                SharedPreferences appPrefs = PreferenceManager
+                    .getDefaultSharedPreferences(getApplicationContext());
+            
+                boolean state = appPrefs.getBoolean("set_pincode", false);
+                appPrefsE.putBoolean("set_pincode",!state); 
+                appPrefsE.commit();
+                setInitVars();
+                finish();
+            }
+            return true; 
+            
+        }
+        
+        return super.onKeyDown(keyCode, event);
+    }
+    
+   
+
+    
+            
+}
diff --git a/src/com/owncloud/android/ui/activity/Preferences.java b/src/com/owncloud/android/ui/activity/Preferences.java
new file mode 100644 (file)
index 0000000..7b23856
--- /dev/null
@@ -0,0 +1,240 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.activity;\r
+\r
+import java.util.Vector;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.content.Intent;\r
+import android.content.SharedPreferences;\r
+import android.os.Bundle;\r
+import android.preference.CheckBoxPreference;\r
+import android.preference.ListPreference;\r
+import android.preference.Preference;\r
+import android.preference.PreferenceManager;\r
+import android.preference.Preference.OnPreferenceChangeListener;\r
+import android.preference.Preference.OnPreferenceClickListener;\r
+import android.util.Log;\r
+\r
+import com.actionbarsherlock.app.ActionBar;\r
+import com.actionbarsherlock.app.SherlockPreferenceActivity;\r
+import com.actionbarsherlock.view.Menu;\r
+import com.actionbarsherlock.view.MenuItem;\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.OwnCloudSession;\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.db.DbHandler;\r
+\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * An Activity that allows the user to change the application's settings.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class Preferences extends SherlockPreferenceActivity implements\r
+        OnPreferenceChangeListener{\r
+    private static final String TAG = "OwnCloudPreferences";\r
+    private final int mNewSession = 47;\r
+    private final int mEditSession = 48;\r
+    private DbHandler mDbHandler;\r
+    private Vector<OwnCloudSession> mSessions;\r
+    //private Account[] mAccounts;\r
+    //private ListPreference mAccountList;\r
+    private ListPreference mTrackingUpdateInterval;\r
+    private CheckBoxPreference mDeviceTracking;\r
+    private CheckBoxPreference pCode;\r
+    private int mSelectedMenuItem;\r
+\r
+    @Override\r
+    public void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        mDbHandler = new DbHandler(getBaseContext());\r
+        mSessions = new Vector<OwnCloudSession>();\r
+        addPreferencesFromResource(R.xml.preferences);\r
+        //populateAccountList();\r
+        ActionBar actionBar = getSherlock().getActionBar();\r
+        actionBar.setDisplayHomeAsUpEnabled(true);\r
+        Preference p = findPreference("manage_account");\r
+        if (p != null)\r
+        p.setOnPreferenceClickListener(new OnPreferenceClickListener() {\r
+            @Override\r
+            public boolean onPreferenceClick(Preference preference) {\r
+                Intent i = new Intent(getApplicationContext(), AccountSelectActivity.class);\r
+                startActivity(i);\r
+                return true;\r
+            }\r
+        });\r
+        \r
+        pCode = (CheckBoxPreference) findPreference("set_pincode");\r
+         \r
+        \r
+        if (pCode != null){\r
+            \r
+            pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {\r
+                @Override\r
+                public boolean onPreferenceChange(Preference preference, Object newValue) {\r
+                                          \r
+                    Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);\r
+                    i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "preferences");\r
+                    i.putExtra(PinCodeActivity.EXTRA_NEW_STATE, newValue.toString());\r
+                    \r
+                    startActivity(i);\r
+                    \r
+                    return true;\r
+                }\r
+            });            \r
+            \r
+        }\r
+        \r
+    }\r
+\r
+\r
+    @Override\r
+    protected void onResume() {\r
+        // TODO Auto-generated method stub\r
+        SharedPreferences appPrefs = PreferenceManager\r
+                .getDefaultSharedPreferences(getApplicationContext());\r
+        \r
+        boolean state = appPrefs.getBoolean("set_pincode", false);\r
+        pCode.setChecked(state);\r
+        \r
+        super.onResume();\r
+    }\r
+\r
+\r
+\r
+    /**\r
+     * Populates the account selector\r
+     *-/\r
+    private void populateAccountList() {\r
+        AccountManager accMan = AccountManager.get(this);\r
+        mAccounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
+        mAccountList = (ListPreference) findPreference("select_oc_account");\r
+        mAccountList.setOnPreferenceChangeListener(this);\r
+\r
+        // Display the name of the current account if there is any\r
+        Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);\r
+        if (defaultAccount != null) {\r
+            mAccountList.setSummary(defaultAccount.name);\r
+        }\r
+        \r
+        // Transform accounts into array of string for preferences to use\r
+        String[] accNames = new String[mAccounts.length];\r
+        for (int i = 0; i < mAccounts.length; i++) {\r
+            Account account = mAccounts[i];\r
+            accNames[i] = account.name;\r
+        }\r
+\r
+        mAccountList.setEntries(accNames);\r
+        mAccountList.setEntryValues(accNames);\r
+    }*/\r
+\r
+    \r
+    \r
+    @Override\r
+    public boolean onCreateOptionsMenu(Menu menu) {\r
+        super.onCreateOptionsMenu(menu);\r
+        //MenuInflater inflater = getSherlock().getMenuInflater();\r
+        //inflater.inflate(R.menu.prefs_menu, menu);\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public boolean onMenuItemSelected(int featureId, MenuItem item) {\r
+        super.onMenuItemSelected(featureId, item);\r
+        Intent intent;\r
+\r
+        switch (item.getItemId()) {\r
+        //case R.id.addSessionItem:\r
+        case 1:\r
+            intent = new Intent(this, PreferencesNewSession.class);\r
+            startActivityForResult(intent, mNewSession);\r
+            break;\r
+        case R.id.SessionContextEdit:\r
+            intent = new Intent(this, PreferencesNewSession.class);\r
+            intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem)\r
+                    .getEntryId());\r
+            intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem)\r
+                    .getName());\r
+            intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem)\r
+                    .getUrl());\r
+            startActivityForResult(intent, mEditSession);\r
+            break;\r
+        case android.R.id.home:\r
+            intent = new Intent(getBaseContext(), FileDisplayActivity.class);\r
+            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);\r
+            startActivity(intent);\r
+            break;\r
+        default:\r
+            Log.w(TAG, "Unknown menu item triggered");\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        super.onActivityResult(requestCode, resultCode, data);\r
+    }\r
+\r
+    @Override\r
+    protected void onDestroy() {\r
+        mDbHandler.close();\r
+        super.onDestroy();\r
+    }\r
+\r
+    \r
+    \r
+    @Override\r
+    /**\r
+     * Updates various summaries after updates. Also starts and stops \r
+     * the\r
+     */\r
+    public boolean onPreferenceChange(Preference preference, Object newValue) {\r
+        // Update current account summary\r
+        /*if (preference.equals(mAccountList)) {\r
+            mAccountList.setSummary(newValue.toString());\r
+        }\r
+\r
+        // Update tracking interval summary\r
+        else*/ if (preference.equals(mTrackingUpdateInterval)) {\r
+            String trackingSummary = getResources().getString(\r
+                    R.string.prefs_trackmydevice_interval_summary);\r
+            trackingSummary = String.format(trackingSummary,\r
+                    newValue.toString());\r
+            mTrackingUpdateInterval.setSummary(trackingSummary);\r
+        }\r
+\r
+        // Start or stop tracking service\r
+        else if (preference.equals(mDeviceTracking)) {\r
+            Intent locationServiceIntent = new Intent();\r
+            locationServiceIntent\r
+                    .setAction("eu.alefzero.owncloud.location.LocationLauncher");\r
+            locationServiceIntent.putExtra("TRACKING_SETTING",\r
+                    (Boolean) newValue);\r
+            sendBroadcast(locationServiceIntent);\r
+        } \r
+        return true;\r
+    }\r
+    \r
+    \r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/activity/PreferencesNewSession.java b/src/com/owncloud/android/ui/activity/PreferencesNewSession.java
new file mode 100644 (file)
index 0000000..3e9eb26
--- /dev/null
@@ -0,0 +1,98 @@
+package com.owncloud.android.ui.activity;\r
+\r
+import android.accounts.AccountAuthenticatorActivity;\r
+import android.app.Activity;\r
+import android.os.Bundle;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+\r
+public class PreferencesNewSession extends AccountAuthenticatorActivity\r
+        implements OnClickListener {\r
+    @Override\r
+    public void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        // setContentView(R.layout.add_new_session);\r
+        /*\r
+         * EditText et;// = (EditText)\r
+         * findViewById(R.id.newSession_sessionName);\r
+         * \r
+         * et = (EditText) findViewById(R.id.newSession_URL); if\r
+         * (getIntent().hasExtra("sessionURL")) { try { URI uri = new\r
+         * URI(getIntent().getStringExtra("sessionURL")); String url =\r
+         * uri.getHost(); if (uri.getPort() != -1) { url += ":" +\r
+         * String.valueOf(uri.getPort()); } if (uri.getPath() != null) { url +=\r
+         * uri.getPath(); } else { url += "/"; } et.setText(url); et =\r
+         * (EditText) findViewById(R.id.newSession_username); if\r
+         * (uri.getAuthority() != null) { if (uri.getUserInfo().indexOf(':') !=\r
+         * -1) { et.setText(uri.getUserInfo().substring(0,\r
+         * uri.getUserInfo().indexOf(':'))); et = (EditText)\r
+         * findViewById(R.id.newSession_password);\r
+         * et.setText(uri.getUserInfo().substring\r
+         * (uri.getUserInfo().indexOf(':')+1)); } else {\r
+         * et.setText(uri.getUserInfo()); } }\r
+         * \r
+         * } catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +\r
+         * e.getLocalizedMessage()); } }\r
+         * \r
+         * mReturnData = new Intent(); setResult(Activity.RESULT_OK,\r
+         * mReturnData); ((Button)\r
+         * findViewById(R.id.button1)).setOnClickListener(this); ((Button)\r
+         * findViewById(R.id.button2)).setOnClickListener(this);\r
+         */\r
+    }\r
+\r
+    @Override\r
+    protected void onResume() {\r
+        super.onResume();\r
+    }\r
+\r
+    public void onClick(View v) {\r
+        /*\r
+         * switch (v.getId()) { case R.id.button1: Intent intent = new Intent();\r
+         * if (getIntent().hasExtra("sessionId")) { intent.putExtra("sessionId",\r
+         * getIntent().getIntExtra("sessionId", -1)); } //String sessionName =\r
+         * ((EditText)\r
+         * findViewById(R.id.newSession_sessionName)).getText().toString(); //\r
+         * if (sessionName.trim().equals("") || !isNameValid(sessionName)) { //\r
+         * Toast.makeText(this, R.string.new_session_session_name_error,\r
+         * Toast.LENGTH_LONG).show(); // break; // } URI uri = prepareURI(); if\r
+         * (uri != null) { //intent.putExtra("sessionName", sessionName);\r
+         * intent.putExtra("sessionURL", uri.toString());\r
+         * setResult(Activity.RESULT_OK, intent); AccountManager accMgr =\r
+         * AccountManager.get(this); Account a = new Account("OwnCloud",\r
+         * AccountAuthenticatorService.ACCOUNT_TYPE);\r
+         * accMgr.addAccountExplicitly(a, "asd", null); finish(); } break; case\r
+         * R.id.button2: setResult(Activity.RESULT_CANCELED); finish(); break; }\r
+         */\r
+    }\r
+\r
+    /*\r
+     * private URI prepareURI() { URI uri = null; String url = ""; try { String\r
+     * username = ((EditText)\r
+     * findViewById(R.id.newSession_username)).getText().toString().trim();\r
+     * String password = ((EditText)\r
+     * findViewById(R.id.newSession_password)).getText().toString().trim();\r
+     * String hostname = ((EditText)\r
+     * findViewById(R.id.newSession_URL)).getText().toString().trim(); String\r
+     * scheme; if (hostname.matches("[A-Za-z]://")) { scheme =\r
+     * hostname.substring(0, hostname.indexOf("://")+3); hostname =\r
+     * hostname.substring(hostname.indexOf("://")+3); } else { scheme =\r
+     * "http://"; } if (!username.equals("")) { if (!password.equals("")) {\r
+     * username += ":" + password + "@"; } else { username += "@"; } } url =\r
+     * scheme + username + hostname; Log.i(TAG, url); uri = new URI(url); }\r
+     * catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +\r
+     * e.getLocalizedMessage()); Toast.makeText(this,\r
+     * R.string.new_session_uri_error, Toast.LENGTH_LONG).show(); } return uri;\r
+     * }\r
+     * \r
+     * private boolean isNameValid(String string) { return\r
+     * string.matches("[A-Za-z0-9 _-]*"); }\r
+     */\r
+\r
+    @Override\r
+    public void onBackPressed() {\r
+        setResult(Activity.RESULT_CANCELED);\r
+        super.onBackPressed();\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/adapter/FileListActionListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListActionListAdapter.java
new file mode 100644 (file)
index 0000000..872b813
--- /dev/null
@@ -0,0 +1,173 @@
+/* ownCloud Android client application
+ *   Copyright (C) 2011  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 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.adapter;
+
+import java.io.File;
+
+import com.owncloud.android.authenticator.AccountAuthenticator;
+import com.owncloud.android.db.ProviderMeta.ProviderTableMeta;
+
+import com.owncloud.android.R;
+import eu.alefzero.webdav.WebdavUtils;
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+public class FileListActionListAdapter implements ListAdapter {
+
+    private Context mContext;
+    private Account mAccount;
+    private String mFilename, mFileType, mFilePath, mFileStoragePath;
+
+    private final int ITEM_DOWNLOAD = 0;
+
+    // private final int ITEM_SHARE = 1;
+
+    public FileListActionListAdapter(Cursor c, Context co, Account account) {
+        mContext = co;
+        mFilename = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_NAME));
+        mFileType = c.getString(c
+                .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
+        mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
+        mFileStoragePath = c.getString(c
+                .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
+        // mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
+        mAccount = account;
+    }
+
+    public boolean areAllItemsEnabled() {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    public boolean isEnabled(int position) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    public int getCount() {
+        // TODO Auto-generated method stub
+        return 1;
+    }
+
+    public Object getItem(int position) {
+        if (position == 0) {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            if (TextUtils.isEmpty(mFileStoragePath)) {
+                intent.putExtra("toDownload", true);
+                AccountManager accm = (AccountManager) mContext
+                        .getSystemService(Context.ACCOUNT_SERVICE);
+                String ocurl = accm.getUserData(mAccount,
+                        AccountAuthenticator.KEY_OC_URL);
+                ocurl += WebdavUtils.encodePath(mFilePath + mFilename);
+                intent.setData(Uri.parse(ocurl));
+            } else {
+                intent.putExtra("toDownload", false);
+                intent.setDataAndType(Uri.fromFile(new File(mFileStoragePath)),
+                        mFileType);
+            }
+            return intent;
+        }
+        return null;
+    }
+
+    public long getItemId(int position) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public int getItemViewType(int position) {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View v = convertView;
+        if (v == null) {
+            LayoutInflater vi = (LayoutInflater) mContext
+                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            v = vi.inflate(R.layout.file_display_action_list_element, null);
+        }
+
+        TextView tv;
+        ImageView iv;
+        switch (position) {
+        case ITEM_DOWNLOAD:
+            tv = (TextView) v.findViewById(R.id.textView1);
+            if (mFileStoragePath == null) {
+                tv.setText("Download");
+            } else {
+                setActionName(tv);
+            }
+            iv = (ImageView) v.findViewById(R.id.imageView1);
+            iv.setImageResource(R.drawable.download);
+            break;
+        }
+
+        return v;
+    }
+
+    public int getViewTypeCount() {
+        // TODO Auto-generated method stub
+        return 2;
+    }
+
+    public boolean hasStableIds() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public boolean isEmpty() {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    public void registerDataSetObserver(DataSetObserver observer) {
+        // TODO Auto-generated method stub
+
+    }
+
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        // TODO Auto-generated method stub
+
+    }
+
+    private void setActionName(TextView tv) {
+        if (mFileType.matches("image/.*")) {
+            tv.setText("View");
+        } else if (mFileType.matches("audio/.*")
+                || mFileType.matches("video/.*")) {
+            tv.setText("Play");
+        } else {
+            tv.setText("Open");
+        }
+    }
+
+}
diff --git a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java
new file mode 100644 (file)
index 0000000..ade2e5e
--- /dev/null
@@ -0,0 +1,202 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.adapter;\r
+\r
+import java.util.Vector;\r
+\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.DisplayUtils;\r
+import com.owncloud.android.datamodel.DataStorageManager;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.files.services.FileDownloader;\r
+import com.owncloud.android.files.services.FileUploader;\r
+\r
+import com.owncloud.android.R;\r
+\r
+import android.accounts.Account;\r
+import android.content.Context;\r
+import android.database.DataSetObserver;\r
+import android.util.Log;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.ImageView;\r
+import android.widget.ListAdapter;\r
+import android.widget.TextView;\r
+\r
+/**\r
+ * This Adapter populates a ListView with all files and folders in an ownCloud\r
+ * instance.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class FileListListAdapter implements ListAdapter {\r
+    private Context mContext;\r
+    private OCFile mFile;\r
+    private Vector<OCFile> mFiles;\r
+    private DataStorageManager mStorageManager;\r
+    private Account mAccount;\r
+\r
+    public FileListListAdapter(OCFile file, DataStorageManager storage_man,\r
+            Context context) {\r
+        mFile = file;\r
+        mStorageManager = storage_man;\r
+        mFiles = mStorageManager.getDirectoryContent(mFile);\r
+        mContext = context;\r
+        mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
+    }\r
+\r
+    @Override\r
+    public boolean areAllItemsEnabled() {\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public boolean isEnabled(int position) {\r
+        // TODO Auto-generated method stub\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public int getCount() {\r
+        return mFiles != null ? mFiles.size() : 0;\r
+    }\r
+\r
+    @Override\r
+    public Object getItem(int position) {\r
+        if (mFiles.size() <= position)\r
+            return null;\r
+        return mFiles.get(position);\r
+    }\r
+\r
+    @Override\r
+    public long getItemId(int position) {\r
+        return mFiles != null ? mFiles.get(position).getFileId() : 0;\r
+    }\r
+\r
+    @Override\r
+    public int getItemViewType(int position) {\r
+        // TODO Auto-generated method stub\r
+        return 0;\r
+    }\r
+\r
+    @Override\r
+    public View getView(int position, View convertView, ViewGroup parent) {\r
+        View view = convertView;\r
+        if (view == null) {\r
+            LayoutInflater inflator = (LayoutInflater) mContext\r
+                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+            view = inflator.inflate(R.layout.list_layout, null);\r
+        }\r
+        if (mFiles.size() > position) {\r
+            OCFile file = mFiles.get(position);\r
+            TextView fileName = (TextView) view.findViewById(R.id.Filename);\r
+            String name = file.getFileName();\r
+\r
+            fileName.setText(name);\r
+            ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
+            if (file.getMimetype() == null || !file.getMimetype().equals("DIR")) {\r
+                fileIcon.setImageResource(R.drawable.file);\r
+            } else {\r
+                fileIcon.setImageResource(R.drawable.ic_menu_archive);\r
+            }\r
+            ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);\r
+            if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {\r
+                localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
+                localStateView.setVisibility(View.VISIBLE);\r
+            } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {\r
+                localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
+                localStateView.setVisibility(View.VISIBLE);\r
+            } else if (file.isDown()) {\r
+                localStateView.setImageResource(R.drawable.local_file_indicator);\r
+                localStateView.setVisibility(View.VISIBLE);\r
+            } else {\r
+                localStateView.setVisibility(View.INVISIBLE);\r
+            }\r
+                /*\r
+            ImageView down = (ImageView) view.findViewById(R.id.imageView2);\r
+            ImageView downloading = (ImageView) view.findViewById(R.id.imageView4);\r
+            ImageView uploading = (ImageView) view.findViewById(R.id.imageView5);\r
+            if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {\r
+                down.setVisibility(View.INVISIBLE);\r
+                downloading.setVisibility(View.VISIBLE);\r
+                uploading.setVisibility(View.INVISIBLE);\r
+            } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {\r
+                down.setVisibility(View.INVISIBLE);\r
+                downloading.setVisibility(View.INVISIBLE);\r
+                uploading.setVisibility(View.VISIBLE);\r
+            } else if (file.isDown()) {\r
+                 down.setVisibility(View.VISIBLE);\r
+                 downloading.setVisibility(View.INVISIBLE);\r
+                 uploading.setVisibility(View.INVISIBLE);\r
+            } else {\r
+                down.setVisibility(View.INVISIBLE);\r
+                downloading.setVisibility(View.INVISIBLE);\r
+                uploading.setVisibility(View.INVISIBLE);\r
+            }*/\r
+                \r
+            if (!file.isDirectory()) {\r
+                view.findViewById(R.id.file_size).setVisibility(View.VISIBLE);\r
+                view.findViewById(R.id.last_mod).setVisibility(View.VISIBLE);\r
+                ((TextView)view.findViewById(R.id.file_size)).setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
+                ((TextView)view.findViewById(R.id.last_mod)).setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
+                // this if-else is needed even thoe fav icon is visible by default\r
+                // because android reuses views in listview\r
+                if (!file.keepInSync()) {\r
+                    view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
+                } else {\r
+                    view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);\r
+                }\r
+            } else {\r
+               view.findViewById(R.id.file_size).setVisibility(View.GONE);\r
+               view.findViewById(R.id.last_mod).setVisibility(View.GONE);\r
+               view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
+            }\r
+        }\r
+\r
+        return view;\r
+    }\r
+\r
+    @Override\r
+    public int getViewTypeCount() {\r
+        return 4;\r
+    }\r
+\r
+    @Override\r
+    public boolean hasStableIds() {\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public boolean isEmpty() {\r
+        return mFiles != null ? mFiles.isEmpty() : false;\r
+    }\r
+\r
+    @Override\r
+    public void registerDataSetObserver(DataSetObserver observer) {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+\r
+    @Override\r
+    public void unregisterDataSetObserver(DataSetObserver observer) {\r
+        // TODO Auto-generated method stub\r
+\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/ui/adapter/LandingScreenAdapter.java b/src/com/owncloud/android/ui/adapter/LandingScreenAdapter.java
new file mode 100644 (file)
index 0000000..8bc5675
--- /dev/null
@@ -0,0 +1,112 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.adapter;\r
+\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.ui.activity.FileDisplayActivity;\r
+import com.owncloud.android.ui.activity.Preferences;\r
+\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.BaseAdapter;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * Populates the landing screen icons.\r
+ * \r
+ * @author Lennart Rosam\r
+ * \r
+ */\r
+public class LandingScreenAdapter extends BaseAdapter {\r
+\r
+    private Context mContext;\r
+\r
+    private final Integer[] mLandingScreenIcons = { R.drawable.home,\r
+            R.drawable.music, R.drawable.contacts, R.drawable.calendar,\r
+            android.R.drawable.ic_menu_agenda, R.drawable.settings };\r
+\r
+    private final Integer[] mLandingScreenTexts = { R.string.main_files,\r
+            R.string.main_music, R.string.main_contacts,\r
+            R.string.main_calendar, R.string.main_bookmarks,\r
+            R.string.main_settings };\r
+\r
+    public LandingScreenAdapter(Context context) {\r
+        mContext = context;\r
+    }\r
+\r
+    @Override\r
+    public int getCount() {\r
+        return mLandingScreenIcons.length;\r
+    }\r
+\r
+    @Override\r
+    /**\r
+     * Returns the Intent associated with this object\r
+     * or null if the functionality is not yet implemented\r
+     */\r
+    public Object getItem(int position) {\r
+        Intent intent = new Intent();\r
+\r
+        switch (position) {\r
+        case 0:\r
+            /*\r
+             * The FileDisplayActivity requires the ownCloud account as an\r
+             * parcableExtra. We will put in the one that is selected in the\r
+             * preferences\r
+             */\r
+            intent.setClass(mContext, FileDisplayActivity.class);\r
+            intent.putExtra("ACCOUNT",\r
+                    AccountUtils.getCurrentOwnCloudAccount(mContext));\r
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\r
+            break;\r
+        case 5:\r
+            intent.setClass(mContext, Preferences.class);\r
+            break;\r
+        default:\r
+            intent = null;\r
+        }\r
+        return intent;\r
+    }\r
+\r
+    @Override\r
+    public long getItemId(int position) {\r
+        return position;\r
+    }\r
+\r
+    @Override\r
+    public View getView(int position, View convertView, ViewGroup parent) {\r
+        if (convertView == null) {\r
+            LayoutInflater inflator = LayoutInflater.from(mContext);\r
+            convertView = inflator.inflate(R.layout.landing_page_item, null);\r
+\r
+            ImageView icon = (ImageView) convertView\r
+                    .findViewById(R.id.gridImage);\r
+            TextView iconText = (TextView) convertView\r
+                    .findViewById(R.id.gridText);\r
+\r
+            icon.setImageResource(mLandingScreenIcons[position]);\r
+            iconText.setText(mLandingScreenTexts[position]);\r
+        }\r
+        return convertView;\r
+    }\r
+}\r
diff --git a/src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java b/src/com/owncloud/android/ui/fragment/AuthenticatorAccountDetailsFragment.java
new file mode 100644 (file)
index 0000000..9517fcd
--- /dev/null
@@ -0,0 +1,7 @@
+package com.owncloud.android.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorAccountDetailsFragment extends SherlockFragment {
+
+}
diff --git a/src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java b/src/com/owncloud/android/ui/fragment/AuthenticatorGetStartedFragment.java
new file mode 100644 (file)
index 0000000..f321aa9
--- /dev/null
@@ -0,0 +1,7 @@
+package com.owncloud.android.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorGetStartedFragment extends SherlockFragment {
+
+}
diff --git a/src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java b/src/com/owncloud/android/ui/fragment/ConfirmationDialogFragment.java
new file mode 100644 (file)
index 0000000..62a68d5
--- /dev/null
@@ -0,0 +1,92 @@
+package com.owncloud.android.ui.fragment;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+
+public class ConfirmationDialogFragment extends SherlockDialogFragment {
+
+    public final static String ARG_CONF_RESOURCE_ID = "resource_id";
+    public final static String ARG_CONF_ARGUMENTS = "string_array";
+    
+    public final static String ARG_POSITIVE_BTN_RES = "positive_btn_res";
+    public final static String ARG_NEUTRAL_BTN_RES = "neutral_btn_res";
+    public final static String ARG_NEGATIVE_BTN_RES = "negative_btn_res";
+    
+    private ConfirmationDialogFragmentListener mListener;
+    
+    public static ConfirmationDialogFragment newInstance(int string_id, String[] arguments, int posBtn, int neuBtn, int negBtn) {
+        ConfirmationDialogFragment frag = new ConfirmationDialogFragment();
+        Bundle args = new Bundle();
+        args.putInt(ARG_CONF_RESOURCE_ID, string_id);
+        args.putStringArray(ARG_CONF_ARGUMENTS, arguments);
+        args.putInt(ARG_POSITIVE_BTN_RES, posBtn);
+        args.putInt(ARG_NEUTRAL_BTN_RES, neuBtn);
+        args.putInt(ARG_NEGATIVE_BTN_RES, negBtn);
+        frag.setArguments(args);
+        return frag;
+    }
+    
+    public void setOnConfirmationListener(ConfirmationDialogFragmentListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Object[] confirmationTarget = getArguments().getStringArray(ARG_CONF_ARGUMENTS);
+        int resourceId = getArguments().getInt(ARG_CONF_RESOURCE_ID, -1);
+        int posBtn = getArguments().getInt(ARG_POSITIVE_BTN_RES, -1);
+        int neuBtn = getArguments().getInt(ARG_NEUTRAL_BTN_RES, -1);
+        int negBtn = getArguments().getInt(ARG_NEGATIVE_BTN_RES, -1);
+        
+        if (confirmationTarget == null || resourceId == -1) {
+            Log.wtf(getTag(), "Calling confirmation dialog without resource or arguments");
+            return null;
+        }
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+            .setIcon(android.R.drawable.ic_dialog_alert)
+            .setMessage(String.format(getString(resourceId), confirmationTarget))
+            .setTitle(android.R.string.dialog_alert_title);
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+            builder.setIconAttribute(android.R.attr.alertDialogIcon);
+        }
+        
+        if (posBtn != -1)
+            builder.setPositiveButton(posBtn,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int whichButton) {
+                            mListener.onConfirmation(getTag()); 
+                        }
+                    });
+        if (neuBtn != -1)
+            builder.setNeutralButton(neuBtn,
+                    new DialogInterface.OnClickListener() {
+                        public void onClick(DialogInterface dialog, int whichButton) {
+                            mListener.onNeutral(getTag()); 
+                        }
+                    });
+        if (negBtn != -1)
+            builder.setNegativeButton(negBtn,
+                    new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            mListener.onCancel(getTag());
+                        }
+                    });
+      return builder.create();
+    }
+    
+    
+    public interface ConfirmationDialogFragmentListener {
+        public void onConfirmation(String callerTag);
+        public void onNeutral(String callerTag);
+        public void onCancel(String callerTag);
+    }
+    
+}
+
diff --git a/src/com/owncloud/android/ui/fragment/FileDetailFragment.java b/src/com/owncloud/android/ui/fragment/FileDetailFragment.java
new file mode 100644 (file)
index 0000000..ae38a0a
--- /dev/null
@@ -0,0 +1,1126 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.fragment;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.apache.commons.httpclient.HttpException;\r
+import org.apache.commons.httpclient.methods.GetMethod;\r
+import org.apache.commons.httpclient.methods.PostMethod;\r
+import org.apache.commons.httpclient.methods.StringRequestEntity;\r
+import org.apache.commons.httpclient.params.HttpConnectionManagerParams;\r
+import org.apache.http.HttpStatus;\r
+import org.apache.http.NameValuePair;\r
+import org.apache.http.client.utils.URLEncodedUtils;\r
+import org.apache.http.message.BasicNameValuePair;\r
+import org.apache.http.protocol.HTTP;\r
+import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;\r
+import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;\r
+import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;\r
+import org.json.JSONException;\r
+import org.json.JSONObject;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.annotation.SuppressLint;\r
+import android.app.Activity;\r
+import android.content.ActivityNotFoundException;\r
+import android.content.BroadcastReceiver;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.content.IntentFilter;\r
+import android.content.res.Resources.NotFoundException;\r
+import android.graphics.Bitmap;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.BitmapFactory.Options;\r
+import android.graphics.Point;\r
+import android.net.Uri;\r
+import android.os.AsyncTask;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.support.v4.app.FragmentTransaction;\r
+import android.util.Log;\r
+import android.view.Display;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+import android.view.ViewGroup;\r
+import android.view.WindowManager.LayoutParams;\r
+import android.webkit.MimeTypeMap;\r
+import android.widget.Button;\r
+import android.widget.CheckBox;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+\r
+import com.actionbarsherlock.app.SherlockDialogFragment;\r
+import com.actionbarsherlock.app.SherlockFragment;\r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.DisplayUtils;\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.datamodel.FileDataStorageManager;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.files.services.FileDownloader;\r
+import com.owncloud.android.files.services.FileUploader;\r
+import com.owncloud.android.ui.activity.FileDetailActivity;\r
+import com.owncloud.android.ui.activity.FileDisplayActivity;\r
+import com.owncloud.android.utils.OwnCloudVersion;\r
+\r
+import com.owncloud.android.R;\r
+import eu.alefzero.webdav.WebdavClient;\r
+import eu.alefzero.webdav.WebdavUtils;\r
+\r
+/**\r
+ * This Fragment is used to display the details about a file.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class FileDetailFragment extends SherlockFragment implements\r
+        OnClickListener, ConfirmationDialogFragment.ConfirmationDialogFragmentListener {\r
+\r
+    public static final String EXTRA_FILE = "FILE";\r
+    public static final String EXTRA_ACCOUNT = "ACCOUNT";\r
+\r
+    private FileDetailFragment.ContainerActivity mContainerActivity;\r
+    \r
+    private int mLayout;\r
+    private View mView;\r
+    private OCFile mFile;\r
+    private Account mAccount;\r
+    private ImageView mPreview;\r
+    \r
+    private DownloadFinishReceiver mDownloadFinishReceiver;\r
+    private UploadFinishReceiver mUploadFinishReceiver;\r
+\r
+    private static final String TAG = "FileDetailFragment";\r
+    public static final String FTAG = "FileDetails"; \r
+    public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT";\r
+\r
+    \r
+    /**\r
+     * Creates an empty details fragment.\r
+     * \r
+     * It's necessary to keep a public constructor without parameters; the system uses it when tries to reinstantiate a fragment automatically. \r
+     */\r
+    public FileDetailFragment() {\r
+        mFile = null;\r
+        mAccount = null;\r
+        mLayout = R.layout.file_details_empty;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Creates a details fragment.\r
+     * \r
+     * When 'fileToDetail' or 'ocAccount' are null, creates a dummy layout (to use when a file wasn't tapped before).\r
+     * \r
+     * @param fileToDetail      An {@link OCFile} to show in the fragment\r
+     * @param ocAccount         An ownCloud account; needed to start downloads\r
+     */\r
+    public FileDetailFragment(OCFile fileToDetail, Account ocAccount){\r
+        mFile = fileToDetail;\r
+        mAccount = ocAccount;\r
+        mLayout = R.layout.file_details_empty;\r
+        \r
+        if(fileToDetail != null && ocAccount != null) {\r
+            mLayout = R.layout.file_details_fragment;\r
+        }\r
+    }\r
+    \r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onAttach(Activity activity) {\r
+        super.onAttach(activity);\r
+        try {\r
+            mContainerActivity = (ContainerActivity) activity;\r
+        } catch (ClassCastException e) {\r
+            throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");\r
+        }\r
+    }\r
+    \r
+    \r
+    @Override\r
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
+            Bundle savedInstanceState) {\r
+        super.onCreateView(inflater, container, savedInstanceState);\r
+        \r
+        if (savedInstanceState != null) {\r
+            mFile = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);\r
+            mAccount = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_ACCOUNT);\r
+        }\r
+        \r
+        View view = null;\r
+        view = inflater.inflate(mLayout, container, false);\r
+        mView = view;\r
+        \r
+        if (mLayout == R.layout.file_details_fragment) {\r
+            mView.findViewById(R.id.fdKeepInSync).setOnClickListener(this);\r
+            mView.findViewById(R.id.fdRenameBtn).setOnClickListener(this);\r
+            mView.findViewById(R.id.fdDownloadBtn).setOnClickListener(this);\r
+            mView.findViewById(R.id.fdOpenBtn).setOnClickListener(this);\r
+            mView.findViewById(R.id.fdRemoveBtn).setOnClickListener(this);\r
+            //mView.findViewById(R.id.fdShareBtn).setOnClickListener(this);\r
+            mPreview = (ImageView)mView.findViewById(R.id.fdPreview);\r
+        }\r
+        \r
+        updateFileDetails();\r
+        return view;\r
+    }\r
+    \r
+\r
+    @Override\r
+    public void onSaveInstanceState(Bundle outState) {\r
+        Log.i(getClass().toString(), "onSaveInstanceState() start");\r
+        super.onSaveInstanceState(outState);\r
+        outState.putParcelable(FileDetailFragment.EXTRA_FILE, mFile);\r
+        outState.putParcelable(FileDetailFragment.EXTRA_ACCOUNT, mAccount);\r
+        Log.i(getClass().toString(), "onSaveInstanceState() end");\r
+    }\r
+\r
+    \r
+    @Override\r
+    public void onResume() {\r
+        super.onResume();\r
+        \r
+        mDownloadFinishReceiver = new DownloadFinishReceiver();\r
+        IntentFilter filter = new IntentFilter(\r
+                FileDownloader.DOWNLOAD_FINISH_MESSAGE);\r
+        getActivity().registerReceiver(mDownloadFinishReceiver, filter);\r
+        \r
+        mUploadFinishReceiver = new UploadFinishReceiver();\r
+        filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);\r
+        getActivity().registerReceiver(mUploadFinishReceiver, filter);\r
+        \r
+        mPreview = (ImageView)mView.findViewById(R.id.fdPreview);\r
+    }\r
+\r
+    @Override\r
+    public void onPause() {\r
+        super.onPause();\r
+        \r
+        getActivity().unregisterReceiver(mDownloadFinishReceiver);\r
+        mDownloadFinishReceiver = null;\r
+        \r
+        getActivity().unregisterReceiver(mUploadFinishReceiver);\r
+        mUploadFinishReceiver = null;\r
+        \r
+        if (mPreview != null) {\r
+            mPreview = null;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public View getView() {\r
+        return super.getView() == null ? mView : super.getView();\r
+    }\r
+\r
+    \r
+    \r
+    @Override\r
+    public void onClick(View v) {\r
+        switch (v.getId()) {\r
+            case R.id.fdDownloadBtn: {\r
+                Intent i = new Intent(getActivity(), FileDownloader.class);\r
+                i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);\r
+                i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath());\r
+                i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());\r
+                i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());\r
+                \r
+                // update ui \r
+                setButtonsForTransferring();\r
+                \r
+                getActivity().startService(i);\r
+                mContainerActivity.onFileStateChanged();    // this is not working; it is performed before the fileDownloadService registers it as 'in progress'\r
+                break;\r
+            }\r
+            case R.id.fdKeepInSync: {\r
+                CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);\r
+                mFile.setKeepInSync(cb.isChecked());\r
+                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());\r
+                fdsm.saveFile(mFile);\r
+                if (mFile.keepInSync()) {\r
+                    onClick(getView().findViewById(R.id.fdDownloadBtn));\r
+                } else {    \r
+                    mContainerActivity.onFileStateChanged();    // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn)\r
+                }\r
+                break;\r
+            }\r
+            case R.id.fdRenameBtn: {\r
+                EditNameFragment dialog = EditNameFragment.newInstance(mFile.getFileName());\r
+                dialog.show(getFragmentManager(), "nameeditdialog");\r
+                dialog.setOnDismissListener(this);\r
+                break;\r
+            }   \r
+            case R.id.fdRemoveBtn: {\r
+                ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(\r
+                        R.string.confirmation_remove_alert,\r
+                        new String[]{mFile.getFileName()},\r
+                        mFile.isDown() ? R.string.confirmation_remove_remote_and_local : R.string.confirmation_remove_remote,\r
+                        mFile.isDown() ? R.string.confirmation_remove_local : -1,\r
+                        R.string.common_cancel);\r
+                confDialog.setOnConfirmationListener(this);\r
+                confDialog.show(getFragmentManager(), FTAG_CONFIRMATION);\r
+                break;\r
+            }\r
+            case R.id.fdOpenBtn: {\r
+                String storagePath = mFile.getStoragePath();\r
+                String encodedStoragePath = WebdavUtils.encodePath(storagePath);\r
+                try {\r
+                    Intent i = new Intent(Intent.ACTION_VIEW);\r
+                    i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mFile.getMimetype());\r
+                    i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);\r
+                    startActivity(i);\r
+                    \r
+                } catch (Throwable t) {\r
+                    Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());\r
+                    boolean toastIt = true; \r
+                    String mimeType = "";\r
+                    try {\r
+                        Intent i = new Intent(Intent.ACTION_VIEW);\r
+                        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));\r
+                        if (mimeType != null && !mimeType.equals(mFile.getMimetype())) {\r
+                            i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType);\r
+                            i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);\r
+                            startActivity(i);\r
+                            toastIt = false;\r
+                        }\r
+                        \r
+                    } catch (IndexOutOfBoundsException e) {\r
+                        Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);\r
+                        \r
+                    } catch (ActivityNotFoundException e) {\r
+                        Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");\r
+                        \r
+                    } catch (Throwable th) {\r
+                        Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);\r
+                        \r
+                    } finally {\r
+                        if (toastIt) {\r
+                            Toast.makeText(getActivity(), "There is no application to handle file " + mFile.getFileName(), Toast.LENGTH_SHORT).show();\r
+                        }\r
+                    }\r
+                    \r
+                }\r
+                break;\r
+            }\r
+            default:\r
+                Log.e(TAG, "Incorrect view clicked!");\r
+        }\r
+        \r
+        /* else if (v.getId() == R.id.fdShareBtn) {\r
+            Thread t = new Thread(new ShareRunnable(mFile.getRemotePath()));\r
+            t.start();\r
+        }*/\r
+    }\r
+    \r
+    \r
+    @Override\r
+    public void onConfirmation(String callerTag) {\r
+        if (callerTag.equals(FTAG_CONFIRMATION)) {\r
+            FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
+            if (fdsm.getFileById(mFile.getFileId()) != null) {\r
+                new Thread(new RemoveRunnable(mFile, mAccount, new Handler())).start();\r
+                boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+                getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+            }\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public void onNeutral(String callerTag) {\r
+        FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
+        File f = null;\r
+        if (mFile.isDown() && (f = new File(mFile.getStoragePath())).exists()) {\r
+            f.delete();\r
+            mFile.setStoragePath(null);\r
+            fdsm.saveFile(mFile);\r
+            updateFileDetails(mFile, mAccount);\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public void onCancel(String callerTag) {\r
+        Log.d(TAG, "REMOVAL CANCELED");\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Check if the fragment was created with an empty layout. An empty fragment can't show file details, must be replaced.\r
+     * \r
+     * @return  True when the fragment was created with the empty layout.\r
+     */\r
+    public boolean isEmpty() {\r
+        return mLayout == R.layout.file_details_empty;\r
+    }\r
+\r
+    \r
+    /**\r
+     * Can be used to get the file that is currently being displayed.\r
+     * @return The file on the screen.\r
+     */\r
+    public OCFile getDisplayedFile(){\r
+        return mFile;\r
+    }\r
+    \r
+    /**\r
+     * Use this method to signal this Activity that it shall update its view.\r
+     * \r
+     * @param file : An {@link OCFile}\r
+     */\r
+    public void updateFileDetails(OCFile file, Account ocAccount) {\r
+        mFile = file;\r
+        mAccount = ocAccount;\r
+        updateFileDetails();\r
+    }\r
+    \r
+\r
+    /**\r
+     * Updates the view with all relevant details about that file.\r
+     */\r
+    public void updateFileDetails() {\r
+\r
+        if (mFile != null && mAccount != null && mLayout == R.layout.file_details_fragment) {\r
+            \r
+            // set file details\r
+            setFilename(mFile.getFileName());\r
+            setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile\r
+                    .getMimetype()));\r
+            setFilesize(mFile.getFileLength());\r
+            if(ocVersionSupportsTimeCreated()){\r
+                setTimeCreated(mFile.getCreationTimestamp());\r
+            }\r
+           \r
+            setTimeModified(mFile.getModificationTimestamp());\r
+            \r
+            CheckBox cb = (CheckBox)getView().findViewById(R.id.fdKeepInSync);\r
+            cb.setChecked(mFile.keepInSync());\r
+\r
+            // configure UI for depending upon local state of the file\r
+            if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) {\r
+                setButtonsForTransferring();\r
+                \r
+            } else if (mFile.isDown()) {\r
+                // Update preview\r
+                if (mFile.getMimetype().startsWith("image/")) {\r
+                    BitmapLoader bl = new BitmapLoader();\r
+                    bl.execute(new String[]{mFile.getStoragePath()});\r
+                }\r
+                \r
+                setButtonsForDown();\r
+                \r
+            } else {\r
+                setButtonsForRemote();\r
+            }\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Updates the filename in view\r
+     * @param filename to set\r
+     */\r
+    private void setFilename(String filename) {\r
+        TextView tv = (TextView) getView().findViewById(R.id.fdFilename);\r
+        if (tv != null)\r
+            tv.setText(filename);\r
+    }\r
+\r
+    /**\r
+     * Updates the MIME type in view\r
+     * @param mimetype to set\r
+     */\r
+    private void setFiletype(String mimetype) {\r
+        TextView tv = (TextView) getView().findViewById(R.id.fdType);\r
+        if (tv != null)\r
+            tv.setText(mimetype);\r
+    }\r
+\r
+    /**\r
+     * Updates the file size in view\r
+     * @param filesize in bytes to set\r
+     */\r
+    private void setFilesize(long filesize) {\r
+        TextView tv = (TextView) getView().findViewById(R.id.fdSize);\r
+        if (tv != null)\r
+            tv.setText(DisplayUtils.bytesToHumanReadable(filesize));\r
+    }\r
+    \r
+    /**\r
+     * Updates the time that the file was created in view\r
+     * @param milliseconds Unix time to set\r
+     */\r
+    private void setTimeCreated(long milliseconds){\r
+        TextView tv = (TextView) getView().findViewById(R.id.fdCreated);\r
+        TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);\r
+        if(tv != null){\r
+            tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));\r
+            tv.setVisibility(View.VISIBLE);\r
+            tvLabel.setVisibility(View.VISIBLE);\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Updates the time that the file was last modified\r
+     * @param milliseconds Unix time to set\r
+     */\r
+    private void setTimeModified(long milliseconds){\r
+        TextView tv = (TextView) getView().findViewById(R.id.fdModified);\r
+        if(tv != null){\r
+            tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Enables or disables buttons for a file being downloaded\r
+     */\r
+    private void setButtonsForTransferring() {\r
+        if (!isEmpty()) {\r
+            Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);\r
+            //downloadButton.setText(R.string.filedetails_download_in_progress);    // ugly\r
+            downloadButton.setEnabled(false);   // TODO replace it with a 'cancel download' button\r
+        \r
+            // let's protect the user from himself ;)\r
+            ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);\r
+            ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(false);\r
+            ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(false);\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Enables or disables buttons for a file locally available \r
+     */\r
+    private void setButtonsForDown() {\r
+        if (!isEmpty()) {\r
+            Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);\r
+            //downloadButton.setText(R.string.filedetails_redownload);      // ugly\r
+            downloadButton.setEnabled(true);\r
+        \r
+            ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(true);\r
+            ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);\r
+            ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Enables or disables buttons for a file not locally available \r
+     */\r
+    private void setButtonsForRemote() {\r
+        if (!isEmpty()) {\r
+            Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);\r
+            //downloadButton.setText(R.string.filedetails_download);    // unnecessary\r
+            downloadButton.setEnabled(true);\r
+            \r
+            ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);\r
+            ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);\r
+            ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);\r
+        }\r
+    }\r
+    \r
+\r
+    /**\r
+     * In ownCloud 3.X.X and 4.X.X there is a bug that SabreDAV does not return\r
+     * the time that the file was created. There is a chance that this will\r
+     * be fixed in future versions. Use this method to check if this version of\r
+     * ownCloud has this fix.\r
+     * @return True, if ownCloud the ownCloud version is supporting creation time\r
+     */\r
+    private boolean ocVersionSupportsTimeCreated(){\r
+        /*if(mAccount != null){\r
+            AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);\r
+            OwnCloudVersion ocVersion = new OwnCloudVersion(accManager\r
+                    .getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
+            if(ocVersion.compareTo(new OwnCloudVersion(0x030000)) < 0) {\r
+                return true;\r
+            }\r
+        }*/\r
+        return false;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Interface to implement by any Activity that includes some instance of FileDetailFragment\r
+     * \r
+     * @author David A. Velasco\r
+     */\r
+    public interface ContainerActivity {\r
+\r
+        /**\r
+         * Callback method invoked when the detail fragment wants to notice its container \r
+         * activity about a relevant state the file shown by the fragment.\r
+         * \r
+         * Added to notify to FileDisplayActivity about the need of refresh the files list. \r
+         * \r
+         * Currently called when:\r
+         *  - a download is started;\r
+         *  - a rename is completed;\r
+         *  - a deletion is completed;\r
+         *  - the 'inSync' flag is changed;\r
+         */\r
+        public void onFileStateChanged();\r
+        \r
+    }\r
+    \r
+\r
+    /**\r
+     * Once the file download has finished -> update view\r
+     * @author Bartek Przybylski\r
+     */\r
+    private class DownloadFinishReceiver extends BroadcastReceiver {\r
+        @Override\r
+        public void onReceive(Context context, Intent intent) {\r
+            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);\r
+\r
+            if (!isEmpty() && accountName.equals(mAccount.name)) {\r
+                boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);\r
+                String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);\r
+                if (mFile.getRemotePath().equals(downloadedRemotePath)) {\r
+                    if (downloadWasFine) {\r
+                        mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH));    // updates the local object without accessing the database again\r
+                    }\r
+                    updateFileDetails();    // it updates the buttons; must be called although !downloadWasFine\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+    \r
+    /**\r
+     * Once the file upload has finished -> update view\r
+     * \r
+     * Being notified about the finish of an upload is necessary for the next sequence:\r
+     *   1. Upload a big file.\r
+     *   2. Force a synchronization; if it finished before the upload, the file in transfer will be included in the local database and in the file list\r
+     *      of its containing folder; the the server includes it in the PROPFIND requests although it's not fully upload. \r
+     *   3. Click the file in the list to see its details.\r
+     *   4. Wait for the upload finishes; at this moment, the details view must be refreshed to enable the action buttons.\r
+     */\r
+    private class UploadFinishReceiver extends BroadcastReceiver {\r
+        @Override\r
+        public void onReceive(Context context, Intent intent) {\r
+            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);\r
+\r
+            if (!isEmpty() && accountName.equals(mAccount.name)) {\r
+                boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);\r
+                String uploadRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH);\r
+                if (mFile.getRemotePath().equals(uploadRemotePath)) {\r
+                    if (uploadWasFine) {\r
+                        FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());\r
+                        mFile = fdsm.getFileByPath(mFile.getRemotePath());\r
+                    }\r
+                    updateFileDetails();    // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+\r
+    // this is a temporary class for sharing purposes, it need to be replaced in transfer service\r
+    private class ShareRunnable implements Runnable {\r
+        private String mPath;\r
+\r
+        public ShareRunnable(String path) {\r
+            mPath = path;\r
+        }\r
+        \r
+        public void run() {\r
+            AccountManager am = AccountManager.get(getActivity());\r
+            Account account = AccountUtils.getCurrentOwnCloudAccount(getActivity());\r
+            OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));\r
+            String url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + AccountUtils.getWebdavPath(ocv);\r
+\r
+            Log.d("share", "sharing for version " + ocv.toString());\r
+\r
+            if (ocv.compareTo(new OwnCloudVersion(0x040000)) >= 0) {\r
+                String APPS_PATH = "/apps/files_sharing/";\r
+                String SHARE_PATH = "ajax/share.php";\r
+\r
+                String SHARED_PATH = "/apps/files_sharing/get.php?token=";\r
+                \r
+                final String WEBDAV_SCRIPT = "webdav.php";\r
+                final String WEBDAV_FILES_LOCATION = "/files/";\r
+                \r
+                WebdavClient wc = new WebdavClient();\r
+                HttpConnectionManagerParams params = new HttpConnectionManagerParams();\r
+                params.setMaxConnectionsPerHost(wc.getHostConfiguration(), 5);\r
+\r
+                //wc.getParams().setParameter("http.protocol.single-cookie-header", true);\r
+                //wc.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);\r
+\r
+                PostMethod post = new PostMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + APPS_PATH + SHARE_PATH);\r
+\r
+                post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8" );\r
+                post.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));\r
+                List<NameValuePair> formparams = new ArrayList<NameValuePair>();\r
+                Log.d("share", mPath+"");\r
+                formparams.add(new BasicNameValuePair("sources",mPath));\r
+                formparams.add(new BasicNameValuePair("uid_shared_with", "public"));\r
+                formparams.add(new BasicNameValuePair("permissions", "0"));\r
+                post.setRequestEntity(new StringRequestEntity(URLEncodedUtils.format(formparams, HTTP.UTF_8)));\r
+\r
+                int status;\r
+                try {\r
+                    PropFindMethod find = new PropFindMethod(url+"/");\r
+                    find.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));\r
+                    Log.d("sharer", ""+ url+"/");\r
+                    wc.setCredentials(account.name.substring(0, account.name.lastIndexOf('@')), am.getPassword(account));\r
+                    \r
+                    for (org.apache.commons.httpclient.Header a : find.getRequestHeaders()) {\r
+                        Log.d("sharer-h", a.getName() + ":"+a.getValue());\r
+                    }\r
+                    \r
+                    int status2 = wc.executeMethod(find);\r
+\r
+                    Log.d("sharer", "propstatus "+status2);\r
+                    \r
+                    GetMethod get = new GetMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + "/");\r
+                    get.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));\r
+                    \r
+                    status2 = wc.executeMethod(get);\r
+\r
+                    Log.d("sharer", "getstatus "+status2);\r
+                    Log.d("sharer", "" + get.getResponseBodyAsString());\r
+                    \r
+                    for (org.apache.commons.httpclient.Header a : get.getResponseHeaders()) {\r
+                        Log.d("sharer", a.getName() + ":"+a.getValue());\r
+                    }\r
+\r
+                    status = wc.executeMethod(post);\r
+                    for (org.apache.commons.httpclient.Header a : post.getRequestHeaders()) {\r
+                        Log.d("sharer-h", a.getName() + ":"+a.getValue());\r
+                    }\r
+                    for (org.apache.commons.httpclient.Header a : post.getResponseHeaders()) {\r
+                        Log.d("sharer", a.getName() + ":"+a.getValue());\r
+                    }\r
+                    String resp = post.getResponseBodyAsString();\r
+                    Log.d("share", ""+post.getURI().toString());\r
+                    Log.d("share", "returned status " + status);\r
+                    Log.d("share", " " +resp);\r
+                    \r
+                    if(status != HttpStatus.SC_OK ||resp == null || resp.equals("") || resp.startsWith("false")) {\r
+                        return;\r
+                     }\r
+\r
+                    JSONObject jsonObject = new JSONObject (resp);\r
+                    String jsonStatus = jsonObject.getString("status");\r
+                    if(!jsonStatus.equals("success")) throw new Exception("Error while sharing file status != success");\r
+                    \r
+                    String token = jsonObject.getString("data");\r
+                    String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token; \r
+                    Log.d("Actions:shareFile ok", "url: " + uri);   \r
+                    \r
+                } catch (HttpException e) {\r
+                    // TODO Auto-generated catch block\r
+                    e.printStackTrace();\r
+                } catch (IOException e) {\r
+                    // TODO Auto-generated catch block\r
+                    e.printStackTrace();\r
+                } catch (JSONException e) {\r
+                    // TODO Auto-generated catch block\r
+                    e.printStackTrace();\r
+                } catch (Exception e) {\r
+                    // TODO Auto-generated catch block\r
+                    e.printStackTrace();\r
+                }\r
+                \r
+            } else if (ocv.compareTo(new OwnCloudVersion(0x030000)) >= 0) {\r
+                \r
+            }\r
+        }\r
+    }\r
+    \r
+    public void onDismiss(EditNameFragment dialog) {\r
+        if (dialog instanceof EditNameFragment) {\r
+            if (((EditNameFragment)dialog).getResult()) {\r
+                String newFilename = ((EditNameFragment)dialog).getNewFilename();\r
+                Log.d(TAG, "name edit dialog dismissed with new name " + newFilename);\r
+                if (!newFilename.equals(mFile.getFileName())) {\r
+                    FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
+                    if (fdsm.getFileById(mFile.getFileId()) != null) {\r
+                        OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + newFilename);\r
+                        newFile.setCreationTimestamp(mFile.getCreationTimestamp());\r
+                        newFile.setFileId(mFile.getFileId());\r
+                        newFile.setFileLength(mFile.getFileLength());\r
+                        newFile.setKeepInSync(mFile.keepInSync());\r
+                        newFile.setLastSyncDate(mFile.getLastSyncDate());\r
+                        newFile.setMimetype(mFile.getMimetype());\r
+                        newFile.setModificationTimestamp(mFile.getModificationTimestamp());\r
+                        newFile.setParentId(mFile.getParentId());\r
+                        boolean localRenameFails = false;\r
+                        if (mFile.isDown()) {\r
+                            File f = new File(mFile.getStoragePath());\r
+                            Log.e(TAG, f.getAbsolutePath());\r
+                            localRenameFails = !(f.renameTo(new File(f.getParent() + File.separator + newFilename)));\r
+                            Log.e(TAG, f.getParent() + File.separator + newFilename);\r
+                            newFile.setStoragePath(f.getParent() + File.separator + newFilename);\r
+                        }\r
+                        \r
+                        if (localRenameFails) {\r
+                            Toast msg = Toast.makeText(getActivity(), R.string.rename_local_fail_msg, Toast.LENGTH_LONG); \r
+                            msg.show();\r
+                            \r
+                        } else {\r
+                            new Thread(new RenameRunnable(mFile, newFile, mAccount, new Handler())).start();\r
+                            boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+                            getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+                        }\r
+\r
+                    }\r
+                }\r
+            }\r
+        } else {\r
+            Log.e(TAG, "Unknown dialog instance passed to onDismissDalog: " + dialog.getClass().getCanonicalName());\r
+        }\r
+        \r
+    }\r
+    \r
+    private class RenameRunnable implements Runnable {\r
+        \r
+        Account mAccount;\r
+        OCFile mOld, mNew;\r
+        Handler mHandler;\r
+        \r
+        public RenameRunnable(OCFile oldFile, OCFile newFile, Account account, Handler handler) {\r
+            mOld = oldFile;\r
+            mNew = newFile;\r
+            mAccount = account;\r
+            mHandler = handler;\r
+        }\r
+        \r
+        public void run() {\r
+            WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());\r
+            wc.allowSelfsignedCertificates();\r
+            AccountManager am = AccountManager.get(getSherlockActivity());\r
+            String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
+            OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
+            String webdav_path = AccountUtils.getWebdavPath(ocv);\r
+            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()));\r
+\r
+            Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));\r
+            LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()),\r
+                                             Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));\r
+            \r
+            boolean success = false;\r
+            try {\r
+                int status = wc.executeMethod(move);\r
+                success = move.succeeded();\r
+                Log.d(TAG, "Move returned status: " + status);\r
+                \r
+            } catch (HttpException e) {\r
+                Log.e(TAG, "HTTP Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);\r
+                \r
+            } catch (IOException e) {\r
+                Log.e(TAG, "I/O Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);\r
+                \r
+            } catch (Exception e) {\r
+                Log.e(TAG, "Unexpected exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);\r
+            }\r
+            \r
+            if (success) {\r
+                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
+                fdsm.removeFile(mOld);\r
+                fdsm.saveFile(mNew);\r
+                mFile = mNew;\r
+                mHandler.post(new Runnable() {\r
+                    @Override\r
+                    public void run() { \r
+                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+                        updateFileDetails(mFile, mAccount);\r
+                        mContainerActivity.onFileStateChanged();\r
+                    }\r
+                });\r
+                \r
+            } else {\r
+                mHandler.post(new Runnable() {\r
+                    @Override\r
+                    public void run() {\r
+                        // undo the local rename\r
+                        if (mNew.isDown()) {\r
+                            File f = new File(mNew.getStoragePath());\r
+                            if (!f.renameTo(new File(mOld.getStoragePath()))) {\r
+                                // the local rename undoing failed; last chance: save the new local storage path in the old file\r
+                                mFile.setStoragePath(mNew.getStoragePath());\r
+                                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
+                                fdsm.saveFile(mFile);\r
+                            }\r
+                        }\r
+                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+                        try {\r
+                            Toast msg = Toast.makeText(getActivity(), R.string.rename_server_fail_msg, Toast.LENGTH_LONG); \r
+                            msg.show();\r
+                            \r
+                        } catch (NotFoundException e) {\r
+                            e.printStackTrace();\r
+                        }\r
+                    }\r
+                });\r
+            }\r
+        }\r
+        private class LocalMoveMethod extends DavMethodBase {\r
+\r
+            public LocalMoveMethod(String uri, String dest) {\r
+                super(uri);\r
+                addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest));\r
+            }\r
+\r
+            @Override\r
+            public String getName() {\r
+                return "MOVE";\r
+            }\r
+\r
+            @Override\r
+            protected boolean isSuccess(int status) {\r
+                return status == 201 || status == 204;\r
+            }\r
+            \r
+        }\r
+    }\r
+    \r
+    private static class EditNameFragment extends SherlockDialogFragment implements OnClickListener {\r
+\r
+        private String mNewFilename;\r
+        private boolean mResult;\r
+        private FileDetailFragment mListener;\r
+        \r
+        static public EditNameFragment newInstance(String filename) {\r
+            EditNameFragment f = new EditNameFragment();\r
+            Bundle args = new Bundle();\r
+            args.putString("filename", filename);\r
+            f.setArguments(args);\r
+            return f;\r
+        }\r
+        \r
+        @Override\r
+        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r
+            View v = inflater.inflate(R.layout.edit_box_dialog, container, false);\r
+\r
+            String currentName = getArguments().getString("filename");\r
+            if (currentName == null)\r
+                currentName = "";\r
+            \r
+            ((Button)v.findViewById(R.id.cancel)).setOnClickListener(this);\r
+            ((Button)v.findViewById(R.id.ok)).setOnClickListener(this);\r
+            ((TextView)v.findViewById(R.id.user_input)).setText(currentName);\r
+            ((TextView)v.findViewById(R.id.user_input)).requestFocus();\r
+            getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);\r
+\r
+            mResult = false;\r
+            return v;\r
+        }\r
+        \r
+        @Override\r
+        public void onClick(View view) {\r
+            switch (view.getId()) {\r
+                case R.id.ok: {\r
+                    mNewFilename = ((TextView)getView().findViewById(R.id.user_input)).getText().toString();\r
+                    mResult = true;\r
+                }\r
+                case R.id.cancel: { // fallthought\r
+                    dismiss();\r
+                    mListener.onDismiss(this);\r
+                }\r
+            }\r
+        }\r
+        \r
+        void setOnDismissListener(FileDetailFragment listener) {\r
+            mListener = listener;\r
+        }\r
+        \r
+        public String getNewFilename() {\r
+            return mNewFilename;\r
+        }\r
+        \r
+        // true if user click ok\r
+        public boolean getResult() {\r
+            return mResult;\r
+        }\r
+        \r
+    }\r
+    \r
+    private class RemoveRunnable implements Runnable {\r
+        \r
+        Account mAccount;\r
+        OCFile mFileToRemove;\r
+        Handler mHandler;\r
+        \r
+        public RemoveRunnable(OCFile fileToRemove, Account account, Handler handler) {\r
+            mFileToRemove = fileToRemove;\r
+            mAccount = account;\r
+            mHandler = handler;\r
+        }\r
+        \r
+        public void run() {\r
+            WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());\r
+            wc.allowSelfsignedCertificates();\r
+            AccountManager am = AccountManager.get(getSherlockActivity());\r
+            String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
+            OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
+            String webdav_path = AccountUtils.getWebdavPath(ocv);\r
+            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));\r
+\r
+            DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));\r
+            \r
+            boolean success = false;\r
+            int status = -1;\r
+            try {\r
+                status = wc.executeMethod(delete);\r
+                success = (delete.succeeded());\r
+                Log.d(TAG, "Delete: returned status " + status);\r
+                \r
+            } catch (HttpException e) {\r
+                Log.e(TAG, "HTTP Exception removing file " + mFileToRemove.getRemotePath(), e);\r
+                \r
+            } catch (IOException e) {\r
+                Log.e(TAG, "I/O Exception removing file " + mFileToRemove.getRemotePath(), e);\r
+                \r
+            } catch (Exception e) {\r
+                Log.e(TAG, "Unexpected exception removing file " + mFileToRemove.getRemotePath(), e);\r
+            }\r
+            \r
+            if (success) {\r
+                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
+                fdsm.removeFile(mFileToRemove);\r
+                mHandler.post(new Runnable() {\r
+                    @Override\r
+                    public void run() {\r
+                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+                        try {\r
+                            Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG);\r
+                            msg.show();\r
+                            if (inDisplayActivity) {\r
+                                // double pane\r
+                                FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();\r
+                                transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment\r
+                                transaction.commit();\r
+                                mContainerActivity.onFileStateChanged();\r
+                                \r
+                            } else {\r
+                                getActivity().finish();\r
+                            }\r
+                            \r
+                        } catch (NotFoundException e) {\r
+                            e.printStackTrace();\r
+                        }\r
+                    }\r
+                });\r
+                \r
+            } else {\r
+                mHandler.post(new Runnable() {\r
+                    @Override\r
+                    public void run() {\r
+                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
+                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
+                        try {\r
+                            Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG); \r
+                            msg.show();\r
+                            \r
+                        } catch (NotFoundException e) {\r
+                            e.printStackTrace();\r
+                        }\r
+                    }\r
+                });\r
+            }\r
+        }\r
+        \r
+    }\r
+    \r
+    class BitmapLoader extends AsyncTask<String, Void, Bitmap> {\r
+        @SuppressLint({ "NewApi", "NewApi", "NewApi" }) // to avoid Lint errors since Android SDK r20\r
+               @Override\r
+        protected Bitmap doInBackground(String... params) {\r
+            Bitmap result = null;\r
+            if (params.length != 1) return result;\r
+            String storagePath = params[0];\r
+            try {\r
+\r
+                BitmapFactory.Options options = new Options();\r
+                options.inScaled = true;\r
+                options.inPurgeable = true;\r
+                options.inJustDecodeBounds = true;\r
+                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {\r
+                    options.inPreferQualityOverSpeed = false;\r
+                }\r
+                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {\r
+                    options.inMutable = false;\r
+                }\r
+\r
+                result = BitmapFactory.decodeFile(storagePath, options);\r
+                options.inJustDecodeBounds = false;\r
+\r
+                int width = options.outWidth;\r
+                int height = options.outHeight;\r
+                int scale = 1;\r
+                if (width >= 2048 || height >= 2048) {\r
+                    scale = (int) Math.ceil((Math.ceil(Math.max(height, width) / 2048.)));\r
+                    options.inSampleSize = scale;\r
+                }\r
+                Display display = getActivity().getWindowManager().getDefaultDisplay();\r
+                Point size = new Point();\r
+                int screenwidth;\r
+                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {\r
+                    display.getSize(size);\r
+                    screenwidth = size.x;\r
+                } else {\r
+                    screenwidth = display.getWidth();\r
+                }\r
+\r
+                Log.e("ASD", "W " + width + " SW " + screenwidth);\r
+\r
+                if (width > screenwidth) {\r
+                    scale = (int) Math.ceil((float)width / screenwidth);\r
+                    options.inSampleSize = scale;\r
+                }\r
+\r
+                result = BitmapFactory.decodeFile(storagePath, options);\r
+\r
+                Log.e("ASD", "W " + options.outWidth + " SW " + options.outHeight);\r
+\r
+            } catch (OutOfMemoryError e) {\r
+                result = null;\r
+                Log.e(TAG, "Out of memory occured for file with size " + storagePath);\r
+                \r
+            } catch (NoSuchFieldError e) {\r
+                result = null;\r
+                Log.e(TAG, "Error from access to unexisting field despite protection " + storagePath);\r
+                \r
+            } catch (Throwable t) {\r
+                result = null;\r
+                Log.e(TAG, "Unexpected error while creating image preview " + storagePath, t);\r
+            }\r
+            return result;\r
+        }\r
+        @Override\r
+        protected void onPostExecute(Bitmap result) {\r
+            if (result != null && mPreview != null) {\r
+                mPreview.setImageBitmap(result);\r
+            }\r
+        }\r
+        \r
+    }\r
+    \r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/fragment/FileListFragment.java b/src/com/owncloud/android/ui/fragment/FileListFragment.java
new file mode 100644 (file)
index 0000000..5d1a8d1
--- /dev/null
@@ -0,0 +1,205 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.fragment;\r
+\r
+import java.util.Vector;\r
+\r
+import com.owncloud.android.datamodel.DataStorageManager;\r
+import com.owncloud.android.datamodel.OCFile;\r
+import com.owncloud.android.ui.FragmentListView;\r
+import com.owncloud.android.ui.adapter.FileListListAdapter;\r
+\r
+import android.app.Activity;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.AdapterView;\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * A Fragment that lists all files and folders in a given path.\r
+ * \r
+ * @author Bartek Przybylski\r
+ * \r
+ */\r
+public class FileListFragment extends FragmentListView {\r
+    private static final String TAG = "FileListFragment";\r
+    \r
+    private FileListFragment.ContainerActivity mContainerActivity;\r
+    \r
+    private OCFile mFile = null;\r
+    private FileListListAdapter mAdapter;\r
+\r
+    \r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onAttach(Activity activity) {\r
+        super.onAttach(activity);\r
+        try {\r
+            mContainerActivity = (ContainerActivity) activity;\r
+        } catch (ClassCastException e) {\r
+            throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");\r
+        }\r
+    }\r
+    \r
+    \r
+    @Override\r
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
+            Bundle savedInstanceState) {\r
+        Log.i(getClass().toString(), "onCreateView() start");\r
+        super.onCreateView(inflater, container, savedInstanceState);\r
+        getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));\r
+        getListView().setDividerHeight(1);\r
+        \r
+        Log.i(getClass().toString(), "onCreateView() end");\r
+        return getListView();\r
+    }    \r
+\r
+\r
+    @Override\r
+    public void onActivityCreated(Bundle savedInstanceState) {\r
+        Log.i(getClass().toString(), "onActivityCreated() start");\r
+        \r
+        super.onCreate(savedInstanceState);\r
+        //mAdapter = new FileListListAdapter();\r
+        \r
+        Log.i(getClass().toString(), "onActivityCreated() stop");\r
+    }\r
+    \r
+    \r
+    @Override\r
+    public void onItemClick(AdapterView<?> l, View v, int position, long id) {\r
+        OCFile file = (OCFile) mAdapter.getItem(position);\r
+        if (file != null) {\r
+            /// Click on a directory\r
+            if (file.getMimetype().equals("DIR")) {\r
+                // just local updates\r
+                mFile = file;\r
+                listDirectory(file);\r
+                // any other updates are let to the container Activity\r
+                mContainerActivity.onDirectoryClick(file);\r
+            \r
+            } else {    /// Click on a file\r
+                mContainerActivity.onFileClick(file);\r
+            }\r
+            \r
+        } else {\r
+            Log.d(TAG, "Null object in ListAdapter!!");\r
+        }\r
+        \r
+    }\r
+\r
+    /**\r
+     * Call this, when the user presses the up button\r
+     */\r
+    public void onNavigateUp() {\r
+        OCFile parentDir = null;\r
+        \r
+        if(mFile != null){\r
+            DataStorageManager storageManager = mContainerActivity.getStorageManager();\r
+            parentDir = storageManager.getFileById(mFile.getParentId());\r
+            mFile = parentDir;\r
+        }\r
+        listDirectory(parentDir);\r
+    }\r
+\r
+    /**\r
+     * Use this to query the {@link OCFile} that is currently\r
+     * being displayed by this fragment\r
+     * @return The currently viewed OCFile\r
+     */\r
+    public OCFile getCurrentFile(){\r
+        return mFile;\r
+    }\r
+    \r
+    /**\r
+     * Calls {@link FileListFragment#listDirectory(OCFile)} with a null parameter\r
+     */\r
+    public void listDirectory(){\r
+        listDirectory(null);\r
+    }\r
+    \r
+    /**\r
+     * Lists the given directory on the view. When the input parameter is null,\r
+     * it will either refresh the last known directory, or list the root\r
+     * if there never was a directory.\r
+     * \r
+     * @param directory File to be listed\r
+     */\r
+    public void listDirectory(OCFile directory) {\r
+        \r
+        DataStorageManager storageManager = mContainerActivity.getStorageManager();\r
+\r
+        // Check input parameters for null\r
+        if(directory == null){\r
+            if(mFile != null){\r
+                directory = mFile;\r
+            } else {\r
+                directory = storageManager.getFileByPath("/");\r
+                if (directory == null) return; // no files, wait for sync\r
+            }\r
+        }\r
+        \r
+        \r
+        // If that's not a directory -> List its parent\r
+        if(!directory.isDirectory()){\r
+            Log.w(TAG, "You see, that is not a directory -> " + directory.toString());\r
+            directory = storageManager.getFileById(directory.getParentId());\r
+        }\r
+\r
+        mFile = directory;\r
+        \r
+        mAdapter = new FileListListAdapter(directory, storageManager, getActivity());\r
+        setListAdapter(mAdapter);\r
+    }\r
+    \r
+    \r
+    \r
+    /**\r
+     * Interface to implement by any Activity that includes some instance of FileListFragment\r
+     * \r
+     * @author David A. Velasco\r
+     */\r
+    public interface ContainerActivity {\r
+\r
+        /**\r
+         * Callback method invoked when a directory is clicked by the user on the files list\r
+         *  \r
+         * @param file\r
+         */\r
+        public void onDirectoryClick(OCFile file);\r
+        \r
+        /**\r
+         * Callback method invoked when a file (non directory) is clicked by the user on the files list\r
+         *  \r
+         * @param file\r
+         */\r
+        public void onFileClick(OCFile file);\r
+\r
+        /**\r
+         * Getter for the current DataStorageManager in the container activity\r
+         */\r
+        public DataStorageManager getStorageManager();\r
+        \r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/ui/fragment/LandingPageFragment.java b/src/com/owncloud/android/ui/fragment/LandingPageFragment.java
new file mode 100644 (file)
index 0000000..a021afb
--- /dev/null
@@ -0,0 +1,58 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package com.owncloud.android.ui.fragment;\r
+\r
+import com.actionbarsherlock.app.SherlockFragment;\r
+import com.owncloud.android.ui.activity.LandingActivity;\r
+import com.owncloud.android.ui.adapter.LandingScreenAdapter;\r
+\r
+import android.os.Bundle;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.ListView;\r
+import com.owncloud.android.R;\r
+\r
+/**\r
+ * Used on the Landing page to display what Components of the ownCloud there\r
+ * are. Like Files, Music, Contacts, etc.\r
+ * \r
+ * @author Lennart Rosam\r
+ * \r
+ */\r
+public class LandingPageFragment extends SherlockFragment {\r
+\r
+    @Override\r
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
+            Bundle savedInstanceState) {\r
+        View root = inflater.inflate(R.layout.landing_page_fragment, container);\r
+        return root;\r
+    }\r
+\r
+    @Override\r
+    public void onActivityCreated(Bundle savedInstanceState) {\r
+        super.onActivityCreated(savedInstanceState);\r
+\r
+        ListView landingScreenItems = (ListView) getView().findViewById(\r
+                R.id.homeScreenList);\r
+        landingScreenItems.setAdapter(new LandingScreenAdapter(getActivity()));\r
+        landingScreenItems\r
+                .setOnItemClickListener((LandingActivity) getActivity());\r
+    }\r
+\r
+}\r
diff --git a/src/com/owncloud/android/utils/OwnCloudVersion.java b/src/com/owncloud/android/utils/OwnCloudVersion.java
new file mode 100644 (file)
index 0000000..b96a9df
--- /dev/null
@@ -0,0 +1,83 @@
+/* ownCloud Android client application
+ *   Copyright (C) 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 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.utils;
+
+public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
+    public static final OwnCloudVersion owncloud_v1 = new OwnCloudVersion(
+            0x010000);
+    public static final OwnCloudVersion owncloud_v2 = new OwnCloudVersion(
+            0x020000);
+    public static final OwnCloudVersion owncloud_v3 = new OwnCloudVersion(
+            0x030000);
+    public static final OwnCloudVersion owncloud_v4 = new OwnCloudVersion(
+            0x040000);
+
+    // format is in version
+    // 0xAABBCC
+    // for version AA.BB.CC
+    // ie version 3.0.3 will be stored as 0x030003
+    private int mVersion;
+    private boolean mIsValid;
+
+    public OwnCloudVersion(int version) {
+        mVersion = version;
+        mIsValid = true;
+    }
+
+    public OwnCloudVersion(String version) {
+        mVersion = 0;
+        mIsValid = false;
+        parseVersionString(version);
+    }
+
+    public String toString() {
+        return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "."
+                + ((mVersion) % 256);
+    }
+
+    public boolean isVersionValid() {
+        return mIsValid;
+    }
+
+    @Override
+    public int compareTo(OwnCloudVersion another) {
+        return another.mVersion == mVersion ? 0
+                : another.mVersion < mVersion ? 1 : -1;
+    }
+
+    private void parseVersionString(String version) {
+        try {
+            String[] nums = version.split("\\.");
+            if (nums.length > 0) {
+                mVersion += Integer.parseInt(nums[0]);
+            }
+            mVersion = mVersion << 8;
+            if (nums.length > 1) {
+                mVersion += Integer.parseInt(nums[1]);
+            }
+            mVersion = mVersion << 8;
+            if (nums.length > 2) {
+                mVersion += Integer.parseInt(nums[2]);
+            }
+            mIsValid = true;
+        } catch (Exception e) {
+            mIsValid = false;
+        }
+    }
+}
diff --git a/src/com/owncloud/android/widgets/ActionEditText.java b/src/com/owncloud/android/widgets/ActionEditText.java
new file mode 100644 (file)
index 0000000..be3abfb
--- /dev/null
@@ -0,0 +1,127 @@
+package com.owncloud.android.widgets;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import com.owncloud.android.R;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.EditText;
+
+public class ActionEditText extends EditText {
+    private String s;
+    private String optionOneString;
+    private int optionOneColor;
+    private String optionTwoString;
+    private int optionTwoColor;
+    private Rect mTextBounds, mButtonRect;
+
+    private String badgeClickCallback;
+    private Rect btn_rect;
+
+    public ActionEditText(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        getAttrs(attrs);
+        s = optionOneString;
+        mTextBounds = new Rect();
+        mButtonRect = new Rect();
+    }
+
+    public ActionEditText(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        getAttrs(attrs);
+        s = optionOneString;
+        mTextBounds = new Rect();
+        mButtonRect = new Rect();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        Paint p = getPaint();
+
+        p.getTextBounds(s, 0, s.length(), mTextBounds);
+
+        getDrawingRect(mButtonRect);
+        mButtonRect.top += 10;
+        mButtonRect.bottom -= 10;
+        mButtonRect.left = (int) (getWidth() - mTextBounds.width() - 18);
+        mButtonRect.right = getWidth() - 10;
+        btn_rect = mButtonRect;
+
+        if (s.equals(optionOneString))
+            p.setColor(optionOneColor);
+        else
+            p.setColor(optionTwoColor);
+        canvas.drawRect(mButtonRect, p);
+        p.setColor(Color.GRAY);
+
+        canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom
+                - (mTextBounds.height() / 2), p);
+
+        invalidate();
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        int touchX = (int) event.getX();
+        int touchY = (int) event.getY();
+        boolean r = super.onTouchEvent(event);
+        if (event.getAction() == MotionEvent.ACTION_UP) {
+            if (btn_rect.contains(touchX, touchY)) {
+                if (s.equals(optionTwoString))
+                    s = optionOneString;
+                else
+                    s = optionTwoString;
+                if (badgeClickCallback != null) {
+                    @SuppressWarnings("rawtypes")
+                    Class[] paramtypes = new Class[2];
+                    paramtypes[0] = android.view.View.class;
+                    paramtypes[1] = String.class;
+                    Method method;
+                    try {
+
+                        method = getContext().getClass().getMethod(
+                                badgeClickCallback, paramtypes);
+                        method.invoke(getContext(), this, s);
+
+                    } catch (NoSuchMethodException e) {
+                        e.printStackTrace();
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    } catch (IllegalAccessException e) {
+                        e.printStackTrace();
+                    } catch (InvocationTargetException e) {
+                        e.printStackTrace();
+                    }
+
+                    invalidate();
+                }
+            }
+        }
+        return r;
+    }
+
+    private void getAttrs(AttributeSet attr) {
+        TypedArray a = getContext().obtainStyledAttributes(attr,
+                R.styleable.ActionEditText);
+        optionOneString = a
+                .getString(R.styleable.ActionEditText_optionOneString);
+        optionTwoString = a
+                .getString(R.styleable.ActionEditText_optionTwoString);
+        optionOneColor = a.getColor(R.styleable.ActionEditText_optionOneColor,
+                0x00ff00);
+        optionTwoColor = a.getColor(R.styleable.ActionEditText_optionTwoColor,
+                0xff0000);
+        badgeClickCallback = a
+                .getString(R.styleable.ActionEditText_onBadgeClick);
+    }
+
+}
diff --git a/src/eu/alefzero/owncloud/AccountUtils.java b/src/eu/alefzero/owncloud/AccountUtils.java
deleted file mode 100644 (file)
index d088d2c..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2012  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud;\r
-\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.utils.OwnCloudVersion;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.content.Context;\r
-import android.content.SharedPreferences;\r
-import android.preference.PreferenceManager;\r
-\r
-public class AccountUtils {\r
-    public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";\r
-    public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";\r
-    public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";\r
-    public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";\r
-    public static final String CARDDAV_PATH_4_0 = "/remote/carddav.php";\r
-    public static final String STATUS_PATH = "/status.php";\r
-\r
-    /**\r
-     * Can be used to get the currently selected ownCloud account in the\r
-     * preferences\r
-     * \r
-     * @param context The current appContext\r
-     * @return The current account or first available, if none is available,\r
-     *         then null.\r
-     */\r
-    public static Account getCurrentOwnCloudAccount(Context context) {\r
-        Account[] ocAccounts = AccountManager.get(context).getAccountsByType(\r
-                AccountAuthenticator.ACCOUNT_TYPE);\r
-        Account defaultAccount = null;\r
-\r
-        SharedPreferences appPreferences = PreferenceManager\r
-                .getDefaultSharedPreferences(context);\r
-        String accountName = appPreferences\r
-                .getString("select_oc_account", null);\r
-\r
-        if (accountName != null) {\r
-            for (Account account : ocAccounts) {\r
-                if (account.name.equals(accountName)) {\r
-                    defaultAccount = account;\r
-                    break;\r
-                }\r
-            }\r
-        } else if (ocAccounts.length != 0) {\r
-            // we at least need to take first account as fallback\r
-            defaultAccount = ocAccounts[0];\r
-        }\r
-\r
-        return defaultAccount;\r
-    }\r
-\r
-    \r
-\r
-    /**\r
-     * Checks, whether or not there are any ownCloud accounts setup.\r
-     * \r
-     * @return true, if there is at least one account.\r
-     */\r
-    public static boolean accountsAreSetup(Context context) {\r
-        AccountManager accMan = AccountManager.get(context);\r
-        Account[] accounts = accMan\r
-                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
-        return accounts.length > 0;\r
-    }\r
-    \r
-    \r
-    public static void setCurrentOwnCloudAccount(Context context, String name) {\r
-        SharedPreferences.Editor appPrefs = PreferenceManager\r
-                .getDefaultSharedPreferences(context).edit();\r
-        appPrefs.putString("select_oc_account", name);\r
-        appPrefs.commit();\r
-    }\r
-\r
-    /**\r
-     * \r
-     * @param version version of owncloud\r
-     * @return webdav path for given OC version, null if OC version unknown\r
-     */\r
-    public static String getWebdavPath(OwnCloudVersion version) {\r
-        if (version.compareTo(OwnCloudVersion.owncloud_v4) >= 0)\r
-            return WEBDAV_PATH_4_0;\r
-        if (version.compareTo(OwnCloudVersion.owncloud_v3) >= 0\r
-                || version.compareTo(OwnCloudVersion.owncloud_v2) >= 0)\r
-            return WEBDAV_PATH_2_0;\r
-        if (version.compareTo(OwnCloudVersion.owncloud_v1) >= 0)\r
-            return WEBDAV_PATH_1_2;\r
-        return null;\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/CrashHandler.java b/src/eu/alefzero/owncloud/CrashHandler.java
deleted file mode 100644 (file)
index 99cd044..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.InputStreamReader;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.LinkedList;
-import java.util.List;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.net.ConnectivityManager;
-import android.os.Environment;
-import android.util.Log;
-
-public class CrashHandler implements UncaughtExceptionHandler {
-
-    public static final String KEY_CRASH_FILENAME = "KEY_CRASH_FILENAME";
-    
-    private Context mContext;
-    private static final String TAG = "CrashHandler";
-    private static final String crash_filename_template = "crash";
-    private static List<String> TAGS;
-    private UncaughtExceptionHandler defaultUEH;
-    
-    // TODO: create base activity which will register for crashlog tag automaticly
-    static {
-        TAGS = new LinkedList<String>();
-        TAGS.add("AccountAuthenticator");
-        TAGS.add("AccountAuthenticator");
-        TAGS.add("ConnectionCheckerRunnable");
-        TAGS.add("EasySSLSocketFactory");
-        TAGS.add("FileDataStorageManager");
-        TAGS.add("PhotoTakenBroadcastReceiver");
-        TAGS.add("InstantUploadService");
-        TAGS.add("FileDownloader");
-        TAGS.add("FileUploader");
-        TAGS.add("LocationUpdateService");
-        TAGS.add("FileSyncAdapter");
-        TAGS.add("AuthActivity");
-        TAGS.add("OwnCloudPreferences");
-        TAGS.add("FileDetailFragment");
-        TAGS.add("FileListFragment");
-        TAGS.add("ownCloudUploader");
-        TAGS.add("WebdavClient");
-    }
-    
-    public CrashHandler(Context context) {
-        mContext = context;
-        defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
-    }
-    
-    @Override
-    public void uncaughtException(Thread thread, Throwable ex) {
-        final Writer writer = new StringWriter();
-        final PrintWriter printwriter = new PrintWriter(writer);
-        ex.printStackTrace(printwriter);
-        final String startrace = writer.toString();
-        printwriter.close();
-        File ocdir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), "owncloud");
-        ocdir.mkdirs();
-
-        String crash_filename = crash_filename_template + System.currentTimeMillis() + ".txt";
-        File crashfile = new File(ocdir, crash_filename);
-        try {
-            PackageInfo pi = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0);
-            ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-            String header = String.format("Model: %s, SDK: %d, Current net: %s AppVersion: %s\n\n",
-                                          android.os.Build.MODEL,
-                                          android.os.Build.VERSION.SDK_INT,
-                                          cm.getActiveNetworkInfo() != null ? cm.getActiveNetworkInfo().getTypeName() : "NONE",
-                                          pi.versionName);
-            Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
-            AccountManager am = AccountManager.get(mContext);
-            String header2 = String.format("Account: %s, OCUrl: %s, OCVersion: %s\n\n",
-                                           account.name,
-                                           am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL),
-                                           am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));
-            
-            crashfile.createNewFile();
-            FileWriter fw = new FileWriter(crashfile);
-            fw.write(header);
-            fw.write(header2);
-            fw.write(startrace);
-            fw.write("\n\n");
-            
-            String logcat = "logcat -d *:S ";
-            
-            for (String s : TAGS)
-                logcat += s + ":V ";
-            
-            Process process = Runtime.getRuntime().exec(logcat);
-            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
-            String logline;
-            while ((logline = br.readLine()) != null)
-                fw.write(logline+"\n");
-            
-            br.close();
-            fw.close();
-            
-            Intent dataintent = new Intent(mContext, CrashlogSendActivity.class);
-            dataintent.putExtra(KEY_CRASH_FILENAME, crashfile.getAbsolutePath());
-            PendingIntent intent;
-            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
-                intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            } else {
-                intent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, dataintent, Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            }
-            AlarmManager mngr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-            if (mngr == null) {
-                Log.e(TAG, "Couldn't retrieve alarm manager!");
-                defaultUEH.uncaughtException(thread, ex);
-                return;
-            }
-            mngr.set(AlarmManager.RTC, System.currentTimeMillis(), intent);
-            System.exit(2);
-        } catch (Exception e1) {
-            Log.e(TAG, "Crash handler failed!");
-            Log.e(TAG, e1.toString());
-            defaultUEH.uncaughtException(thread, ex);
-            return;
-        }
-    }
-}
diff --git a/src/eu/alefzero/owncloud/CrashlogSendActivity.java b/src/eu/alefzero/owncloud/CrashlogSendActivity.java
deleted file mode 100644 (file)
index 9ff83f6..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.multipart.FilePart;
-import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
-import org.apache.commons.httpclient.methods.multipart.Part;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.actionbarsherlock.app.SherlockActivity;
-
-import eu.alefzero.webdav.FileRequestEntity;
-
-public class CrashlogSendActivity extends SherlockActivity implements OnClickListener, OnCancelListener {
-    
-    private static final String TAG = "CrashlogSendActivity";
-    private static final String CRASHLOG_SUBMIT_URL = "http://alefzero.eu/a/crashlog/";
-    private static final int DIALOG_SUBMIT = 5;
-    
-    private String mLogFilename;
-    
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mLogFilename = getIntent().getStringExtra(CrashHandler.KEY_CRASH_FILENAME);
-        if (mLogFilename == null) {
-            Log.wtf(TAG, "No file crashlog path given!");
-            finish();
-            return;
-        }
-        Log.i(TAG, "crashlog file path " + mLogFilename);
-        
-        showDialog(DIALOG_SUBMIT);
-    }
-    
-
-    @Override
-    protected Dialog onCreateDialog(int id) {
-        if (id == DIALOG_SUBMIT) {
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setMessage(R.string.crashlog_message);
-            builder.setNegativeButton(R.string.crashlog_dont_send_report, this);
-            builder.setPositiveButton(R.string.crashlog_send_report, this);
-            builder.setCancelable(true);
-            builder.setOnCancelListener(this);
-            return builder.create();
-        }
-        return super.onCreateDialog(id);
-    }
-
-
-    @Override
-    public void onClick(DialogInterface dialog, final int which) {
-        new Thread(new Runnable() {
-            
-            @Override
-            public void run() {
-                // TODO Auto-generated method stub
-                File file = new File(mLogFilename);
-                if (which == Dialog.BUTTON_POSITIVE) {
-                    try {
-                        HttpClient client = new HttpClient();
-                        PostMethod post = new PostMethod(CRASHLOG_SUBMIT_URL);
-                        Part[] parts = {new FilePart("crashfile", file)};
-                        post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
-                        client.executeMethod(post);
-                        post.releaseConnection();
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-                file.delete();
-                finish();                
-            }
-        }).start();
-    }
-
-
-    @Override
-    public void onCancel(DialogInterface dialog) {
-        new File(mLogFilename).delete();
-        finish();
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/DisplayUtils.java b/src/eu/alefzero/owncloud/DisplayUtils.java
deleted file mode 100644 (file)
index 3e9f778..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud;\r
-\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-\r
-/**\r
- * A helper class for some string operations.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class DisplayUtils {\r
-\r
-    private static final String[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };\r
-\r
-    private static HashMap<String, String> mimeType2HUmanReadable;\r
-    static {\r
-        mimeType2HUmanReadable = new HashMap<String, String>();\r
-        // images\r
-        mimeType2HUmanReadable.put("image/jpeg", "JPEG image");\r
-        mimeType2HUmanReadable.put("image/jpg", "JPEG image");\r
-        mimeType2HUmanReadable.put("image/png", "PNG image");\r
-        mimeType2HUmanReadable.put("image/bmp", "Bitmap image");\r
-        mimeType2HUmanReadable.put("image/gif", "GIF image");\r
-        mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");\r
-        mimeType2HUmanReadable.put("image/tiff", "TIFF image");\r
-        // music\r
-        mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");\r
-        mimeType2HUmanReadable.put("application/ogg", "OGG music file");\r
-\r
-    }\r
-\r
-    /**\r
-     * Converts the file size in bytes to human readable output.\r
-     * \r
-     * @param bytes Input file size\r
-     * @return Like something readable like "12 MB"\r
-     */\r
-    public static String bytesToHumanReadable(long bytes) {\r
-        double result = bytes;\r
-        int attachedsuff = 0;\r
-        while (result > 1024 && attachedsuff < suffixes.length) {\r
-            result /= 1024.;\r
-            attachedsuff++;\r
-        }\r
-        result = ((int) (result * 100)) / 100.;\r
-        return result + " " + suffixes[attachedsuff];\r
-    }\r
-\r
-    /**\r
-     * Removes special HTML entities from a string\r
-     * \r
-     * @param s Input string\r
-     * @return A cleaned version of the string\r
-     */\r
-    public static String HtmlDecode(String s) {\r
-        /*\r
-         * TODO: Perhaps we should use something more proven like:\r
-         * http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/StringEscapeUtils.html#unescapeHtml%28java.lang.String%29\r
-         */\r
-\r
-        String ret = "";\r
-        for (int i = 0; i < s.length(); ++i) {\r
-            if (s.charAt(i) == '%') {\r
-                ret += (char) Integer.parseInt(s.substring(i + 1, i + 3), 16);\r
-                i += 2;\r
-            } else {\r
-                ret += s.charAt(i);\r
-            }\r
-        }\r
-        return ret;\r
-    }\r
-\r
-    /**\r
-     * Converts MIME types like "image/jpg" to more end user friendly output\r
-     * like "JPG image".\r
-     * \r
-     * @param mimetype MIME type to convert\r
-     * @return A human friendly version of the MIME type\r
-     */\r
-    public static String convertMIMEtoPrettyPrint(String mimetype) {\r
-        if (mimeType2HUmanReadable.containsKey(mimetype)) {\r
-            return mimeType2HUmanReadable.get(mimetype);\r
-        }\r
-        if (mimetype.split("/").length >= 2)\r
-            return mimetype.split("/")[1].toUpperCase() + " file";\r
-        return "Unknown type";\r
-    }\r
-\r
-    /**\r
-     * Converts Unix time to human readable format\r
-     * @param miliseconds that have passed since 01/01/1970\r
-     * @return The human readable time for the users locale\r
-     */\r
-    public static String unixTimeToHumanReadable(long milliseconds) {\r
-        Date date = new Date(milliseconds);\r
-        return date.toLocaleString();\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/OwnCloudSession.java b/src/eu/alefzero/owncloud/OwnCloudSession.java
deleted file mode 100644 (file)
index 0a090d6..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud;\r
-\r
-/**\r
- * Represents a session to an ownCloud instance\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class OwnCloudSession {\r
-    private String mSessionName;\r
-    private String mSessionUrl;\r
-    private int mEntryId;\r
-\r
-    public OwnCloudSession(String name, String url, int entryId) {\r
-        mSessionName = name;\r
-        mSessionUrl = url;\r
-        mEntryId = entryId;\r
-    }\r
-\r
-    public void setName(String name) {\r
-        mSessionName = name;\r
-    }\r
-\r
-    public String getName() {\r
-        return mSessionName;\r
-    }\r
-\r
-    public void setUrl(String url) {\r
-        mSessionUrl = url;\r
-    }\r
-\r
-    public String getUrl() {\r
-        return mSessionUrl;\r
-    }\r
-\r
-    public int getEntryId() {\r
-        return mEntryId;\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/Uploader.java b/src/eu/alefzero/owncloud/Uploader.java
deleted file mode 100644 (file)
index 523db94..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2012  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud;\r
-\r
-import java.io.File;\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.LinkedList;\r
-import java.util.List;\r
-import java.util.Stack;\r
-import java.util.Vector;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.app.AlertDialog;\r
-import android.app.AlertDialog.Builder;\r
-import android.app.Dialog;\r
-import android.app.ListActivity;\r
-import android.app.ProgressDialog;\r
-import android.content.Context;\r
-import android.content.DialogInterface;\r
-import android.content.DialogInterface.OnCancelListener;\r
-import android.content.DialogInterface.OnClickListener;\r
-import android.content.Intent;\r
-import android.database.Cursor;\r
-import android.net.Uri;\r
-import android.os.Bundle;\r
-import android.os.Parcelable;\r
-import android.provider.MediaStore.Images.Media;\r
-import android.util.Log;\r
-import android.view.View;\r
-import android.view.Window;\r
-import android.widget.AdapterView;\r
-import android.widget.AdapterView.OnItemClickListener;\r
-import android.widget.Button;\r
-import android.widget.EditText;\r
-import android.widget.SimpleAdapter;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.datamodel.DataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.files.services.FileUploader;\r
-import eu.alefzero.webdav.WebdavClient;\r
-\r
-/**\r
- * This can be used to upload things to an ownCloud instance.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {\r
-    private static final String TAG = "ownCloudUploader";\r
-\r
-    private Account mAccount;\r
-    private AccountManager mAccountManager;\r
-    private Stack<String> mParents;\r
-    private ArrayList<Parcelable> mStreamsToUpload;\r
-    private boolean mCreateDir;\r
-    private String mUploadPath;\r
-    private static final String[] CONTENT_PROJECTION = { Media.DATA, Media.DISPLAY_NAME, Media.MIME_TYPE, Media.SIZE };\r
-    private DataStorageManager mStorageManager;\r
-    private OCFile mFile;\r
-\r
-    private final static int DIALOG_NO_ACCOUNT = 0;\r
-    private final static int DIALOG_WAITING = 1;\r
-    private final static int DIALOG_NO_STREAM = 2;\r
-    private final static int DIALOG_MULTIPLE_ACCOUNT = 3;\r
-    private final static int DIALOG_GET_DIRNAME = 4;\r
-\r
-    private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
-        mParents = new Stack<String>();\r
-        mParents.add("");\r
-        if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {\r
-            prepareStreamsToUpload();\r
-            mAccountManager = (AccountManager) getSystemService(Context.ACCOUNT_SERVICE);\r
-            Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
-            if (accounts.length == 0) {\r
-                Log.i(TAG, "No ownCloud account is available");\r
-                showDialog(DIALOG_NO_ACCOUNT);\r
-            } else if (accounts.length > 1) {\r
-                Log.i(TAG, "More then one ownCloud is available");\r
-                showDialog(DIALOG_MULTIPLE_ACCOUNT);\r
-            } else {\r
-                mAccount = accounts[0];\r
-                setContentView(R.layout.uploader_layout);\r
-                mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());\r
-                populateDirectoryList();\r
-            }\r
-        } else {\r
-            showDialog(DIALOG_NO_STREAM);\r
-        }\r
-    }\r
-    \r
-    @Override\r
-    protected Dialog onCreateDialog(final int id) {\r
-        final AlertDialog.Builder builder = new Builder(this);\r
-        switch (id) {\r
-        case DIALOG_WAITING:\r
-            ProgressDialog pDialog = new ProgressDialog(this);\r
-            pDialog.setIndeterminate(false);\r
-            pDialog.setCancelable(false);\r
-            pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));\r
-            return pDialog;\r
-        case DIALOG_NO_ACCOUNT:\r
-            builder.setIcon(android.R.drawable.ic_dialog_alert);\r
-            builder.setTitle(R.string.uploader_wrn_no_account_title);\r
-            builder.setMessage(R.string.uploader_wrn_no_account_text);\r
-            builder.setCancelable(false);\r
-            builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {\r
-                public void onClick(DialogInterface dialog, int which) {\r
-                    if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {\r
-                        // using string value since in API7 this\r
-                        // constatn is not defined\r
-                        // in API7 < this constatant is defined in\r
-                        // Settings.ADD_ACCOUNT_SETTINGS\r
-                        // and Settings.EXTRA_AUTHORITIES\r
-                        Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
-                        intent.putExtra("authorities", new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
-                        startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);\r
-                    } else {\r
-                        // since in API7 there is no direct call for\r
-                        // account setup, so we need to\r
-                        // show our own AccountSetupAcricity, get\r
-                        // desired results and setup\r
-                        // everything for ourself\r
-                        Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);\r
-                        startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);\r
-                    }\r
-                }\r
-            });\r
-            builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {\r
-                public void onClick(DialogInterface dialog, int which) {\r
-                    finish();\r
-                }\r
-            });\r
-            return builder.create();\r
-        /*case DIALOG_GET_DIRNAME:\r
-            final EditText dirName = new EditText(getBaseContext());\r
-            builder.setView(dirName);\r
-            builder.setTitle(R.string.uploader_info_dirname);\r
-            String pathToUpload;\r
-            if (mParents.empty()) {\r
-                pathToUpload = "/";\r
-            } else {\r
-                mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), null,\r
-                        null, null, null);\r
-                mCursor.moveToFirst();\r
-                pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH))\r
-                        + mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");   // TODO don't make this ; use WebdavUtils.encode in the right moment\r
-            }\r
-            a a = new a(pathToUpload, dirName);\r
-            builder.setPositiveButton(R.string.common_ok, a);\r
-            builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {\r
-                public void onClick(DialogInterface dialog, int which) {\r
-                    dialog.cancel();\r
-                }\r
-            });\r
-            return builder.create();*/\r
-        case DIALOG_MULTIPLE_ACCOUNT:\r
-            CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];\r
-            for (int i = 0; i < ac.length; ++i) {\r
-                ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;\r
-            }\r
-            builder.setTitle(R.string.common_choose_account);\r
-            builder.setItems(ac, new OnClickListener() {\r
-                public void onClick(DialogInterface dialog, int which) {\r
-                    mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];\r
-                    mStorageManager = new FileDataStorageManager(mAccount, getContentResolver());\r
-                    populateDirectoryList();\r
-                }\r
-            });\r
-            builder.setCancelable(true);\r
-            builder.setOnCancelListener(new OnCancelListener() {\r
-                public void onCancel(DialogInterface dialog) {\r
-                    dialog.cancel();\r
-                    finish();\r
-                }\r
-            });\r
-            return builder.create();\r
-        default:\r
-            throw new IllegalArgumentException("Unknown dialog id: " + id);\r
-        }\r
-    }\r
-\r
-    class a implements OnClickListener {\r
-        String mPath;\r
-        EditText mDirname;\r
-\r
-        public a(String path, EditText dirname) {\r
-            mPath = path; \r
-            mDirname = dirname;\r
-        }\r
-\r
-        public void onClick(DialogInterface dialog, int which) {\r
-            Uploader.this.mUploadPath = mPath + mDirname.getText().toString();\r
-            Uploader.this.mCreateDir = true;\r
-            uploadFiles();\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void onBackPressed() {\r
-\r
-        if (mParents.size() <= 1) {\r
-            super.onBackPressed();\r
-            return;\r
-        } else {\r
-            mParents.pop();\r
-            populateDirectoryList();\r
-        }\r
-    }\r
-\r
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\r
-        // click on folder in the list\r
-        Log.d(TAG, "on item click");\r
-        Vector<OCFile> tmpfiles = mStorageManager.getDirectoryContent(mFile);\r
-        if (tmpfiles == null) return;\r
-        // filter on dirtype\r
-        Vector<OCFile> files = new Vector<OCFile>();\r
-        for (OCFile f : tmpfiles)\r
-            if (f.isDirectory())\r
-                files.add(f);\r
-        if (files.size() < position) {\r
-            throw new IndexOutOfBoundsException("Incorrect item selected");\r
-        }\r
-        mParents.push(files.get(position).getFileName());\r
-        populateDirectoryList();\r
-    }\r
-\r
-    public void onClick(View v) {\r
-        // click on button\r
-        switch (v.getId()) {\r
-        case R.id.uploader_choose_folder:\r
-            mUploadPath = "";   // first element in mParents is root dir, represented by ""; init mUploadPath with "/" results in a "//" prefix\r
-            for (String p : mParents)\r
-                mUploadPath += p + OCFile.PATH_SEPARATOR;\r
-            Log.d(TAG, "Uploading file to dir " + mUploadPath);\r
-\r
-            uploadFiles();\r
-\r
-            break;\r
-        case android.R.id.button1: // dynamic action for create aditional dir\r
-            showDialog(DIALOG_GET_DIRNAME);\r
-            break;\r
-        default:\r
-            throw new IllegalArgumentException("Wrong element clicked");\r
-        }\r
-    }\r
-\r
-    @Override\r
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
-        super.onActivityResult(requestCode, resultCode, data);\r
-        Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);\r
-        if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {\r
-            dismissDialog(DIALOG_NO_ACCOUNT);\r
-            if (resultCode == RESULT_CANCELED) {\r
-                finish();\r
-            }\r
-            Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);\r
-            if (accounts.length == 0) {\r
-                showDialog(DIALOG_NO_ACCOUNT);\r
-            } else {\r
-                // there is no need for checking for is there more then one\r
-                // account at this point\r
-                // since account setup can set only one account at time\r
-                mAccount = accounts[0];\r
-                populateDirectoryList();\r
-            }\r
-        }\r
-    }\r
-\r
-    private void populateDirectoryList() {\r
-        setContentView(R.layout.uploader_layout);\r
-\r
-        String full_path = "";\r
-        for (String a : mParents)\r
-            full_path += a + "/";\r
-        \r
-        Log.d(TAG, "Populating view with content of : " + full_path);\r
-        \r
-        mFile = mStorageManager.getFileByPath(full_path);\r
-        if (mFile != null) {\r
-            Vector<OCFile> files = mStorageManager.getDirectoryContent(mFile);\r
-            if (files != null) {\r
-                List<HashMap<String, Object>> data = new LinkedList<HashMap<String,Object>>();\r
-                for (OCFile f : files) {\r
-                    HashMap<String, Object> h = new HashMap<String, Object>();\r
-                    if (f.isDirectory()) {\r
-                        h.put("dirname", f.getFileName());\r
-                        data.add(h);\r
-                    }\r
-                }\r
-                SimpleAdapter sa = new SimpleAdapter(this,\r
-                                                     data,\r
-                                                     R.layout.uploader_list_item_layout,\r
-                                                     new String[] {"dirname"},\r
-                                                     new int[] {R.id.textView1});\r
-                setListAdapter(sa);\r
-                Button btn = (Button) findViewById(R.id.uploader_choose_folder);\r
-                btn.setOnClickListener(this);\r
-                getListView().setOnItemClickListener(this);\r
-            }\r
-        }\r
-        /*\r
-        mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI, null, ProviderTableMeta.FILE_NAME\r
-                + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?", new String[] { "/", mAccount.name }, null);\r
-\r
-        if (mCursor.moveToFirst()) {\r
-            mCursor = managedQuery(\r
-                    ProviderMeta.ProviderTableMeta.CONTENT_URI,\r
-                    null,\r
-                    ProviderTableMeta.FILE_CONTENT_TYPE + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND "\r
-                            + ProviderTableMeta.FILE_PARENT + "=?",\r
-                    new String[] { "DIR", mAccount.name,\r
-                            mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID)) }, null);\r
-\r
-            ListView lv = getListView();\r
-            lv.setOnItemClickListener(this);\r
-            SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout, mCursor,\r
-                    new String[] { ProviderTableMeta.FILE_NAME }, new int[] { R.id.textView1 });\r
-            setListAdapter(sca);\r
-            Button btn = (Button) findViewById(R.id.uploader_choose_folder);\r
-            btn.setOnClickListener(this);\r
-            /*\r
-             * disable this until new server interaction service wont be created\r
-             * // insert create new directory for multiple items uploading if\r
-             * (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {\r
-             * Button createDirBtn = new Button(this);\r
-             * createDirBtn.setId(android.R.id.button1);\r
-             * createDirBtn.setText(R.string.uploader_btn_create_dir_text);\r
-             * createDirBtn.setOnClickListener(this); ((LinearLayout)\r
-             * findViewById(R.id.linearLayout1)).addView( createDirBtn,\r
-             * LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); }\r
-             *\r
-        }*/\r
-    }\r
-\r
-    private void prepareStreamsToUpload() {\r
-        if (getIntent().getAction().equals(Intent.ACTION_SEND)) {\r
-            mStreamsToUpload = new ArrayList<Parcelable>();\r
-            mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));\r
-        } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {\r
-            mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);\r
-        } else {\r
-            // unknow action inserted\r
-            throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());\r
-        }\r
-    }\r
-\r
-    public void uploadFiles() {\r
-        WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());\r
-        wdc.allowSelfsignedCertificates();\r
-\r
-        // create last directory in path if nessesary\r
-        if (mCreateDir) {\r
-            wdc.createDirectory(mUploadPath);\r
-        }\r
-\r
-        String[] local = new String[mStreamsToUpload.size()], remote = new String[mStreamsToUpload.size()];\r
-\r
-        for (int i = 0; i < mStreamsToUpload.size(); ++i) {\r
-            Uri uri = (Uri) mStreamsToUpload.get(i);\r
-            if (uri.getScheme().equals("content")) {\r
-                Cursor c = getContentResolver().query((Uri) mStreamsToUpload.get(i),\r
-                                                      CONTENT_PROJECTION,\r
-                                                      null,\r
-                                                      null,\r
-                                                      null);\r
-\r
-                if (!c.moveToFirst())\r
-                    continue;\r
-\r
-                final String display_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),\r
-                             data = c.getString(c.getColumnIndex(Media.DATA));\r
-                local[i] = data;\r
-                remote[i] = mUploadPath + display_name;\r
-            } else if (uri.getScheme().equals("file")) {\r
-                final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme() + "://", ""));\r
-                local[i] = file.getAbsolutePath();\r
-                remote[i] = mUploadPath + file.getName();\r
-            }\r
-\r
-        }\r
-        Intent intent = new Intent(getApplicationContext(), FileUploader.class);\r
-        intent.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_MULTIPLE_FILES);\r
-        intent.putExtra(FileUploader.KEY_LOCAL_FILE, local);\r
-        intent.putExtra(FileUploader.KEY_REMOTE_FILE, remote);\r
-        intent.putExtra(FileUploader.KEY_ACCOUNT, mAccount);\r
-        startService(intent);\r
-        finish();\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java b/src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java
deleted file mode 100644 (file)
index be0b8e0..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2012  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.authenticator;\r
-\r
-import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;\r
-import android.accounts.*;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.os.Bundle;\r
-import android.util.Log;\r
-\r
-public class AccountAuthenticator extends AbstractAccountAuthenticator {\r
-    /**\r
-     * Is used by android system to assign accounts to authenticators. Should be\r
-     * used by application and all extensions.\r
-     */\r
-    public static final String ACCOUNT_TYPE = "owncloud";\r
-    public static final String AUTH_TOKEN_TYPE = "org.owncloud";\r
-\r
-    public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";\r
-    public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";\r
-    public static final String KEY_LOGIN_OPTIONS = "loginOptions";\r
-    public static final String KEY_ACCOUNT = "account";\r
-    /**\r
-     * Value under this key should handle path to webdav php script. Will be\r
-     * removed and usage should be replaced by combining\r
-     * {@link eu.alefzero.owncloud.authenticator.KEY_OC_BASE_URL} and\r
-     * {@link eu.alefzero.owncloud.utils.OwnCloudVersion}\r
-     * \r
-     * @deprecated\r
-     */\r
-    public static final String KEY_OC_URL = "oc_url";\r
-    /**\r
-     * Version should be 3 numbers separated by dot so it can be parsed by\r
-     * {@link eu.alefzero.owncloud.utils.OwnCloudVersion}\r
-     */\r
-    public static final String KEY_OC_VERSION = "oc_version";\r
-    /**\r
-     * Base url should point to owncloud installation without trailing / ie:\r
-     * http://server/path or https://owncloud.server\r
-     */\r
-    public static final String KEY_OC_BASE_URL = "oc_base_url";\r
-\r
-    private static final String TAG = "AccountAuthenticator";\r
-    private Context mContext;\r
-\r
-    public AccountAuthenticator(Context context) {\r
-        super(context);\r
-        mContext = context;\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public Bundle addAccount(AccountAuthenticatorResponse response,\r
-            String accountType, String authTokenType,\r
-            String[] requiredFeatures, Bundle options)\r
-            throws NetworkErrorException {\r
-        Log.i(TAG, "Adding account with type " + accountType\r
-                + " and auth token " + authTokenType);\r
-        try {\r
-            validateAccountType(accountType);\r
-        } catch (AuthenticatorException e) {\r
-            Log.e(TAG, "Failed to validate account type " + accountType + ": "\r
-                    + e.getMessage());\r
-            e.printStackTrace();\r
-            return e.getFailureBundle();\r
-        }\r
-        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
-                response);\r
-        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);\r
-        intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);\r
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
-\r
-        setIntentFlags(intent);\r
-        final Bundle bundle = new Bundle();\r
-        bundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
-        return bundle;\r
-    }\r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public Bundle confirmCredentials(AccountAuthenticatorResponse response,\r
-            Account account, Bundle options) throws NetworkErrorException {\r
-        try {\r
-            validateAccountType(account.type);\r
-        } catch (AuthenticatorException e) {\r
-            Log.e(TAG, "Failed to validate account type " + account.type + ": "\r
-                    + e.getMessage());\r
-            e.printStackTrace();\r
-            return e.getFailureBundle();\r
-        }\r
-        Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
-                response);\r
-        intent.putExtra(KEY_ACCOUNT, account);\r
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
-\r
-        setIntentFlags(intent);\r
-\r
-        Bundle resultBundle = new Bundle();\r
-        resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
-        return resultBundle;\r
-    }\r
-\r
-    @Override\r
-    public Bundle editProperties(AccountAuthenticatorResponse response,\r
-            String accountType) {\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public Bundle getAuthToken(AccountAuthenticatorResponse response,\r
-            Account account, String authTokenType, Bundle options)\r
-            throws NetworkErrorException {\r
-        try {\r
-            validateAccountType(account.type);\r
-            validateAuthTokenType(authTokenType);\r
-        } catch (AuthenticatorException e) {\r
-            Log.e(TAG, "Failed to validate account type " + account.type + ": "\r
-                    + e.getMessage());\r
-            e.printStackTrace();\r
-            return e.getFailureBundle();\r
-        }\r
-        final AccountManager am = AccountManager.get(mContext);\r
-        final String password = am.getPassword(account);\r
-        if (password != null) {\r
-            final Bundle result = new Bundle();\r
-            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);\r
-            result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);\r
-            result.putString(AccountManager.KEY_AUTHTOKEN, password);\r
-            return result;\r
-        }\r
-\r
-        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
-                response);\r
-        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);\r
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
-        intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);\r
-\r
-        final Bundle bundle = new Bundle();\r
-        bundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
-        return bundle;\r
-    }\r
-\r
-    @Override\r
-    public String getAuthTokenLabel(String authTokenType) {\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public Bundle hasFeatures(AccountAuthenticatorResponse response,\r
-            Account account, String[] features) throws NetworkErrorException {\r
-        final Bundle result = new Bundle();\r
-        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);\r
-        return result;\r
-    }\r
-\r
-    @Override\r
-    public Bundle updateCredentials(AccountAuthenticatorResponse response,\r
-            Account account, String authTokenType, Bundle options)\r
-            throws NetworkErrorException {\r
-        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,\r
-                response);\r
-        intent.putExtra(KEY_ACCOUNT, account);\r
-        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);\r
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);\r
-        setIntentFlags(intent);\r
-\r
-        final Bundle bundle = new Bundle();\r
-        bundle.putParcelable(AccountManager.KEY_INTENT, intent);\r
-        return bundle;\r
-    }\r
-\r
-    @Override\r
-    public Bundle getAccountRemovalAllowed(\r
-            AccountAuthenticatorResponse response, Account account)\r
-            throws NetworkErrorException {\r
-        return super.getAccountRemovalAllowed(response, account);\r
-    }\r
-\r
-    private void setIntentFlags(Intent intent) {\r
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\r
-        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);\r
-        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);\r
-        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);\r
-        intent.addFlags(Intent.FLAG_FROM_BACKGROUND);\r
-    }\r
-\r
-    private void validateAccountType(String type)\r
-            throws UnsupportedAccountTypeException {\r
-        if (!type.equals(ACCOUNT_TYPE)) {\r
-            throw new UnsupportedAccountTypeException();\r
-        }\r
-    }\r
-\r
-    private void validateAuthTokenType(String authTokenType)\r
-            throws UnsupportedAuthTokenTypeException {\r
-        if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {\r
-            throw new UnsupportedAuthTokenTypeException();\r
-        }\r
-    }\r
-\r
-    public static class AuthenticatorException extends Exception {\r
-        private static final long serialVersionUID = 1L;\r
-        private Bundle mFailureBundle;\r
-\r
-        public AuthenticatorException(int code, String errorMsg) {\r
-            mFailureBundle = new Bundle();\r
-            mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);\r
-            mFailureBundle\r
-                    .putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);\r
-        }\r
-\r
-        public Bundle getFailureBundle() {\r
-            return mFailureBundle;\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedAccountTypeException extends\r
-            AuthenticatorException {\r
-        private static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedAccountTypeException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
-                    "Unsupported account type");\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedAuthTokenTypeException extends\r
-            AuthenticatorException {\r
-        private static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedAuthTokenTypeException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
-                    "Unsupported auth token type");\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedFeaturesException extends\r
-            AuthenticatorException {\r
-        public static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedFeaturesException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
-                    "Unsupported features");\r
-        }\r
-    }\r
-\r
-    public static class AccessDeniedException extends AuthenticatorException {\r
-        public AccessDeniedException(int code, String errorMsg) {\r
-            super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");\r
-        }\r
-\r
-        private static final long serialVersionUID = 1L;\r
-\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/authenticator/AccountAuthenticatorService.java b/src/eu/alefzero/owncloud/authenticator/AccountAuthenticatorService.java
deleted file mode 100644 (file)
index 69e8847..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  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 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 eu.alefzero.owncloud.authenticator;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class AccountAuthenticatorService extends Service {
-
-    private AccountAuthenticator mAuthenticator;
-    static final public String ACCOUNT_TYPE = "owncloud";
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mAuthenticator = new AccountAuthenticator(this);
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mAuthenticator.getIBinder();
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java b/src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java
deleted file mode 100644 (file)
index 691c93e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.authenticator;
-
-import java.net.URL;
-
-import org.apache.commons.httpclient.HttpStatus;
-
-import eu.alefzero.webdav.WebdavClient;
-
-import android.net.Uri;
-import android.os.Handler;
-
-public class AuthenticationRunnable implements Runnable {
-
-    private OnAuthenticationResultListener mListener;
-    private Handler mHandler;
-    private URL mUrl;
-    private String mUsername;
-    private String mPassword;
-
-    public AuthenticationRunnable(URL url, String username, String password) {
-        mListener = null;
-        mUrl = url;
-        mUsername = username;
-        mPassword = password;
-    }
-
-    public void setOnAuthenticationResultListener(
-            OnAuthenticationResultListener listener, Handler handler) {
-        mListener = listener;
-        mHandler = handler;
-    }
-
-    @Override
-    public void run() {
-        Uri uri;
-        uri = Uri.parse(mUrl.toString());
-        int login_result = WebdavClient.tryToLogin(uri, mUsername, mPassword);
-        switch (login_result) {
-        case HttpStatus.SC_OK:
-            postResult(true, uri.toString());
-            break;
-        case HttpStatus.SC_UNAUTHORIZED:
-            postResult(false, "Invalid login or/and password");
-            break;
-        case HttpStatus.SC_NOT_FOUND:
-            postResult(false, "Wrong path given");
-            break;
-        default:
-            postResult(false, "Internal server error, code: " + login_result);
-        }
-    }
-
-    private void postResult(final boolean success, final String message) {
-        if (mHandler != null && mListener != null) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mListener.onAuthenticationResult(success, message);
-                }
-            });
-        }
-    }
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java b/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java
deleted file mode 100644 (file)
index 119b242..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.authenticator;
-
-import java.net.ConnectException;
-import java.net.SocketTimeoutException;
-import java.net.UnknownHostException;
-
-import javax.net.ssl.SSLHandshakeException;
-
-import org.apache.commons.httpclient.HttpStatus;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.OnConnectCheckListener.ResultType;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-import eu.alefzero.webdav.WebdavClient;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.Uri;
-import android.os.Handler;
-import android.util.Log;
-
-public class ConnectionCheckerRunnable implements Runnable {
-    
-    /** Maximum time to wait for a response from the server when the connection is being tested, in MILLISECONDs.  */
-    public static final int TRY_CONNECTION_TIMEOUT = 5000;
-    
-    private static final String TAG = "ConnectionCheckerRunnable";
-    private OnConnectCheckListener mListener;
-    private String mUrl;
-    private Handler mHandler;
-    private ResultType mLatestResult;
-    private Context mContext;
-    private OwnCloudVersion mOCVersion;
-
-    public void setListener(OnConnectCheckListener listener, Handler handler) {
-        mListener = listener;
-        mHandler = handler;
-    }
-
-    public ConnectionCheckerRunnable(String url, Context context) {
-        mListener = null;
-        mHandler = null;
-        mUrl = url;
-        mContext = context;
-        mOCVersion = null;
-    }
-
-    @Override
-    public void run() {
-
-        if (!isOnline()) {
-            postResult(ResultType.NO_NETWORK_CONNECTION);
-            return;
-        }
-        if (mUrl.startsWith("http://") || mUrl.startsWith("https://")) {
-            mLatestResult = (mUrl.startsWith("https://"))? ResultType.OK_SSL : ResultType.OK_NO_SSL;
-            tryConnection(Uri.parse(mUrl + AccountUtils.STATUS_PATH));
-            postResult(mLatestResult);
-        } else {
-            Uri uri = Uri.parse("https://" + mUrl + AccountUtils.STATUS_PATH);
-            if (tryConnection(uri)) {
-                postResult(ResultType.OK_SSL);
-                return;
-            }
-            Log.d(TAG,
-                    "establishing secure connection failed, trying non secure connection");
-            uri = Uri.parse("http://" + mUrl + AccountUtils.STATUS_PATH);
-
-            if (tryConnection(uri)) {
-                postResult(ResultType.OK_NO_SSL);
-                return;
-            }
-            postResult(mLatestResult);
-        }
-    }
-
-    public OwnCloudVersion getDiscoveredVersion() {
-        return mOCVersion;
-    }
-
-    private boolean tryConnection(Uri uri) {
-        WebdavClient wc = new WebdavClient();
-        wc.allowSelfsignedCertificates();
-        GetMethod get = new GetMethod(uri.toString());
-        boolean retval = false;
-        try {
-            int status = wc.executeMethod(get, TRY_CONNECTION_TIMEOUT);
-            switch (status) {
-            case HttpStatus.SC_OK: {
-                String response = get.getResponseBodyAsString();
-                JSONObject json = new JSONObject(response);
-                if (!json.getBoolean("installed")) {
-                    mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
-                    break;
-                }
-                mOCVersion = new OwnCloudVersion(json.getString("version"));
-                if (!mOCVersion.isVersionValid())
-                    break;
-                retval = true;
-                break;
-            }
-            case HttpStatus.SC_NOT_FOUND:
-                mLatestResult = ResultType.FILE_NOT_FOUND;
-                break;
-            case HttpStatus.SC_INTERNAL_SERVER_ERROR:
-                mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
-                break;
-            default:
-                mLatestResult = ResultType.UNKNOWN_ERROR;
-                Log.e(TAG, "Not handled status received from server: " + status);
-            }
-
-        } catch (Exception e) {
-            if (e instanceof UnknownHostException
-                    || e instanceof ConnectException 
-                    || e instanceof SocketTimeoutException) {
-                mLatestResult = ResultType.HOST_NOT_AVAILABLE;
-            } else if (e instanceof JSONException) {
-                mLatestResult = ResultType.INSTANCE_NOT_CONFIGURED;
-            } else if (e instanceof SSLHandshakeException) {
-                mLatestResult = ResultType.SSL_INIT_ERROR;
-            } else {
-                mLatestResult = ResultType.UNKNOWN_ERROR;
-            }
-            e.printStackTrace();
-        }
-
-        return retval;
-    }
-
-    private boolean isOnline() {
-        ConnectivityManager cm = (ConnectivityManager) mContext
-                .getSystemService(Context.CONNECTIVITY_SERVICE);
-        return cm != null && cm.getActiveNetworkInfo() != null
-                && cm.getActiveNetworkInfo().isConnectedOrConnecting();
-    }
-
-    private void postResult(final ResultType result) {
-        if (mHandler != null && mListener != null) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mListener.onConnectionCheckResult(result);
-                }
-            });
-        }
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java b/src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java
deleted file mode 100644 (file)
index f1de8f5..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * $HeadURL$
- * $Revision$
- * $Date$
- * 
- * ====================================================================
- *
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.UnknownHostException;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-
-import org.apache.commons.httpclient.ConnectTimeoutException;
-import org.apache.commons.httpclient.HttpClientError;
-import org.apache.commons.httpclient.params.HttpConnectionParams;
-import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
-import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
-
-import android.util.Log;
-
-/**
- * <p>
- * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s that
- * accept self-signed certificates.
- * </p>
- * <p>
- * This socket factory SHOULD NOT be used for productive systems due to security
- * reasons, unless it is a concious decision and you are perfectly aware of
- * security implications of accepting self-signed certificates
- * </p>
- * 
- * <p>
- * Example of using custom protocol socket factory for a specific host:
- * 
- * <pre>
- * Protocol easyhttps = new Protocol(&quot;https&quot;, new EasySSLProtocolSocketFactory(),
- *         443);
- * 
- * URI uri = new URI(&quot;https://localhost/&quot;, true);
- * // use relative url only
- * GetMethod httpget = new GetMethod(uri.getPathQuery());
- * HostConfiguration hc = new HostConfiguration();
- * hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
- * HttpClient client = new HttpClient();
- * client.executeMethod(hc, httpget);
- * </pre>
- * 
- * </p>
- * <p>
- * Example of using custom protocol socket factory per default instead of the
- * standard one:
- * 
- * <pre>
- * Protocol easyhttps = new Protocol(&quot;https&quot;, new EasySSLProtocolSocketFactory(),
- *         443);
- * Protocol.registerProtocol(&quot;https&quot;, easyhttps);
- * 
- * HttpClient client = new HttpClient();
- * GetMethod httpget = new GetMethod(&quot;https://localhost/&quot;);
- * client.executeMethod(httpget);
- * </pre>
- * 
- * </p>
- * 
- * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
- * 
- *         <p>
- *         DISCLAIMER: HttpClient developers DO NOT actively support this
- *         component. The component is provided as a reference material, which
- *         may be inappropriate for use without additional customization.
- *         </p>
- */
-
-public class EasySSLSocketFactory implements ProtocolSocketFactory {
-
-    private static final String TAG = "EasySSLSocketFactory";
-    private SSLContext sslcontext = null;
-
-    /**
-     * Constructor for EasySSLProtocolSocketFactory.
-     */
-    public EasySSLSocketFactory() {
-        super();
-    }
-
-    private static SSLContext createEasySSLContext() {
-        try {
-            SSLContext context = SSLContext.getInstance("TLS");
-            context.init(null, new TrustManager[] { new EasyX509TrustManager(
-                    null) }, null);
-            return context;
-        } catch (Exception er) {
-            Log.e(TAG, er.getMessage() + "");
-            throw new HttpClientError(er.toString());
-        }
-    }
-
-    private SSLContext getSSLContext() {
-        if (this.sslcontext == null) {
-            this.sslcontext = createEasySSLContext();
-        }
-        return this.sslcontext;
-    }
-
-    /**
-     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
-     */
-    public Socket createSocket(String host, int port, InetAddress clientHost,
-            int clientPort) throws IOException, UnknownHostException {
-
-        return getSSLContext().getSocketFactory().createSocket(host, port,
-                clientHost, clientPort);
-    }
-
-    /**
-     * Attempts to get a new socket connection to the given host within the
-     * given time limit.
-     * <p>
-     * To circumvent the limitations of older JREs that do not support connect
-     * timeout a controller thread is executed. The controller thread attempts
-     * to create a new socket within the given limit of time. If socket
-     * constructor does not return until the timeout expires, the controller
-     * terminates and throws an {@link ConnectTimeoutException}
-     * </p>
-     * 
-     * @param host the host name/IP
-     * @param port the port on the host
-     * @param clientHost the local host name/IP to bind the socket to
-     * @param clientPort the port on the local machine
-     * @param params {@link HttpConnectionParams Http connection parameters}
-     * 
-     * @return Socket a new socket
-     * 
-     * @throws IOException if an I/O error occurs while creating the socket
-     * @throws UnknownHostException if the IP address of the host cannot be
-     *             determined
-     */
-    public Socket createSocket(final String host, final int port,
-            final InetAddress localAddress, final int localPort,
-            final HttpConnectionParams params) throws IOException,
-            UnknownHostException, ConnectTimeoutException {
-        if (params == null) {
-            throw new IllegalArgumentException("Parameters may not be null");
-        }
-        int timeout = params.getConnectionTimeout();
-        SocketFactory socketfactory = getSSLContext().getSocketFactory();
-        if (timeout == 0) {
-            Socket socket = socketfactory.createSocket(host, port, localAddress,
-                    localPort);
-            socket.setSoTimeout(params.getSoTimeout());
-            return socket;
-        } else {
-            Socket socket = socketfactory.createSocket();
-            SocketAddress localaddr = new InetSocketAddress(localAddress,
-                    localPort);
-            SocketAddress remoteaddr = new InetSocketAddress(host, port);
-            socket.setSoTimeout(params.getSoTimeout());
-            socket.bind(localaddr);
-            socket.connect(remoteaddr, timeout);
-            return socket;
-        }
-    }
-
-    /**
-     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
-     */
-    public Socket createSocket(String host, int port) throws IOException,
-            UnknownHostException {
-        return getSSLContext().getSocketFactory().createSocket(host, port);
-    }
-
-    /**
-     * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
-     */
-    public Socket createSocket(Socket socket, String host, int port,
-            boolean autoClose) throws IOException, UnknownHostException {
-        return getSSLContext().getSocketFactory().createSocket(socket, host,
-                port, autoClose);
-    }
-
-    public boolean equals(Object obj) {
-        return ((obj != null) && obj.getClass().equals(
-                EasySSLSocketFactory.class));
-    }
-
-    public int hashCode() {
-        return EasySSLSocketFactory.class.hashCode();
-    }
-
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java b/src/eu/alefzero/owncloud/authenticator/EasyX509TrustManager.java
deleted file mode 100644 (file)
index bdd659d..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-package eu.alefzero.owncloud.authenticator;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
-
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * @author olamy
- * @version $Id: EasyX509TrustManager.java 765355 2009-04-15 20:59:07Z evenisse
- *          $
- * @since 1.2.3
- */
-public class EasyX509TrustManager implements X509TrustManager {
-
-    private X509TrustManager standardTrustManager = null;
-
-    /**
-     * Constructor for EasyX509TrustManager.
-     */
-    public EasyX509TrustManager(KeyStore keystore)
-            throws NoSuchAlgorithmException, KeyStoreException {
-        super();
-        TrustManagerFactory factory = TrustManagerFactory
-                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        factory.init(keystore);
-        TrustManager[] trustmanagers = factory.getTrustManagers();
-        if (trustmanagers.length == 0) {
-            throw new NoSuchAlgorithmException("no trust manager found");
-        }
-        this.standardTrustManager = (X509TrustManager) trustmanagers[0];
-    }
-
-    /**
-     * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],
-     *      String authType)
-     */
-    public void checkClientTrusted(X509Certificate[] certificates,
-            String authType) throws CertificateException {
-        standardTrustManager.checkClientTrusted(certificates, authType);
-    }
-
-    /**
-     * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
-     *      String authType)
-     */
-    public void checkServerTrusted(X509Certificate[] certificates,
-            String authType) throws CertificateException {
-        if ((certificates != null) && (certificates.length == 1)) {
-            certificates[0].checkValidity();
-        } else {
-            // standardTrustManager.checkServerTrusted( certificates, authType
-            // );
-        }
-    }
-
-    /**
-     * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
-     */
-    public X509Certificate[] getAcceptedIssuers() {
-        return this.standardTrustManager.getAcceptedIssuers();
-    }
-
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/authenticator/OnAuthenticationResultListener.java b/src/eu/alefzero/owncloud/authenticator/OnAuthenticationResultListener.java
deleted file mode 100644 (file)
index a8764ee..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.alefzero.owncloud.authenticator;
-
-public interface OnAuthenticationResultListener {
-
-    public void onAuthenticationResult(boolean success, String message);
-
-}
diff --git a/src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java b/src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java
deleted file mode 100644 (file)
index f7da0da..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package eu.alefzero.owncloud.authenticator;
-
-public interface OnConnectCheckListener {
-
-    enum ResultType {
-        OK_SSL, OK_NO_SSL, SSL_INIT_ERROR, HOST_NOT_AVAILABLE, TIMEOUT, NO_NETWORK_CONNECTION, INORRECT_ADDRESS, INSTANCE_NOT_CONFIGURED, FILE_NOT_FOUND, UNKNOWN_ERROR
-    }
-
-    public void onConnectionCheckResult(ResultType type);
-
-}
diff --git a/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java b/src/eu/alefzero/owncloud/datamodel/DataStorageManager.java
deleted file mode 100644 (file)
index 9f1d89b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.datamodel;
-
-import java.util.List;
-import java.util.Vector;
-
-public interface DataStorageManager {
-
-    public OCFile getFileByPath(String path);
-
-    public OCFile getFileById(long id);
-
-    public boolean fileExists(String path);
-
-    public boolean fileExists(long id);
-
-    public boolean saveFile(OCFile file);
-
-    public void saveFiles(List<OCFile> files);
-
-    public Vector<OCFile> getDirectoryContent(OCFile f);
-    
-    public void removeFile(OCFile file);
-}
diff --git a/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java b/src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java
deleted file mode 100644 (file)
index f0d0db2..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.datamodel;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Vector;
-
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.owncloud.files.services.FileDownloader;
-import android.accounts.Account;
-import android.content.ContentProviderClient;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.OperationApplicationException;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.RemoteException;
-import android.util.Log;
-
-public class FileDataStorageManager implements DataStorageManager {
-
-    private ContentResolver mContentResolver;
-    private ContentProviderClient mContentProvider;
-    private Account mAccount;
-
-    private static String TAG = "FileDataStorageManager";
-
-    public FileDataStorageManager(Account account, ContentResolver cr) {
-        mContentProvider = null;
-        mContentResolver = cr;
-        mAccount = account;
-    }
-
-    public FileDataStorageManager(Account account, ContentProviderClient cp) {
-        mContentProvider = cp;
-        mContentResolver = null;
-        mAccount = account;
-    }
-
-    @Override
-    public OCFile getFileByPath(String path) {
-        Cursor c = getCursorForValue(ProviderTableMeta.FILE_PATH, path);
-        OCFile file = null;
-        if (c.moveToFirst()) {
-            file = createFileInstance(c);
-        }
-        c.close();
-        return file;
-    }
-
-    @Override
-    public OCFile getFileById(long id) {
-        Cursor c = getCursorForValue(ProviderTableMeta._ID, String.valueOf(id));
-        OCFile file = null;
-        if (c.moveToFirst()) {
-            file = createFileInstance(c);
-        }
-        c.close();
-        return file;
-    }
-
-    @Override
-    public boolean fileExists(long id) {
-        return fileExists(ProviderTableMeta._ID, String.valueOf(id));
-    }
-
-    @Override
-    public boolean fileExists(String path) {
-        return fileExists(ProviderTableMeta.FILE_PATH, path);
-    }
-
-    @Override
-    public boolean saveFile(OCFile file) {
-        boolean overriden = false;
-        ContentValues cv = new ContentValues();
-        cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
-        cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
-        cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
-        cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
-        cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
-        if (file.getParentId() != 0)
-            cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
-        cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
-        if (!file.isDirectory())
-            cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-        cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
-        cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
-        cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
-
-        if (fileExists(file.getRemotePath())) {
-            OCFile oldFile = getFileByPath(file.getRemotePath());
-            if (file.getStoragePath() == null && oldFile.getStoragePath() != null)
-                file.setStoragePath(oldFile.getStoragePath());
-            if (!file.isDirectory());
-                cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-            file.setFileId(oldFile.getFileId());
-
-            overriden = true;
-            if (getContentResolver() != null) {
-                getContentResolver().update(ProviderTableMeta.CONTENT_URI, cv,
-                        ProviderTableMeta._ID + "=?",
-                        new String[] { String.valueOf(file.getFileId()) });
-            } else {
-                try {
-                    getContentProvider().update(ProviderTableMeta.CONTENT_URI,
-                            cv, ProviderTableMeta._ID + "=?",
-                            new String[] { String.valueOf(file.getFileId()) });
-                } catch (RemoteException e) {
-                    Log.e(TAG,
-                            "Fail to insert insert file to database "
-                                    + e.getMessage());
-                }
-            }
-        } else {
-            Uri result_uri = null;
-            if (getContentResolver() != null) {
-                result_uri = getContentResolver().insert(
-                        ProviderTableMeta.CONTENT_URI_FILE, cv);
-            } else {
-                try {
-                    result_uri = getContentProvider().insert(
-                            ProviderTableMeta.CONTENT_URI_FILE, cv);
-                } catch (RemoteException e) {
-                    Log.e(TAG,
-                            "Fail to insert insert file to database "
-                                    + e.getMessage());
-                }
-            }
-            if (result_uri != null) {
-                long new_id = Long.parseLong(result_uri.getPathSegments()
-                        .get(1));
-                file.setFileId(new_id);
-            }
-        }
-
-        if (file.isDirectory() && file.needsUpdatingWhileSaving())
-            for (OCFile f : getDirectoryContent(file))
-                saveFile(f);
-
-        return overriden;
-    }
-
-
-    @Override
-    public void saveFiles(List<OCFile> files) {
-        
-        Iterator<OCFile> filesIt = files.iterator();
-        ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(files.size());
-        OCFile file = null;
-
-        // prepare operations to perform
-        while (filesIt.hasNext()) {
-            file = filesIt.next();
-            ContentValues cv = new ContentValues();
-            cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
-            cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
-            cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
-            cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
-            cv.put(ProviderTableMeta.FILE_NAME, file.getFileName());
-            if (file.getParentId() != 0)
-                cv.put(ProviderTableMeta.FILE_PARENT, file.getParentId());
-            cv.put(ProviderTableMeta.FILE_PATH, file.getRemotePath());
-            if (!file.isDirectory())
-                cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-            cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
-            cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDate());
-            cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
-
-            if (fileExists(file.getRemotePath())) {
-                OCFile tmpfile = getFileByPath(file.getRemotePath());
-                file.setStoragePath(tmpfile.getStoragePath());
-                if (!file.isDirectory());
-                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getStoragePath());
-                file.setFileId(tmpfile.getFileId());
-
-                operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
-                        withValues(cv).
-                        withSelection(  ProviderTableMeta._ID + "=?", 
-                                        new String[] { String.valueOf(file.getFileId()) })
-                        .build());
-                
-            } else {
-                operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
-            }
-        }
-        
-        // apply operations in batch
-        ContentProviderResult[] results = null;
-        try {
-            if (getContentResolver() != null) {
-                results = getContentResolver().applyBatch(ProviderMeta.AUTHORITY_FILES, operations);
-            
-            } else {
-                results = getContentProvider().applyBatch(operations);
-            }
-            
-        } catch (OperationApplicationException e) {
-            Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
-            
-        } catch (RemoteException e) {
-            Log.e(TAG, "Fail to update/insert list of files to database " + e.getMessage());
-        }
-        
-        // update new id in file objects for insertions
-        if (results != null) {
-            long newId;
-            for (int i=0; i<results.length; i++) {
-                if (results[i].uri != null) {
-                    newId = Long.parseLong(results[i].uri.getPathSegments().get(1));
-                    files.get(i).setFileId(newId);
-                    //Log.v(TAG, "Found and added id in insertion for " + files.get(i).getRemotePath());
-                }
-            }
-        }
-
-        for (OCFile aFile : files) {
-            if (aFile.isDirectory() && aFile.needsUpdatingWhileSaving())
-                saveFiles(getDirectoryContent(aFile));
-        }
-
-    }
-    
-    public void setAccount(Account account) {
-        mAccount = account;
-    }
-
-    public Account getAccount() {
-        return mAccount;
-    }
-
-    public void setContentResolver(ContentResolver cr) {
-        mContentResolver = cr;
-    }
-
-    public ContentResolver getContentResolver() {
-        return mContentResolver;
-    }
-
-    public void setContentProvider(ContentProviderClient cp) {
-        mContentProvider = cp;
-    }
-
-    public ContentProviderClient getContentProvider() {
-        return mContentProvider;
-    }
-
-    public Vector<OCFile> getDirectoryContent(OCFile f) {
-        if (f != null && f.isDirectory() && f.getFileId() != -1) {
-            Vector<OCFile> ret = new Vector<OCFile>();
-
-            Uri req_uri = Uri.withAppendedPath(
-                    ProviderTableMeta.CONTENT_URI_DIR,
-                    String.valueOf(f.getFileId()));
-            Cursor c = null;
-
-            if (getContentProvider() != null) {
-                try {
-                    c = getContentProvider().query(req_uri, null,
-                            ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                            new String[] { mAccount.name }, null);
-                } catch (RemoteException e) {
-                    Log.e(TAG, e.getMessage());
-                    return ret;
-                }
-            } else {
-                c = getContentResolver().query(req_uri, null,
-                        ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                        new String[] { mAccount.name }, null);
-            }
-
-            if (c.moveToFirst()) {
-                do {
-                    OCFile child = createFileInstance(c);
-                    ret.add(child);
-                } while (c.moveToNext());
-            }
-
-            c.close();
-            
-            Collections.sort(ret);
-            
-            return ret;
-        }
-        return null;
-    }
-
-    private boolean fileExists(String cmp_key, String value) {
-        Cursor c;
-        if (getContentResolver() != null) {
-            c = getContentResolver()
-                    .query(ProviderTableMeta.CONTENT_URI,
-                            null,
-                            cmp_key + "=? AND "
-                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER
-                                    + "=?",
-                            new String[] { value, mAccount.name }, null);
-        } else {
-            try {
-                c = getContentProvider().query(
-                        ProviderTableMeta.CONTENT_URI,
-                        null,
-                        cmp_key + "=? AND "
-                                + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                        new String[] { value, mAccount.name }, null);
-            } catch (RemoteException e) {
-                Log.e(TAG,
-                        "Couldn't determine file existance, assuming non existance: "
-                                + e.getMessage());
-                return false;
-            }
-        }
-        boolean retval = c.moveToFirst();
-        c.close();
-        return retval;
-    }
-
-    private Cursor getCursorForValue(String key, String value) {
-        Cursor c = null;
-        if (getContentResolver() != null) {
-            c = getContentResolver()
-                    .query(ProviderTableMeta.CONTENT_URI,
-                            null,
-                            key + "=? AND "
-                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER
-                                    + "=?",
-                            new String[] { value, mAccount.name }, null);
-        } else {
-            try {
-                c = getContentProvider().query(
-                        ProviderTableMeta.CONTENT_URI,
-                        null,
-                        key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER
-                                + "=?", new String[] { value, mAccount.name },
-                        null);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Could not get file details: " + e.getMessage());
-                c = null;
-            }
-        }
-        return c;
-    }
-
-    private OCFile createFileInstance(Cursor c) {
-        OCFile file = null;
-        if (c != null) {
-            file = new OCFile(c.getString(c
-                    .getColumnIndex(ProviderTableMeta.FILE_PATH)));
-            file.setFileId(c.getLong(c.getColumnIndex(ProviderTableMeta._ID)));
-            file.setParentId(c.getLong(c
-                    .getColumnIndex(ProviderTableMeta.FILE_PARENT)));
-            file.setMimetype(c.getString(c
-                    .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)));
-            if (!file.isDirectory()) {
-                file.setStoragePath(c.getString(c
-                        .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
-                if (file.getStoragePath() == null) {
-                    // try to find existing file and bind it with current account
-                    File f = new File(FileDownloader.getSavePath(mAccount.name) + file.getRemotePath());
-                    if (f.exists())
-                        file.setStoragePath(f.getAbsolutePath());
-                }
-            }
-            file.setFileLength(c.getLong(c
-                    .getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH)));
-            file.setCreationTimestamp(c.getLong(c
-                    .getColumnIndex(ProviderTableMeta.FILE_CREATION)));
-            file.setModificationTimestamp(c.getLong(c
-                    .getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
-            file.setLastSyncDate(c.getLong(c
-                    .getColumnIndex(ProviderTableMeta.FILE_LAST_SYNC_DATE)));
-            file.setKeepInSync(c.getInt(
-                                c.getColumnIndex(ProviderTableMeta.FILE_KEEP_IN_SYNC)) == 1 ? true : false);
-        }
-        return file;
-    }
-    
-    public void removeFile(OCFile file) {
-        Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
-        if (getContentProvider() != null) {
-            try {
-                getContentProvider().delete(file_uri,
-                                            ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
-                                            new String[]{mAccount.name});
-            } catch (RemoteException e) {
-                e.printStackTrace();
-            }
-        } else {
-            getContentResolver().delete(file_uri,
-                                        ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
-                                        new String[]{mAccount.name});
-        }
-        if (file.isDown()) {
-            new File(file.getStoragePath()).delete();
-        }
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/datamodel/OCFile.java b/src/eu/alefzero/owncloud/datamodel/OCFile.java
deleted file mode 100644 (file)
index 01a1f58..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.datamodel;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import eu.alefzero.owncloud.files.services.FileDownloader;
-
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public class OCFile implements Parcelable, Comparable<OCFile> {
-
-    public static final Parcelable.Creator<OCFile> CREATOR = new Parcelable.Creator<OCFile>() {
-        @Override
-        public OCFile createFromParcel(Parcel source) {
-            return new OCFile(source);
-        }
-
-        @Override
-        public OCFile[] newArray(int size) {
-            return new OCFile[size];
-        }
-    };
-
-    public static final String PATH_SEPARATOR = "/";
-    
-    private long mId;
-    private long mParentId;
-    private long mLength;
-    private long mCreationTimestamp;
-    private long mModifiedTimestamp;
-    private String mRemotePath;
-    private String mLocalPath;
-    private String mMimeType;
-    private boolean mNeedsUpdating;
-    private long mLastSyncDate;
-    private boolean mKeepInSync;
-
-    /**
-     * Create new {@link OCFile} with given path.
-     * 
-     * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
-     * 
-     * @param path The remote path of the file.
-     */
-    public OCFile(String path) {
-        resetData();
-        mNeedsUpdating = false;
-        if (path == null || path.length() <= 0 || !path.startsWith(PATH_SEPARATOR)) {
-            throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
-        }
-        mRemotePath = path;
-    }
-
-    /**
-     * Reconstruct from parcel
-     * 
-     * @param source The source parcel
-     */
-    private OCFile(Parcel source) {
-        mId = source.readLong();
-        mParentId = source.readLong();
-        mLength = source.readLong();
-        mCreationTimestamp = source.readLong();
-        mModifiedTimestamp = source.readLong();
-        mRemotePath = source.readString();
-        mLocalPath = source.readString();
-        mMimeType = source.readString();
-        mNeedsUpdating = source.readInt() == 0;
-        mKeepInSync = source.readInt() == 1;
-        mLastSyncDate = source.readLong();
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeLong(mId);
-        dest.writeLong(mParentId);
-        dest.writeLong(mLength);
-        dest.writeLong(mCreationTimestamp);
-        dest.writeLong(mModifiedTimestamp);
-        dest.writeString(mRemotePath);
-        dest.writeString(mLocalPath);
-        dest.writeString(mMimeType);
-        dest.writeInt(mNeedsUpdating ? 1 : 0);
-        dest.writeInt(mKeepInSync ? 1 : 0);
-        dest.writeLong(mLastSyncDate);
-    }
-    
-    /**
-     * Gets the ID of the file
-     * 
-     * @return the file ID
-     */
-    public long getFileId() {
-        return mId;
-    }
-
-    /**
-     * Returns the remote path of the file on ownCloud
-     * 
-     * @return The remote path to the file
-     */
-    public String getRemotePath() {
-        return mRemotePath;
-    }
-
-    /**
-     * Can be used to check, whether or not this file exists in the database
-     * already
-     * 
-     * @return true, if the file exists in the database
-     */
-    public boolean fileExists() {
-        return mId != -1;
-    }
-
-    /**
-     * Use this to find out if this file is a Directory
-     * 
-     * @return true if it is a directory
-     */
-    public boolean isDirectory() {
-        return mMimeType != null && mMimeType.equals("DIR");
-    }
-
-    /**
-     * Use this to check if this file is available locally
-     * 
-     * @return true if it is
-     */
-    public boolean isDown() {
-        if (mLocalPath != null && mLocalPath.length() > 0) {
-            File file = new File(mLocalPath);
-            return (file.exists());
-        }
-        return false;
-    }
-    
-    /**
-     * The path, where the file is stored locally
-     * 
-     * @return The local path to the file
-     */
-    public String getStoragePath() {
-        return mLocalPath;
-    }
-
-    /**
-     * Can be used to set the path where the file is stored
-     * 
-     * @param storage_path to set
-     */
-    public void setStoragePath(String storage_path) {
-        mLocalPath = storage_path;
-    }
-
-    /**
-     * Get a UNIX timestamp of the file creation time
-     * 
-     * @return A UNIX timestamp of the time that file was created
-     */
-    public long getCreationTimestamp() {
-        return mCreationTimestamp;
-    }
-
-    /**
-     * Set a UNIX timestamp of the time the file was created
-     * 
-     * @param creation_timestamp to set
-     */
-    public void setCreationTimestamp(long creation_timestamp) {
-        mCreationTimestamp = creation_timestamp;
-    }
-
-    /**
-     * Get a UNIX timestamp of the file modification time
-     * 
-     * @return A UNIX timestamp of the modification time
-     */
-    public long getModificationTimestamp() {
-        return mModifiedTimestamp;
-    }
-
-    /**
-     * Set a UNIX timestamp of the time the time the file was modified.
-     * 
-     * @param modification_timestamp to set
-     */
-    public void setModificationTimestamp(long modification_timestamp) {
-        mModifiedTimestamp = modification_timestamp;
-    }
-
-    /**
-     * Returns the filename and "/" for the root directory
-     * 
-     * @return The name of the file
-     */
-    public String getFileName() {
-        File f = new File(getRemotePath());
-        return f.getName().length() == 0 ? "/" : f.getName();
-    }
-
-    /**
-     * Can be used to get the Mimetype
-     * 
-     * @return the Mimetype as a String
-     */
-    public String getMimetype() {
-        return mMimeType;
-    }
-
-    /**
-     * Adds a file to this directory. If this file is not a directory, an
-     * exception gets thrown.
-     * 
-     * @param file to add
-     * @throws IllegalStateException if you try to add a something and this is
-     *             not a directory
-     */
-    public void addFile(OCFile file) throws IllegalStateException {
-        if (isDirectory()) {
-            file.mParentId = mId;
-            mNeedsUpdating = true;
-            return;
-        }
-        throw new IllegalStateException(
-                "This is not a directory where you can add stuff to!");
-    }
-
-    /**
-     * Used internally. Reset all file properties
-     */
-    private void resetData() {
-        mId = -1;
-        mRemotePath = null;
-        mParentId = 0;
-        mLocalPath = null;
-        mMimeType = null;
-        mLength = 0;
-        mCreationTimestamp = 0;
-        mModifiedTimestamp = 0;
-        mLastSyncDate = 0;
-        mKeepInSync = false;
-        mNeedsUpdating = false;
-    }
-
-    /**
-     * Sets the ID of the file
-     * 
-     * @param file_id to set
-     */
-    public void setFileId(long file_id) {
-        mId = file_id;
-    }
-
-    /**
-     * Sets the Mime-Type of the
-     * 
-     * @param mimetype to set
-     */
-    public void setMimetype(String mimetype) {
-        mMimeType = mimetype;
-    }
-
-    /**
-     * Sets the ID of the parent folder
-     * 
-     * @param parent_id to set
-     */
-    public void setParentId(long parent_id) {
-        mParentId = parent_id;
-    }
-
-    /**
-     * Sets the file size in bytes
-     * 
-     * @param file_len to set
-     */
-    public void setFileLength(long file_len) {
-        mLength = file_len;
-    }
-
-    /**
-     * Returns the size of the file in bytes
-     * 
-     * @return The filesize in bytes
-     */
-    public long getFileLength() {
-        return mLength;
-    }
-
-    /**
-     * Returns the ID of the parent Folder
-     * 
-     * @return The ID
-     */
-    public long getParentId() {
-        return mParentId;
-    }
-
-    /**
-     * Check, if this file needs updating
-     * 
-     * @return
-     */
-    public boolean needsUpdatingWhileSaving() {
-        return mNeedsUpdating;
-    }
-    
-    public long getLastSyncDate() {
-        return mLastSyncDate;
-    }
-    
-    public void setLastSyncDate(long lastSyncDate) {
-        mLastSyncDate = lastSyncDate;
-    }
-
-    public void setKeepInSync(boolean keepInSync) {
-        mKeepInSync = keepInSync;
-    }
-    
-    public boolean keepInSync() {
-        return mKeepInSync;
-    }
-    
-    @Override
-    public int describeContents() {
-        return this.hashCode();
-    }
-
-    @Override
-    public int compareTo(OCFile another) {
-        if (isDirectory() && another.isDirectory()) {
-            return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
-        } else if (isDirectory()) {
-            return -1;
-        } else if (another.isDirectory()) {
-            return 1;
-        }
-        return getRemotePath().toLowerCase().compareTo(another.getRemotePath().toLowerCase());
-    }
-
-    public boolean equals(Object o) {
-        if(o instanceof OCFile){
-            OCFile that = (OCFile) o;
-            if(that != null){
-                return this.mId == that.mId;
-            }
-        }
-        
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, parentId=%s, keepInSinc=%s]";
-        asString = String.format(asString, new Long(mId), getFileName(), mMimeType, isDown(), mLocalPath, mRemotePath, new Long(mParentId), new Boolean(mKeepInSync));
-        return asString;
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/db/DbHandler.java b/src/eu/alefzero/owncloud/db/DbHandler.java
deleted file mode 100644 (file)
index 23b8bb6..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.db;\r
-\r
-import java.util.Vector;\r
-\r
-import eu.alefzero.owncloud.OwnCloudSession;\r
-\r
-import android.content.ContentValues;\r
-import android.content.Context;\r
-import android.database.Cursor;\r
-import android.database.sqlite.SQLiteDatabase;\r
-import android.database.sqlite.SQLiteOpenHelper;\r
-\r
-/**\r
- * Custom database helper for ownCloud\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class DbHandler {\r
-    private SQLiteDatabase mDB;\r
-    private OpenerHepler mHelper;\r
-    private final String mDatabaseName = "ownCloud";\r
-    private final String TABLE_SESSIONS = "sessions";\r
-    private final int mDatabaseVersion = 1;\r
-    \r
-    private final String TABLE_INSTANT_UPLOAD = "instant_upload";\r
-\r
-    public DbHandler(Context context) {\r
-        mHelper = new OpenerHepler(context);\r
-        mDB = mHelper.getWritableDatabase();\r
-    }\r
-\r
-    public void close() {\r
-        mDB.close();\r
-    }\r
-\r
-    public boolean putFileForLater(String filepath, String account) {\r
-        ContentValues cv = new ContentValues();\r
-        cv.put("path", filepath);\r
-        cv.put("account", account);\r
-        return mDB.insert(TABLE_INSTANT_UPLOAD, null, cv) != -1;\r
-    }\r
-    \r
-    public Cursor getAwaitingFiles() {\r
-        return mDB.query(TABLE_INSTANT_UPLOAD, null, null, null, null, null, null);\r
-    }\r
-    \r
-    public void clearFiles() {\r
-        mDB.delete(TABLE_INSTANT_UPLOAD, null, null);\r
-    }\r
-    \r
-    private class OpenerHepler extends SQLiteOpenHelper {\r
-        public OpenerHepler(Context context) {\r
-            super(context, mDatabaseName, null, mDatabaseVersion);\r
-        }\r
-\r
-        @Override\r
-        public void onCreate(SQLiteDatabase db) {\r
-            db.execSQL("CREATE TABLE " + TABLE_INSTANT_UPLOAD + " ("\r
-                       + " _id INTEGET PRIMARY KEY, "\r
-                       + " path TEXT,"\r
-                       + " account TEXT);");\r
-        }\r
-\r
-        @Override\r
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
-        }\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/db/ProviderMeta.java b/src/eu/alefzero/owncloud/db/ProviderMeta.java
deleted file mode 100644 (file)
index 62c0ace..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.db;\r
-\r
-import android.net.Uri;\r
-import android.provider.BaseColumns;\r
-\r
-/**\r
- * Meta-Class that holds various static field information\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class ProviderMeta {\r
-\r
-    public static final String AUTHORITY_FILES = "org.owncloud";\r
-    public static final String DB_FILE = "owncloud.db";\r
-    public static final String DB_NAME = "filelist";\r
-    public static final int DB_VERSION = 2;\r
-\r
-    private ProviderMeta() {\r
-    }\r
-\r
-    static public class ProviderTableMeta implements BaseColumns {\r
-        public static final String DB_NAME = "filelist";\r
-        public static final Uri CONTENT_URI = Uri.parse("content://"\r
-                + AUTHORITY_FILES + "/");\r
-        public static final Uri CONTENT_URI_FILE = Uri.parse("content://"\r
-                + AUTHORITY_FILES + "/file");\r
-        public static final Uri CONTENT_URI_DIR = Uri.parse("content://"\r
-                + AUTHORITY_FILES + "/dir");\r
-\r
-        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.owncloud.file";\r
-        public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.owncloud.file";\r
-\r
-        public static final String FILE_PARENT = "parent";\r
-        public static final String FILE_NAME = "filename";\r
-        public static final String FILE_CREATION = "created";\r
-        public static final String FILE_MODIFIED = "modified";\r
-        public static final String FILE_CONTENT_LENGTH = "content_length";\r
-        public static final String FILE_CONTENT_TYPE = "content_type";\r
-        public static final String FILE_STORAGE_PATH = "media_path";\r
-        public static final String FILE_PATH = "path";\r
-        public static final String FILE_ACCOUNT_OWNER = "file_owner";\r
-        public static final String FILE_LAST_SYNC_DATE = "last_sync_date";\r
-        public static final String FILE_KEEP_IN_SYNC = "keep_in_sync";\r
-\r
-        public static final String DEFAULT_SORT_ORDER = FILE_NAME\r
-                + " collate nocase asc";\r
-\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java b/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java
deleted file mode 100644 (file)
index 3d2554d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package eu.alefzero.owncloud.extensions;
-
-import android.os.Bundle;
-import android.support.v4.app.FragmentManager;
-
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-
-public class ExtensionsAvailableActivity extends SherlockFragmentActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        FragmentManager fm = getSupportFragmentManager();
-        ExtensionsAvailableDialog ead = new ExtensionsAvailableDialog();
-        ead.show(fm, "extensions_available_dialog");
-    }
-}
diff --git a/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java b/src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java
deleted file mode 100644 (file)
index 202acf2..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-package eu.alefzero.owncloud.extensions;
-
-import eu.alefzero.owncloud.R;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-
-public class ExtensionsAvailableDialog extends DialogFragment implements
-        OnClickListener {
-
-    public ExtensionsAvailableDialog() {
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        View view = inflater.inflate(R.layout.extensions_available_dialog,
-                container);
-        Button btnYes = (Button) view.findViewById(R.id.buttonYes);
-        Button btnNo = (Button) view.findViewById(R.id.buttonNo);
-        btnYes.setOnClickListener(this);
-        btnNo.setOnClickListener(this);
-        getDialog().setTitle(R.string.extensions_avail_title);
-        return view;
-    }
-
-    @Override
-    public void onClick(View v) {
-        switch (v.getId()) {
-        case R.id.buttonYes: {
-            Intent i = new Intent(getActivity(), ExtensionsListActivity.class);
-            startActivity(i);
-            getActivity().finish();
-        }
-            break;
-        case R.id.buttonNo:
-            getActivity().finish();
-            break;
-        default:
-            Log.e("EAD", "Button with unknown id clicked " + v.getId());
-        }
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java b/src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java
deleted file mode 100644 (file)
index ec7d8bb..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-package eu.alefzero.owncloud.extensions;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Vector;
-
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-
-import android.R;
-import android.app.Activity;
-import android.app.ListActivity;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.widget.SimpleAdapter;
-
-public class ExtensionsListActivity extends ListActivity {
-
-    private static final String packages_url = "http://alefzero.eu/a/packages.php";
-
-    private Thread mGetterThread;
-    private final Handler mHandler = new Handler();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mGetterThread = new Thread(new JsonGetter());
-        mGetterThread.start();
-    }
-
-    public void done(JSONArray a) {
-        LinkedList<HashMap<String, String>> ll = new LinkedList<HashMap<String, String>>();
-        for (int i = 0; i < a.length(); ++i) {
-            try {
-                ExtensionApplicationEntry ela = new ExtensionApplicationEntry(
-                        ((JSONObject) a.get(i)));
-                HashMap<String, String> ss = new HashMap<String, String>();
-                ss.put("NAME", ela.getName());
-                ss.put("DESC", ela.getDescription());
-                ll.add(ss);
-            } catch (JSONException e) {
-                e.printStackTrace();
-            }
-        }
-        setListAdapter(new SimpleAdapter(this, ll, R.layout.simple_list_item_2,
-                new String[] { "NAME", "DESC" }, new int[] {
-                        android.R.id.text1, android.R.id.text2 }));
-
-    }
-
-    private class JsonGetter implements Runnable {
-
-        @Override
-        public void run() {
-            HttpClient hc = new HttpClient();
-            GetMethod gm = new GetMethod(packages_url);
-            final JSONArray ar;
-            try {
-                hc.executeMethod(gm);
-                Log.e("ASD", gm.getResponseBodyAsString() + "");
-                ar = new JSONObject(gm.getResponseBodyAsString())
-                        .getJSONArray("apps");
-            } catch (Exception e) {
-                e.printStackTrace();
-                return;
-            }
-
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    done(ar);
-                }
-            });
-
-        }
-
-    }
-
-    private class ExtensionApplicationEntry {
-        private static final String APP_NAME = "name";
-        private static final String APP_VERSION = "version";
-        private static final String APP_DESC = "description";
-        private static final String APP_ICON = "icon";
-        private static final String APP_URL = "download";
-        private static final String APP_PLAYID = "play_id";
-
-        private String mName, mDescription, mIcon, mDownload, mPlayId;
-        private OwnCloudVersion mVersion;
-
-        public ExtensionApplicationEntry(JSONObject appentry) {
-            try {
-                mName = appentry.getString(APP_NAME);
-                mDescription = appentry.getString(APP_DESC);
-                mIcon = appentry.getString(APP_ICON);
-                mDownload = appentry.getString(APP_URL);
-                mPlayId = appentry.getString(APP_PLAYID);
-                mVersion = new OwnCloudVersion(appentry.getString(APP_VERSION));
-            } catch (JSONException e) {
-                e.printStackTrace();
-            }
-        }
-
-        public String getName() {
-            return mName;
-        }
-
-        public String getDescription() {
-            return mDescription;
-        }
-
-        public String getIcon() {
-            return mIcon;
-        }
-
-        public String getDownload() {
-            return mDownload;
-        }
-
-        public String getPlayId() {
-            return mPlayId;
-        }
-
-        public OwnCloudVersion getVersion() {
-            return mVersion;
-        }
-    }
-}
diff --git a/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java b/src/eu/alefzero/owncloud/files/PhotoTakenBroadcastReceiver.java
deleted file mode 100644 (file)
index c89a825..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.files;
-
-import java.io.File;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.DbHandler;
-import eu.alefzero.owncloud.files.services.InstantUploadService;
-import android.accounts.Account;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.ConnectivityManager;
-import android.preference.Preference;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.webkit.MimeTypeMap;
-
-public class PhotoTakenBroadcastReceiver extends BroadcastReceiver {
-
-    private static String TAG = "PhotoTakenBroadcastReceiver";
-    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) {
-        if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("instant_uploading", false)) {
-            Log.d(TAG, "Instant upload disabled, abording uploading");
-            return;
-        }
-        if (intent.getAction().equals(android.net.ConnectivityManager.CONNECTIVITY_ACTION)) {
-            handleConnectivityAction(context, intent);
-        } else if (intent.getAction().equals(NEW_PHOTO_ACTION)) {
-            handleNewPhontoAction(context, intent);
-        } else {
-            Log.e(TAG, "Incorrect intent sent: " + intent.getAction());
-        }
-    }
-
-    private void handleNewPhontoAction(Context context, Intent intent) {
-        Account account = AccountUtils.getCurrentOwnCloudAccount(context);
-        if (account == null) {
-            Log.w(TAG, "No owncloud account found for instant upload, abording");
-            return;
-        }
-
-        Cursor c = context.getContentResolver().query(intent.getData(), CONTENT_PROJECTION, null, null, null);
-        
-        if (!c.moveToFirst()) {
-            Log.e(TAG, "Couldn't resolve given uri!");
-            return;
-        }
-        
-        String file_path = c.getString(c.getColumnIndex(Media.DATA));
-        String file_name = c.getString(c.getColumnIndex(Media.DISPLAY_NAME));
-        String mime_type = c.getString(c.getColumnIndex(Media.MIME_TYPE));
-        long file_size = c.getLong(c.getColumnIndex(Media.SIZE));
-
-        c.close();
-        
-        if (!isOnline(context)) {
-            DbHandler db = new DbHandler(context);
-            db.putFileForLater(file_path, account.name);
-            db.close();
-            return;
-        }
-        
-        Intent upload_intent = new Intent(context, InstantUploadService.class);
-        upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
-        upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
-        upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, file_name);
-        upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, file_size);
-        upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mime_type);
-        
-        context.startService(upload_intent);
-    }
-
-    private void handleConnectivityAction(Context context, Intent intent) {
-        if (!intent.hasExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY) ||
-            isOnline(context)) {
-            DbHandler db = new DbHandler(context);
-            Cursor c = db.getAwaitingFiles();
-            if (c.moveToFirst()) {
-                do {
-                    String account_name = c.getString(c.getColumnIndex("account"));
-                    String file_path = c.getString(c.getColumnIndex("path"));
-                    File f = new File(file_path);
-                    if (f.exists()) {
-                        Intent upload_intent = new Intent(context, InstantUploadService.class);
-                        Account account = new Account(account_name, AccountAuthenticator.ACCOUNT_TYPE);
-                        
-                        String mimeType = null;
-                        try {
-                            mimeType = MimeTypeMap.getSingleton()
-                                    .getMimeTypeFromExtension(
-                                            f.getName().substring(f.getName().lastIndexOf('.') + 1));
-                        
-                        } catch (IndexOutOfBoundsException e) {
-                            Log.e(TAG, "Trying to find out MIME type of a file without extension: " + f.getName());
-                        }
-                        if (mimeType == null)
-                            mimeType = "application/octet-stream";
-                        
-                        upload_intent.putExtra(InstantUploadService.KEY_ACCOUNT, account);
-                        upload_intent.putExtra(InstantUploadService.KEY_FILE_PATH, file_path);
-                        upload_intent.putExtra(InstantUploadService.KEY_DISPLAY_NAME, f.getName());
-                        upload_intent.putExtra(InstantUploadService.KEY_FILE_SIZE, f.length());
-                        upload_intent.putExtra(InstantUploadService.KEY_MIME_TYPE, mimeType);
-                        
-                        context.startService(upload_intent);
-                    } else {
-                        Log.w(TAG, "Instant upload file " + f.getName() + " dont exist anymore");
-                    }
-                } while(c.moveToNext());
-                c.close();
-            }
-            db.clearFiles();
-            db.close();
-        }
-        
-    }
-
-    private boolean isOnline(Context context) {
-        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
-        return cm.getActiveNetworkInfo() != null && cm.getActiveNetworkInfo().isConnected();
-    }
-    
-}
diff --git a/src/eu/alefzero/owncloud/files/interfaces/OnDatatransferProgressListener.java b/src/eu/alefzero/owncloud/files/interfaces/OnDatatransferProgressListener.java
deleted file mode 100644 (file)
index 4a897dd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-package eu.alefzero.owncloud.files.interfaces;
-
-public interface OnDatatransferProgressListener {
-    void transferProgress(long progressRate);
-
-}
diff --git a/src/eu/alefzero/owncloud/files/services/FileDownloader.java b/src/eu/alefzero/owncloud/files/services/FileDownloader.java
deleted file mode 100644 (file)
index b0dd2b2..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-package eu.alefzero.owncloud.files.services;\r
-\r
-import java.io.File;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.app.Notification;\r
-import android.app.NotificationManager;\r
-import android.app.PendingIntent;\r
-import android.app.Service;\r
-import android.content.ContentValues;\r
-import android.content.Intent;\r
-import android.net.Uri;\r
-import android.os.Environment;\r
-import android.os.Handler;\r
-import android.os.HandlerThread;\r
-import android.os.IBinder;\r
-import android.os.Looper;\r
-import android.os.Message;\r
-import android.os.Process;\r
-import android.util.Log;\r
-import android.widget.RemoteViews;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;\r
-import eu.alefzero.webdav.WebdavClient;\r
-\r
-public class FileDownloader extends Service implements OnDatatransferProgressListener {\r
-    public static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";\r
-    public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";    \r
-    public static final String EXTRA_ACCOUNT = "ACCOUNT";\r
-    public static final String EXTRA_FILE_PATH = "FILE_PATH";\r
-    public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";\r
-    public static final String EXTRA_FILE_SIZE = "FILE_SIZE";\r
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";\r
-    \r
-    private static final String TAG = "FileDownloader";\r
-\r
-    private NotificationManager mNotificationMngr;\r
-    private Looper mServiceLooper;\r
-    private ServiceHandler mServiceHandler;\r
-    private Account mAccount;\r
-    private String mFilePath;\r
-    private String mRemotePath;\r
-    private int mLastPercent;\r
-    private long mTotalDownloadSize;\r
-    private long mCurrentDownloadSize;\r
-    private Notification mNotification;\r
-    \r
-    /**\r
-     * Static map with the files being download and the path to the temporal file were are download\r
-     */\r
-    private static Map<String, String> mDownloadsInProgress = Collections.synchronizedMap(new HashMap<String, String>());\r
-    \r
-    /**\r
-     * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading\r
-     */\r
-    public static boolean isDownloading(Account account, String remotePath) {\r
-        return (mDownloadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);\r
-    }\r
-    \r
-    /**\r
-     * Builds a key for mDownloadsInProgress from the accountName and remotePath\r
-     */\r
-    private static String buildRemoteName(String accountName, String remotePath) {\r
-        return accountName + remotePath;\r
-    }\r
-\r
-    \r
-    private final class ServiceHandler extends Handler {\r
-        public ServiceHandler(Looper looper) {\r
-            super(looper);\r
-        }\r
-\r
-        @Override\r
-        public void handleMessage(Message msg) {\r
-            downloadFile();\r
-            stopSelf(msg.arg1);\r
-        }\r
-    }\r
-    \r
-    public static final String getSavePath(String accountName) {\r
-        File sdCard = Environment.getExternalStorageDirectory();\r
-        return sdCard.getAbsolutePath() + "/owncloud/" + Uri.encode(accountName, "@");   \r
-            // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B\r
-    }\r
-    \r
-    public static final String getTemporalPath(String accountName) {\r
-        File sdCard = Environment.getExternalStorageDirectory();\r
-        return sdCard.getAbsolutePath() + "/owncloud/tmp/" + Uri.encode(accountName, "@");\r
-            // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B\r
-    }\r
-\r
-    @Override\r
-    public void onCreate() {\r
-        super.onCreate();\r
-        mNotificationMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
-        HandlerThread thread = new HandlerThread("FileDownladerThread",\r
-                Process.THREAD_PRIORITY_BACKGROUND);\r
-        thread.start();\r
-        mServiceLooper = thread.getLooper();\r
-        mServiceHandler = new ServiceHandler(mServiceLooper);\r
-    }\r
-\r
-    @Override\r
-    public IBinder onBind(Intent arg0) {\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public int onStartCommand(Intent intent, int flags, int startId) {\r
-        if (    !intent.hasExtra(EXTRA_ACCOUNT) ||\r
-                !intent.hasExtra(EXTRA_FILE_PATH) ||\r
-                !intent.hasExtra(EXTRA_REMOTE_PATH)\r
-           ) {\r
-            Log.e(TAG, "Not enough information provided in intent");\r
-            return START_NOT_STICKY;\r
-        }\r
-        mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);\r
-        mFilePath = intent.getStringExtra(EXTRA_FILE_PATH);\r
-        mRemotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);\r
-        mTotalDownloadSize = intent.getLongExtra(EXTRA_FILE_SIZE, -1);\r
-        mCurrentDownloadSize = mLastPercent = 0;\r
-\r
-        Message msg = mServiceHandler.obtainMessage();\r
-        msg.arg1 = startId;\r
-        mServiceHandler.sendMessage(msg);\r
-\r
-        return START_NOT_STICKY;\r
-    }\r
-\r
-    /**\r
-     * Core download method: requests the file to download and stores it.\r
-     */\r
-    private void downloadFile() {\r
-        boolean downloadResult = false;\r
-\r
-        /// prepare client object to send the request to the ownCloud server\r
-        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);\r
-        WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());\r
-        String username = mAccount.name.split("@")[0];\r
-        String password = null;\r
-        try {\r
-            password = am.blockingGetAuthToken(mAccount,\r
-                    AccountAuthenticator.AUTH_TOKEN_TYPE, true);\r
-        } catch (Exception e) {\r
-            Log.e(TAG, "Access to account credentials failed", e);\r
-            sendFinalBroadcast(downloadResult, null);\r
-            return;\r
-        }\r
-        wdc.setCredentials(username, password);\r
-        wdc.allowSelfsignedCertificates();\r
-        wdc.setDataTransferProgressListener(this);\r
-\r
-        \r
-        /// download will be in a temporal file\r
-        File tmpFile = new File(getTemporalPath(mAccount.name) + mFilePath);\r
-        \r
-        /// create status notification to show the download progress\r
-        mNotification = new Notification(R.drawable.icon, getString(R.string.downloader_download_in_progress_ticker), System.currentTimeMillis());\r
-        mNotification.flags |= Notification.FLAG_ONGOING_EVENT;\r
-        mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);\r
-        mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, mTotalDownloadSize == -1);\r
-        mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), 0, tmpFile.getName()));\r
-        mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);\r
-        // TODO put something smart in the contentIntent below\r
-        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);\r
-        mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);\r
-        \r
-\r
-        /// perform the download\r
-        tmpFile.getParentFile().mkdirs();\r
-        mDownloadsInProgress.put(buildRemoteName(mAccount.name, mRemotePath), tmpFile.getAbsolutePath());\r
-        File newFile = null;\r
-        try {\r
-            if (wdc.downloadFile(mRemotePath, tmpFile)) {\r
-                newFile = new File(getSavePath(mAccount.name) + mFilePath);\r
-                newFile.getParentFile().mkdirs();\r
-                boolean moved = tmpFile.renameTo(newFile);\r
-            \r
-                if (moved) {\r
-                    ContentValues cv = new ContentValues();\r
-                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());\r
-                    getContentResolver().update(\r
-                            ProviderTableMeta.CONTENT_URI,\r
-                            cv,\r
-                            ProviderTableMeta.FILE_NAME + "=? AND "\r
-                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
-                            new String[] {\r
-                                mFilePath.substring(mFilePath.lastIndexOf('/') + 1),\r
-                                mAccount.name });\r
-                    downloadResult = true;\r
-                }\r
-            }\r
-        } finally {\r
-            mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));\r
-        }\r
-\r
-        \r
-        /// notify result\r
-        mNotificationMngr.cancel(R.string.downloader_download_in_progress_ticker);\r
-        int tickerId = (downloadResult) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker;\r
-        int contentId = (downloadResult) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;\r
-        Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());\r
-        finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;\r
-        // TODO put something smart in the contentIntent below\r
-        finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);\r
-        finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), tmpFile.getName()), finalNotification.contentIntent);\r
-        mNotificationMngr.notify(tickerId, finalNotification);\r
-            \r
-        sendFinalBroadcast(downloadResult, (downloadResult)?newFile.getAbsolutePath():null);\r
-    }\r
-\r
-    /**\r
-     * Callback method to update the progress bar in the status notification.\r
-     */\r
-    @Override\r
-    public void transferProgress(long progressRate) {\r
-        mCurrentDownloadSize += progressRate;\r
-        int percent = (int)(100.0*((double)mCurrentDownloadSize)/((double)mTotalDownloadSize));\r
-        if (percent != mLastPercent) {\r
-          mNotification.contentView.setProgressBar(R.id.status_progress, 100, (int)(100*mCurrentDownloadSize/mTotalDownloadSize), mTotalDownloadSize == -1);\r
-          mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), percent, new File(mFilePath).getName()));\r
-          mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);\r
-        }\r
-        \r
-        mLastPercent = percent;\r
-    }\r
-    \r
-\r
-    /**\r
-     * Sends a broadcast in order to the interested activities can update their view\r
-     * \r
-     * @param downloadResult        'True' if the download was successful\r
-     * @param newFilePath           Absolute path to the download file\r
-     */\r
-    private void sendFinalBroadcast(boolean downloadResult, String newFilePath) {\r
-        Intent end = new Intent(DOWNLOAD_FINISH_MESSAGE);\r
-        end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult);\r
-        end.putExtra(ACCOUNT_NAME, mAccount.name);\r
-        end.putExtra(EXTRA_REMOTE_PATH, mRemotePath);\r
-        if (downloadResult) {\r
-            end.putExtra(EXTRA_FILE_PATH, newFilePath);\r
-        }\r
-        sendBroadcast(end);\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/files/services/FileOperation.java b/src/eu/alefzero/owncloud/files/services/FileOperation.java
deleted file mode 100644 (file)
index b0e9d4a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.files.services;
-
-import java.io.File;
-
-import android.accounts.Account;
-import android.content.Context;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.webdav.WebdavClient;
-
-public class FileOperation {
-
-    Context mContext;
-    
-    public FileOperation(Context contex){
-        this.mContext = contex;
-    }
-    
-    /**
-     * Deletes a file from ownCloud - locally and remote.
-     * @param file The file to delete
-     * @return True on success, otherwise false
-     */
-    public boolean delete(OCFile file){
-        
-        Account account = AccountUtils.getCurrentOwnCloudAccount(mContext);
-        WebdavClient client = new WebdavClient(account, mContext);
-        if(client.deleteFile(file.getRemotePath())){
-            File localFile = new File(file.getStoragePath());
-            return localFile.delete();
-        }
-        
-        return false;
-    }
-    
-}
diff --git a/src/eu/alefzero/owncloud/files/services/FileUploader.java b/src/eu/alefzero/owncloud/files/services/FileUploader.java
deleted file mode 100644 (file)
index 3f30f1b..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-package eu.alefzero.owncloud.files.services;
-
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import android.accounts.Account;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.util.Log;
-import android.webkit.MimeTypeMap;
-import android.widget.RemoteViews;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
-import eu.alefzero.owncloud.datamodel.OCFile;
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;
-import eu.alefzero.webdav.WebdavClient;
-
-public class FileUploader extends Service implements OnDatatransferProgressListener {
-
-    public static final String UPLOAD_FINISH_MESSAGE = "UPLOAD_FINISH";
-    public static final String EXTRA_PARENT_DIR_ID = "PARENT_DIR_ID";
-    public static final String EXTRA_UPLOAD_RESULT = "RESULT";
-    public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
-    public static final String EXTRA_FILE_PATH = "FILE_PATH";
-    
-    public static final String KEY_LOCAL_FILE = "LOCAL_FILE";
-    public static final String KEY_REMOTE_FILE = "REMOTE_FILE";
-    public static final String KEY_ACCOUNT = "ACCOUNT";
-    public static final String KEY_UPLOAD_TYPE = "UPLOAD_TYPE";
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";    
-
-    public static final int UPLOAD_SINGLE_FILE = 0;
-    public static final int UPLOAD_MULTIPLE_FILES = 1;
-
-    private static final String TAG = "FileUploader";
-    
-    private NotificationManager mNotificationManager;
-    private Looper mServiceLooper;
-    private ServiceHandler mServiceHandler;
-    private Account mAccount;
-    private String[] mLocalPaths, mRemotePaths;
-    private int mUploadType;
-    private Notification mNotification;
-    private long mTotalDataToSend, mSendData;
-    private int mCurrentIndexUpload, mPreviousPercent;
-    private int mSuccessCounter;
-    
-    /**
-     * Static map with the files being download and the path to the temporal file were are download
-     */
-    private static Map<String, String> mUploadsInProgress = Collections.synchronizedMap(new HashMap<String, String>());
-    
-    /**
-     * Returns True when the file referred by 'remotePath' in the ownCloud account 'account' is downloading
-     */
-    public static boolean isUploading(Account account, String remotePath) {
-        return (mUploadsInProgress.get(buildRemoteName(account.name, remotePath)) != null);
-    }
-    
-    /**
-     * Builds a key for mUplaodsInProgress from the accountName and remotePath
-     */
-    private static String buildRemoteName(String accountName, String remotePath) {
-        return accountName + remotePath;
-    }
-
-    
-    
-
-    @Override
-    public IBinder onBind(Intent arg0) {
-        return null;
-    }
-
-    private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            uploadFile();
-            stopSelf(msg.arg1);
-        }
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        HandlerThread thread = new HandlerThread("FileUploaderThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-        mServiceLooper = thread.getLooper();
-        mServiceHandler = new ServiceHandler(mServiceLooper);
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (!intent.hasExtra(KEY_ACCOUNT) && !intent.hasExtra(KEY_UPLOAD_TYPE)) {
-            Log.e(TAG, "Not enough information provided in intent");
-            return Service.START_NOT_STICKY;
-        }
-        mAccount = intent.getParcelableExtra(KEY_ACCOUNT);
-        mUploadType = intent.getIntExtra(KEY_UPLOAD_TYPE, -1);
-        if (mUploadType == -1) {
-            Log.e(TAG, "Incorrect upload type provided");
-            return Service.START_NOT_STICKY;
-        }
-        if (mUploadType == UPLOAD_SINGLE_FILE) {
-            mLocalPaths = new String[] { intent.getStringExtra(KEY_LOCAL_FILE) };
-            mRemotePaths = new String[] { intent
-                    .getStringExtra(KEY_REMOTE_FILE) };
-        } else { // mUploadType == UPLOAD_MULTIPLE_FILES
-            mLocalPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
-            mRemotePaths = intent.getStringArrayExtra(KEY_REMOTE_FILE);
-        }
-
-        if (mLocalPaths.length != mRemotePaths.length) {
-            Log.e(TAG, "Different number of remote paths and local paths!");
-            return Service.START_NOT_STICKY;
-        }
-
-        Message msg = mServiceHandler.obtainMessage();
-        msg.arg1 = startId;
-        mServiceHandler.sendMessage(msg);
-
-        return Service.START_NOT_STICKY;
-    }
-
-    
-    /**
-     * Core upload method: sends the file(s) to upload
-     */
-    public void uploadFile() {
-        FileDataStorageManager storageManager = new FileDataStorageManager(mAccount, getContentResolver());
-
-        mTotalDataToSend = mSendData = mPreviousPercent = 0;
-        
-        /// prepare client object to send the request to the ownCloud server
-        WebdavClient wc = new WebdavClient(mAccount, getApplicationContext());
-        wc.allowSelfsignedCertificates();
-        wc.setDataTransferProgressListener(this);
-
-        /// create status notification to show the upload progress
-        mNotification = new Notification(eu.alefzero.owncloud.R.drawable.icon, getString(R.string.uploader_upload_in_progress_ticker), System.currentTimeMillis());
-        mNotification.flags |= Notification.FLAG_ONGOING_EVENT;
-        RemoteViews oldContentView = mNotification.contentView;
-        mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout);
-        mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
-        mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);
-        // dvelasco ; contentIntent MUST be assigned to avoid app crashes in versions previous to Android 4.x ;
-        //              BUT an empty Intent is not a very elegant solution; something smart should happen when a user 'clicks' on an upload in the notification bar
-        mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
-        mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
-
-        
-        /// perform the upload
-        File [] localFiles = new File[mLocalPaths.length];
-        for (int i = 0; i < mLocalPaths.length; ++i) {
-            localFiles[i] = new File(mLocalPaths[i]);
-            mTotalDataToSend += localFiles[i].length();
-        }
-        Log.d(TAG, "Will upload " + mTotalDataToSend + " bytes, with " + mLocalPaths.length + " files");
-        mSuccessCounter = 0;
-        for (int i = 0; i < mLocalPaths.length; ++i) {
-            String mimeType = null;
-            try {
-                mimeType = MimeTypeMap.getSingleton()
-                        .getMimeTypeFromExtension(
-                                mLocalPaths[i].substring(mLocalPaths[i]
-                                    .lastIndexOf('.') + 1));
-            } catch (IndexOutOfBoundsException e) {
-                Log.e(TAG, "Trying to find out MIME type of a file without extension: " + mLocalPaths[i]);
-            }
-            if (mimeType == null)
-                mimeType = "application/octet-stream";
-            mCurrentIndexUpload = i;
-            long parentDirId = -1;
-            boolean uploadResult = false;
-            String availablePath = getAvailableRemotePath(wc, mRemotePaths[i]);
-            try {
-                File f = new File(mRemotePaths[i]);
-                parentDirId = storageManager.getFileByPath(f.getParent().endsWith("/")?f.getParent():f.getParent()+"/").getFileId();
-                if(availablePath != null) {
-                    mRemotePaths[i] = availablePath;
-                    mUploadsInProgress.put(buildRemoteName(mAccount.name, mRemotePaths[i]), mLocalPaths[i]);
-                    if (wc.putFile(mLocalPaths[i], mRemotePaths[i], mimeType)) {
-                        OCFile new_file = new OCFile(mRemotePaths[i]);
-                        new_file.setMimetype(mimeType);
-                        new_file.setFileLength(localFiles[i].length());
-                        new_file.setModificationTimestamp(System.currentTimeMillis());
-                        new_file.setLastSyncDate(0);
-                        new_file.setStoragePath(mLocalPaths[i]);         
-                        new_file.setParentId(parentDirId);
-                        storageManager.saveFile(new_file);
-                        mSuccessCounter++;
-                        uploadResult = true;
-                    }
-                }
-            } finally {
-                mUploadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePaths[i]));
-                
-                /// notify upload (or fail) of EACH file to activities interested
-                Intent end = new Intent(UPLOAD_FINISH_MESSAGE);
-                end.putExtra(EXTRA_PARENT_DIR_ID, parentDirId);
-                end.putExtra(EXTRA_UPLOAD_RESULT, uploadResult);
-                end.putExtra(EXTRA_REMOTE_PATH, mRemotePaths[i]);
-                end.putExtra(EXTRA_FILE_PATH, mLocalPaths[i]);
-                end.putExtra(ACCOUNT_NAME, mAccount.name);
-                sendBroadcast(end);
-            }
-            
-        }
-        
-        /// notify final result
-        if (mSuccessCounter == mLocalPaths.length) {    // success
-            //Notification finalNotification = new Notification(R.drawable.icon, getString(R.string.uploader_upload_succeeded_ticker), System.currentTimeMillis());
-            mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove the ongoing flag
-            mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
-            mNotification.contentView = oldContentView;
-            // TODO put something smart in the contentIntent below
-            mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
-            if (mLocalPaths.length == 1) {
-                mNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                    getString(R.string.uploader_upload_succeeded_ticker), 
-                                                    String.format(getString(R.string.uploader_upload_succeeded_content_single), localFiles[0].getName()), 
-                                                    mNotification.contentIntent);
-            } else {
-                mNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                    getString(R.string.uploader_upload_succeeded_ticker), 
-                                                    String.format(getString(R.string.uploader_upload_succeeded_content_multiple), mSuccessCounter), 
-                                                    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
-            
-        } else {
-            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());
-            finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;
-            // TODO put something smart in the contentIntent below
-            finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);
-            if (mLocalPaths.length == 1) {
-                finalNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                        getString(R.string.uploader_upload_failed_ticker), 
-                                                        String.format(getString(R.string.uploader_upload_failed_content_single), localFiles[0].getName()), 
-                                                        finalNotification.contentIntent);
-            } else {
-                finalNotification.setLatestEventInfo(   getApplicationContext(), 
-                                                        getString(R.string.uploader_upload_failed_ticker), 
-                                                        String.format(getString(R.string.uploader_upload_failed_content_multiple), mSuccessCounter, mLocalPaths.length), 
-                                                        finalNotification.contentIntent);
-            }                
-            mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification);
-        }
-        
-    }
-
-    /**
-     * Checks if remotePath does not exist in the server and returns it, or adds a suffix to it in order to avoid the server
-     * file is overwritten.
-     * 
-     * @param string
-     * @return
-     */
-    private String getAvailableRemotePath(WebdavClient wc, String remotePath) {
-        Boolean check = wc.existsFile(remotePath);
-        if (check == null) {    // null means fail
-            return null;
-        } else if (!check) {
-            return remotePath;
-        }
-    
-        int pos = remotePath.lastIndexOf(".");
-        String suffix = "";
-        String extension = "";
-        if (pos >= 0) {
-            extension = remotePath.substring(pos+1);
-            remotePath = remotePath.substring(0, pos);
-        }
-        int count = 2;
-        while (check != null && check) {
-            suffix = " (" + count + ")";
-            if (pos >= 0)
-                check = wc.existsFile(remotePath + suffix + "." + extension);
-            else
-                check = wc.existsFile(remotePath + suffix);
-            count++;
-        }
-        if (check == null) {
-            return null;
-        } else if (pos >=0) {
-            return remotePath + suffix + "." + extension;
-        } else {
-            return remotePath + suffix;
-        }
-    }
-    
-    
-    /**
-     * Callback method to update the progress bar in the status notification.
-     */
-    @Override
-    public void transferProgress(long progressRate) {
-        mSendData += progressRate;
-        int percent = (int)(100*((double)mSendData)/((double)mTotalDataToSend));
-        if (percent != mPreviousPercent) {
-            String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, new File(mLocalPaths[mCurrentIndexUpload]).getName());
-            mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, false);
-            mNotification.contentView.setTextViewText(R.id.status_text, text);
-            mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification);
-        }
-        mPreviousPercent = percent;
-    }
-}
diff --git a/src/eu/alefzero/owncloud/files/services/InstantUploadService.java b/src/eu/alefzero/owncloud/files/services/InstantUploadService.java
deleted file mode 100644 (file)
index b666e59..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.files.services;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.apache.commons.httpclient.HttpException;
-import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.utils.OwnCloudVersion;
-import eu.alefzero.webdav.WebdavClient;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.Service;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.IBinder;
-import android.util.Log;
-
-public class InstantUploadService extends Service {
-
-    public static String KEY_FILE_PATH = "KEY_FILEPATH";
-    public static String KEY_FILE_SIZE = "KEY_FILESIZE";
-    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";
-    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)) {
-            Log.w(TAG, "Not all required information was provided, abording");
-            return Service.START_NOT_STICKY;
-        }
-        
-        if (mUploaderRunnable == null) {
-            mUploaderRunnable = new UploaderRunnable();
-        }
-        
-        String filename = intent.getStringExtra(KEY_DISPLAY_NAME);
-        String filepath = intent.getStringExtra(KEY_FILE_PATH);
-        String mimetype = intent.getStringExtra(KEY_MIME_TYPE);
-        Account account = intent.getParcelableExtra(KEY_ACCOUNT);
-        long filesize = intent.getLongExtra(KEY_FILE_SIZE, -1);
-        
-        mUploaderRunnable.addElementToQueue(filename, filepath, mimetype, filesize, account);
-        
-        // starting new thread for new download doesnt seems like a good idea
-        // maybe some thread pool or single background thread would be better
-        Log.d(TAG, "Starting instant upload thread");
-        new Thread(mUploaderRunnable).start();
-        
-        return Service.START_STICKY;
-    }
-    
-    private class UploaderRunnable implements Runnable {
-        
-        Object mLock;
-        List<HashMap<String, Object>> mHashMapList;
-        
-        public UploaderRunnable() {
-            mHashMapList = new LinkedList<HashMap<String, Object>>();
-            mLock = new Object();
-        }
-        
-        public void addElementToQueue(String filename,
-                                      String filepath,
-                                      String mimetype,
-                                      long length,
-                                      Account account) {
-            HashMap<String, Object> new_map = new HashMap<String, Object>();
-            new_map.put(KEY_ACCOUNT, account);
-            new_map.put(KEY_DISPLAY_NAME, filename);
-            new_map.put(KEY_FILE_PATH, filepath);
-            new_map.put(KEY_MIME_TYPE, mimetype);
-            new_map.put(KEY_FILE_SIZE, length);
-            
-            synchronized (mLock) {
-                mHashMapList.add(new_map);
-            }
-        }
-        
-        private HashMap<String, Object> getFirstObject() {
-            synchronized (mLock) {
-                if (mHashMapList.size() == 0)
-                    return null;
-                HashMap<String, Object> ret = mHashMapList.get(0);
-                mHashMapList.remove(0);
-                return ret;
-            }
-        }
-        
-        public void run() {
-            HashMap<String, Object> working_map;
-            AccountManager am = AccountManager.get(getApplicationContext());
-            
-            while ((working_map = getFirstObject()) != null) {
-                Account account = (Account) working_map.get(KEY_ACCOUNT);
-                String username = account.name.substring(0, account.name.lastIndexOf('@'));
-                String password = am.getPassword(account);
-                String filename = (String) working_map.get(KEY_DISPLAY_NAME);
-                String filepath = (String) working_map.get(KEY_FILE_PATH);
-                String mimetype = (String) working_map.get(KEY_MIME_TYPE);
-                
-                String oc_base_url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL);
-                String oc_version = am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION);
-                OwnCloudVersion ocv = new OwnCloudVersion(oc_version);
-                String webdav_path = AccountUtils.getWebdavPath(ocv);
-                WebdavClient wdc = new WebdavClient(account, getApplicationContext());
-                wdc.allowSelfsignedCertificates();
-                wdc.setCredentials(username, password);
-                
-                MkColMethod mkcol = new MkColMethod(oc_base_url+webdav_path+INSTANT_UPLOAD_DIR);
-                int status = 0;
-                try {
-                    status = wdc.executeMethod(mkcol);
-                    Log.e(TAG, "mkcol returned " + status);
-                    wdc.putFile(filepath, INSTANT_UPLOAD_DIR + "/" + filename, mimetype);
-                } catch (HttpException e) {
-                    e.printStackTrace();
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-    }
-    
-}
diff --git a/src/eu/alefzero/owncloud/files/services/OnUploadCompletedListener.java b/src/eu/alefzero/owncloud/files/services/OnUploadCompletedListener.java
deleted file mode 100644 (file)
index 99d0bfa..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-package eu.alefzero.owncloud.files.services;
-
-public interface OnUploadCompletedListener extends Runnable {
-
-    public boolean getUploadResult();
-
-    public void setUploadResult(boolean result);
-}
diff --git a/src/eu/alefzero/owncloud/location/LocationServiceLauncherReciever.java b/src/eu/alefzero/owncloud/location/LocationServiceLauncherReciever.java
deleted file mode 100644 (file)
index a435414..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  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 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 eu.alefzero.owncloud.location;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-public class LocationServiceLauncherReciever extends BroadcastReceiver {
-
-    private final String TAG = getClass().getSimpleName();
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        Intent deviceTrackingIntent = new Intent();
-        deviceTrackingIntent
-                .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
-        SharedPreferences preferences = PreferenceManager
-                .getDefaultSharedPreferences(context);
-        boolean trackDevice = preferences.getBoolean("enable_devicetracking",
-                true);
-
-        // Used in Preferences activity so that tracking is disabled or
-        // reenabled
-        if (intent.hasExtra("TRACKING_SETTING")) {
-            trackDevice = intent.getBooleanExtra("TRACKING_SETTING", true);
-        }
-
-        startOrStopDeviceTracking(context, trackDevice);
-    }
-
-    /**
-     * Used internally. Starts or stops the device tracking service
-     * 
-     * @param trackDevice true to start the service, false to stop it
-     */
-    private void startOrStopDeviceTracking(Context context, boolean trackDevice) {
-        Intent deviceTrackingIntent = new Intent();
-        deviceTrackingIntent
-                .setAction("eu.alefzero.owncloud.location.LocationUpdateService");
-        if (!isDeviceTrackingServiceRunning(context) && trackDevice) {
-            Log.d(TAG, "Starting device tracker service");
-            context.startService(deviceTrackingIntent);
-        } else if (isDeviceTrackingServiceRunning(context) && !trackDevice) {
-            Log.d(TAG, "Stopping device tracker service");
-            context.stopService(deviceTrackingIntent);
-        }
-    }
-
-    /**
-     * Checks to see whether or not the LocationUpdateService is running
-     * 
-     * @return true, if it is. Otherwise false
-     */
-    private boolean isDeviceTrackingServiceRunning(Context context) {
-        ActivityManager manager = (ActivityManager) context
-                .getSystemService(Context.ACTIVITY_SERVICE);
-        for (RunningServiceInfo service : manager
-                .getRunningServices(Integer.MAX_VALUE)) {
-            if (getClass().getName().equals(service.service.getClassName())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/location/LocationUpdateService.java b/src/eu/alefzero/owncloud/location/LocationUpdateService.java
deleted file mode 100644 (file)
index 96ae329..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  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 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 eu.alefzero.owncloud.location;
-
-import android.app.IntentService;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.location.Criteria;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
-import android.os.Bundle;
-import android.preference.PreferenceManager;
-import android.util.Log;
-import android.widget.Toast;
-
-public class LocationUpdateService extends IntentService implements
-        LocationListener {
-
-    public static final String TAG = "LocationUpdateService";
-
-    private LocationManager mLocationManager;
-    private LocationProvider mLocationProvider;
-    private SharedPreferences mPreferences;
-
-    public LocationUpdateService() {
-        super(TAG);
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
-        // Determine, how we can track the device
-        Criteria criteria = new Criteria();
-        criteria.setAccuracy(Criteria.ACCURACY_FINE);
-        criteria.setPowerRequirement(Criteria.POWER_LOW);
-        mLocationProvider = mLocationManager.getProvider(mLocationManager
-                .getBestProvider(criteria, true));
-
-        // Notify user if there is no way to track the device
-        if (mLocationProvider == null) {
-            Toast.makeText(this,
-                    eu.alefzero.owncloud.R.string.location_no_provider,
-                    Toast.LENGTH_LONG);
-            stopSelf();
-            return;
-        }
-
-        // Get preferences for device tracking
-        mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
-        boolean trackDevice = mPreferences.getBoolean("enable_devicetracking",
-                true);
-        int updateIntervall = Integer.parseInt(mPreferences.getString(
-                "devicetracking_update_intervall", "30")) * 60 * 1000;
-        int distanceBetweenLocationChecks = 50;
-
-        // If we do shall track the device -> Stop
-        if (!trackDevice) {
-            Log.d(TAG, "Devicetracking is disabled");
-            stopSelf();
-            return;
-        }
-
-        mLocationManager.requestLocationUpdates(mLocationProvider.getName(),
-                updateIntervall, distanceBetweenLocationChecks, this);
-    }
-
-    @Override
-    public void onLocationChanged(Location location) {
-        Log.d(TAG, "Location changed: " + location);
-
-    }
-
-    @Override
-    public void onProviderDisabled(String arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void onProviderEnabled(String arg0) {
-        // TODO Auto-generated method stub
-
-    }
-
-    @Override
-    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
-        // TODO Auto-generated method stub
-
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/providers/FileContentProvider.java b/src/eu/alefzero/owncloud/providers/FileContentProvider.java
deleted file mode 100644 (file)
index 7ed73a9..0000000
+++ /dev/null
@@ -1,237 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.providers;\r
-\r
-import java.util.HashMap;\r
-\r
-import eu.alefzero.owncloud.db.ProviderMeta;\r
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
-\r
-import android.content.ContentProvider;\r
-import android.content.ContentUris;\r
-import android.content.ContentValues;\r
-import android.content.Context;\r
-import android.content.UriMatcher;\r
-import android.database.Cursor;\r
-import android.database.SQLException;\r
-import android.database.sqlite.SQLiteDatabase;\r
-import android.database.sqlite.SQLiteOpenHelper;\r
-import android.database.sqlite.SQLiteQueryBuilder;\r
-import android.net.Uri;\r
-import android.text.TextUtils;\r
-import android.util.Log;\r
-\r
-/**\r
- * The ContentProvider for the ownCloud App.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class FileContentProvider extends ContentProvider {\r
-\r
-    private DataBaseHelper mDbHelper;\r
-\r
-    private static HashMap<String, String> mProjectionMap;\r
-    static {\r
-        mProjectionMap = new HashMap<String, String>();\r
-        mProjectionMap.put(ProviderTableMeta._ID, ProviderTableMeta._ID);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_PARENT,\r
-                ProviderTableMeta.FILE_PARENT);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_PATH,\r
-                ProviderTableMeta.FILE_PATH);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_NAME,\r
-                ProviderTableMeta.FILE_NAME);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_CREATION,\r
-                ProviderTableMeta.FILE_CREATION);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,\r
-                ProviderTableMeta.FILE_MODIFIED);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,\r
-                ProviderTableMeta.FILE_CONTENT_LENGTH);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,\r
-                ProviderTableMeta.FILE_CONTENT_TYPE);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,\r
-                ProviderTableMeta.FILE_STORAGE_PATH);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_LAST_SYNC_DATE,\r
-                ProviderTableMeta.FILE_LAST_SYNC_DATE);\r
-        mProjectionMap.put(ProviderTableMeta.FILE_KEEP_IN_SYNC,\r
-                ProviderTableMeta.FILE_KEEP_IN_SYNC);\r
-    }\r
-\r
-    private static final int SINGLE_FILE = 1;\r
-    private static final int DIRECTORY = 2;\r
-    private static final int ROOT_DIRECTORY = 3;\r
-    private static final UriMatcher mUriMatcher;\r
-    static {\r
-        mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);\r
-        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);\r
-        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);\r
-        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);\r
-        mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);\r
-    }\r
-\r
-    @Override\r
-    public int delete(Uri uri, String where, String[] whereArgs) {\r
-        SQLiteDatabase db = mDbHelper.getWritableDatabase();\r
-        int count = 0;\r
-        switch (mUriMatcher.match(uri)) {\r
-        case SINGLE_FILE:\r
-            count = db.delete(ProviderTableMeta.DB_NAME,\r
-                    ProviderTableMeta._ID\r
-                            + "="\r
-                            + uri.getPathSegments().get(1)\r
-                            + (!TextUtils.isEmpty(where) ? " AND (" + where\r
-                                    + ")" : ""), whereArgs);\r
-            break;\r
-        case ROOT_DIRECTORY:\r
-            count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);\r
-            break;\r
-        default:\r
-            throw new IllegalArgumentException("Unknown uri: " + uri.toString());\r
-        }\r
-        getContext().getContentResolver().notifyChange(uri, null);\r
-        return count;\r
-    }\r
-\r
-    @Override\r
-    public String getType(Uri uri) {\r
-        switch (mUriMatcher.match(uri)) {\r
-        case ROOT_DIRECTORY:\r
-            return ProviderTableMeta.CONTENT_TYPE;\r
-        case SINGLE_FILE:\r
-            return ProviderTableMeta.CONTENT_TYPE_ITEM;\r
-        default:\r
-            throw new IllegalArgumentException("Unknown Uri id."\r
-                    + uri.toString());\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public Uri insert(Uri uri, ContentValues values) {\r
-        if (mUriMatcher.match(uri) != SINGLE_FILE &&\r
-            mUriMatcher.match(uri) != ROOT_DIRECTORY) {\r
-            \r
-            throw new IllegalArgumentException("Unknown uri id: " + uri);\r
-        }\r
-\r
-        SQLiteDatabase db = mDbHelper.getWritableDatabase();\r
-        long rowId = db.insert(ProviderTableMeta.DB_NAME, null, values);\r
-        if (rowId > 0) {\r
-            Uri insertedFileUri = ContentUris.withAppendedId(\r
-                    ProviderTableMeta.CONTENT_URI_FILE, rowId);\r
-            getContext().getContentResolver().notifyChange(insertedFileUri,\r
-                    null);\r
-            return insertedFileUri;\r
-        }\r
-        throw new SQLException("ERROR " + uri);\r
-    }\r
-\r
-    @Override\r
-    public boolean onCreate() {\r
-        mDbHelper = new DataBaseHelper(getContext());\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public Cursor query(Uri uri, String[] projection, String selection,\r
-            String[] selectionArgs, String sortOrder) {\r
-        SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();\r
-\r
-        sqlQuery.setTables(ProviderTableMeta.DB_NAME);\r
-        sqlQuery.setProjectionMap(mProjectionMap);\r
-\r
-        switch (mUriMatcher.match(uri)) {\r
-        case ROOT_DIRECTORY:\r
-            break;\r
-        case DIRECTORY:\r
-            sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="\r
-                    + uri.getPathSegments().get(1));\r
-            break;\r
-        case SINGLE_FILE:\r
-            if (uri.getPathSegments().size() > 1) {\r
-                sqlQuery.appendWhere(ProviderTableMeta._ID + "="\r
-                        + uri.getPathSegments().get(1));\r
-            }\r
-            break;\r
-        default:\r
-            throw new IllegalArgumentException("Unknown uri id: " + uri);\r
-        }\r
-\r
-        String order;\r
-        if (TextUtils.isEmpty(sortOrder)) {\r
-            order = ProviderTableMeta.DEFAULT_SORT_ORDER;\r
-        } else {\r
-            order = sortOrder;\r
-        }\r
-\r
-        SQLiteDatabase db = mDbHelper.getReadableDatabase();\r
-        Cursor c = sqlQuery.query(db, projection, selection, selectionArgs,\r
-                null, null, order);\r
-\r
-        c.setNotificationUri(getContext().getContentResolver(), uri);\r
-\r
-        return c;\r
-    }\r
-\r
-    @Override\r
-    public int update(Uri uri, ContentValues values, String selection,\r
-            String[] selectionArgs) {\r
-        return mDbHelper.getWritableDatabase().update(\r
-                ProviderTableMeta.DB_NAME, values, selection, selectionArgs);\r
-    }\r
-\r
-    class DataBaseHelper extends SQLiteOpenHelper {\r
-\r
-        public DataBaseHelper(Context context) {\r
-            super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);\r
-\r
-        }\r
-\r
-        @Override\r
-        public void onCreate(SQLiteDatabase db) {\r
-            // files table\r
-            Log.i("SQL", "Entering in onCreate");\r
-            db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "("\r
-                    + ProviderTableMeta._ID + " INTEGER PRIMARY KEY, "\r
-                    + ProviderTableMeta.FILE_NAME + " TEXT, "\r
-                    + ProviderTableMeta.FILE_PATH + " TEXT, "\r
-                    + ProviderTableMeta.FILE_PARENT + " INTEGER, "\r
-                    + ProviderTableMeta.FILE_CREATION + " INTEGER, "\r
-                    + ProviderTableMeta.FILE_MODIFIED + " INTEGER, "\r
-                    + ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, "\r
-                    + ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, "\r
-                    + ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, "\r
-                    + ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT, "\r
-                    + ProviderTableMeta.FILE_LAST_SYNC_DATE + " INTEGER, "\r
-                    + ProviderTableMeta.FILE_KEEP_IN_SYNC + " INTEGER );");\r
-        }\r
-\r
-        @Override\r
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
-            Log.i("SQL", "Entering in onUpgrade");\r
-            if (oldVersion == 1 && newVersion >= 2) {\r
-                Log.i("SQL", "Entering in the ADD in onUpgrade");\r
-                db.execSQL("ALTER TABLE " + ProviderTableMeta.DB_NAME +\r
-                           " ADD COLUMN " + ProviderTableMeta.FILE_KEEP_IN_SYNC  + " INTEGER " +\r
-                           " DEFAULT 0");\r
-            } else Log.i("SQL", "OUT of the ADD in onUpgrade; oldVersion == " + oldVersion + ", newVersion == " + newVersion);\r
-        }\r
-\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
deleted file mode 100644 (file)
index fa982e7..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.syncadapter;\r
-\r
-import java.io.IOException;\r
-import java.net.UnknownHostException;\r
-import java.util.Date;\r
-\r
-import org.apache.http.HttpRequest;\r
-import org.apache.http.HttpResponse;\r
-import org.apache.http.client.ClientProtocolException;\r
-import org.apache.http.conn.ConnectionKeepAliveStrategy;\r
-import org.apache.http.protocol.HttpContext;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.accounts.AuthenticatorException;\r
-import android.accounts.OperationCanceledException;\r
-import android.content.AbstractThreadedSyncAdapter;\r
-import android.content.ContentProviderClient;\r
-import android.content.Context;\r
-import android.net.Uri;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.datamodel.DataStorageManager;\r
-import eu.alefzero.webdav.WebdavClient;\r
-\r
-/**\r
- * Base SyncAdapter for OwnCloud Designed to be subclassed for the concrete\r
- * SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..\r
- * \r
- * @author sassman\r
- * \r
- */\r
-public abstract class AbstractOwnCloudSyncAdapter extends\r
-        AbstractThreadedSyncAdapter {\r
-\r
-    private AccountManager accountManager;\r
-    private Account account;\r
-    private ContentProviderClient contentProvider;\r
-    private Date lastUpdated;\r
-    private DataStorageManager mStoreManager;\r
-\r
-    private WebdavClient mClient = null;\r
-\r
-    public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {\r
-        super(context, autoInitialize);\r
-        this.setAccountManager(AccountManager.get(context));\r
-    }\r
-\r
-    public AccountManager getAccountManager() {\r
-        return accountManager;\r
-    }\r
-\r
-    public void setAccountManager(AccountManager accountManager) {\r
-        this.accountManager = accountManager;\r
-    }\r
-\r
-    public Account getAccount() {\r
-        return account;\r
-    }\r
-\r
-    public void setAccount(Account account) {\r
-        this.account = account;\r
-    }\r
-\r
-    public ContentProviderClient getContentProvider() {\r
-        return contentProvider;\r
-    }\r
-\r
-    public void setContentProvider(ContentProviderClient contentProvider) {\r
-        this.contentProvider = contentProvider;\r
-    }\r
-\r
-    public Date getLastUpdated() {\r
-        return lastUpdated;\r
-    }\r
-\r
-    public void setLastUpdated(Date lastUpdated) {\r
-        this.lastUpdated = lastUpdated;\r
-    }\r
-\r
-    public void setStorageManager(DataStorageManager storage_manager) {\r
-        mStoreManager = storage_manager;\r
-    }\r
-\r
-    public DataStorageManager getStorageManager() {\r
-        return mStoreManager;\r
-    }\r
-\r
-    protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {\r
-        return new ConnectionKeepAliveStrategy() {\r
-            public long getKeepAliveDuration(HttpResponse response,\r
-                    HttpContext context) {\r
-                // Change keep alive straategy basing on response: ie\r
-                // forbidden/not found/etc\r
-                // should have keep alive 0\r
-                // default return: 5s\r
-                int statusCode = response.getStatusLine().getStatusCode();\r
-\r
-                // HTTP 400, 500 Errors as well as HTTP 118 - Connection timed\r
-                // out\r
-                if ((statusCode >= 400 && statusCode <= 418)\r
-                        || (statusCode >= 421 && statusCode <= 426)\r
-                        || (statusCode >= 500 && statusCode <= 510)\r
-                        || statusCode == 118) {\r
-                    return 0;\r
-                }\r
-\r
-                return 5 * 1000;\r
-            }\r
-        };\r
-    }\r
-\r
-    protected HttpResponse fireRawRequest(HttpRequest query)\r
-            throws ClientProtocolException, OperationCanceledException,\r
-            AuthenticatorException, IOException {\r
-        /*\r
-         * BasicHttpContext httpContext = new BasicHttpContext(); BasicScheme\r
-         * basicAuth = new BasicScheme();\r
-         * httpContext.setAttribute("preemptive-auth", basicAuth);\r
-         * \r
-         * HttpResponse response = getClient().execute(mHost, query,\r
-         * httpContext);\r
-         */\r
-        return null;\r
-    }\r
-\r
-    protected Uri getUri() {\r
-        return Uri.parse(this.getAccountManager().getUserData(getAccount(),\r
-                AccountAuthenticator.KEY_OC_URL));\r
-    }\r
-\r
-    protected WebdavClient getClient() throws OperationCanceledException,\r
-            AuthenticatorException, IOException {\r
-        if (mClient == null) {\r
-            if (this.getAccountManager().getUserData(getAccount(),\r
-                    AccountAuthenticator.KEY_OC_URL) == null) {\r
-                throw new UnknownHostException();\r
-            }\r
-            mClient = new WebdavClient(account, getContext());\r
-            mClient.allowSelfsignedCertificates();\r
-            // mHost = mClient.getTargetHost();\r
-        }\r
-\r
-        return mClient;\r
-    }\r
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/ContactSyncAdapter.java
deleted file mode 100644 (file)
index b0ab956..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.entity.ByteArrayEntity;
-
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.content.SyncResult;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.util.Log;
-
-public class ContactSyncAdapter extends AbstractOwnCloudSyncAdapter {
-    private String mAddrBookUri;
-
-    public ContactSyncAdapter(Context context, boolean autoInitialize) {
-        super(context, autoInitialize);
-        mAddrBookUri = null;
-    }
-
-    @Override
-    public void onPerformSync(Account account, Bundle extras, String authority,
-            ContentProviderClient provider, SyncResult syncResult) {
-        setAccount(account);
-        setContentProvider(provider);
-        Cursor c = getLocalContacts(false);
-        if (c.moveToFirst()) {
-            do {
-                String lookup = c.getString(c
-                        .getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
-                String a = getAddressBookUri();
-                String uri = a + lookup + ".vcf";
-                FileInputStream f;
-                try {
-                    f = getContactVcard(lookup);
-                    HttpPut query = new HttpPut(uri);
-                    byte[] b = new byte[f.available()];
-                    f.read(b);
-                    query.setEntity(new ByteArrayEntity(b));
-                    HttpResponse response = fireRawRequest(query);
-                } catch (IOException e) {
-                    e.printStackTrace();
-                    return;
-                } catch (OperationCanceledException e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                } catch (AuthenticatorException e) {
-                    // TODO Auto-generated catch block
-                    e.printStackTrace();
-                }
-            } while (c.moveToNext());
-            // } while (c.moveToNext());
-        }
-
-    }
-
-    private String getAddressBookUri() {
-        if (mAddrBookUri != null)
-            return mAddrBookUri;
-
-        AccountManager am = getAccountManager();
-        String uri = am.getUserData(getAccount(),
-                AccountAuthenticator.KEY_OC_URL).replace(
-                AccountUtils.WEBDAV_PATH_2_0, AccountUtils.CARDDAV_PATH_2_0);
-        uri += "/addressbooks/"
-                + getAccount().name.substring(0,
-                        getAccount().name.lastIndexOf('@')) + "/default/";
-        mAddrBookUri = uri;
-        return uri;
-    }
-
-    private FileInputStream getContactVcard(String lookupKey)
-            throws IOException {
-        Uri uri = Uri.withAppendedPath(
-                ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
-        AssetFileDescriptor fd = getContext().getContentResolver()
-                .openAssetFileDescriptor(uri, "r");
-        return fd.createInputStream();
-    }
-
-    private Cursor getLocalContacts(boolean include_hidden_contacts) {
-        return getContext().getContentResolver().query(
-                ContactsContract.Contacts.CONTENT_URI,
-                new String[] { ContactsContract.Contacts._ID,
-                        ContactsContract.Contacts.LOOKUP_KEY },
-                ContactsContract.Contacts.IN_VISIBLE_GROUP + " = ?",
-                new String[] { (include_hidden_contacts ? "0" : "1") },
-                ContactsContract.Contacts._ID + " DESC");
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java b/src/eu/alefzero/owncloud/syncadapter/ContactSyncService.java
deleted file mode 100644 (file)
index 465a940..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package eu.alefzero.owncloud.syncadapter;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class ContactSyncService extends Service {
-    private static final Object syncAdapterLock = new Object();
-    private static AbstractOwnCloudSyncAdapter mSyncAdapter = null;
-
-    @Override
-    public void onCreate() {
-        synchronized (syncAdapterLock) {
-            if (mSyncAdapter == null) {
-                mSyncAdapter = new ContactSyncAdapter(getApplicationContext(),
-                        true);
-            }
-        }
-    }
-
-    @Override
-    public IBinder onBind(Intent arg0) {
-        return mSyncAdapter.getSyncAdapterBinder();
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java b/src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
deleted file mode 100644 (file)
index 8be8dff..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.syncadapter;\r
-\r
-import java.io.IOException;\r
-import java.util.List;\r
-import java.util.Vector;\r
-\r
-import org.apache.jackrabbit.webdav.DavException;\r
-import org.apache.jackrabbit.webdav.MultiStatus;\r
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AuthenticatorException;\r
-import android.accounts.OperationCanceledException;\r
-import android.content.ContentProviderClient;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.SyncResult;\r
-import android.os.Bundle;\r
-import android.util.Log;\r
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.files.services.FileDownloader;\r
-import eu.alefzero.webdav.WebdavEntry;\r
-import eu.alefzero.webdav.WebdavUtils;\r
-\r
-/**\r
- * SyncAdapter implementation for syncing sample SyncAdapter contacts to the\r
- * platform ContactOperations provider.\r
- * \r
- * @author Bartek Przybylski\r
- */\r
-public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {\r
-\r
-    private final static String TAG = "FileSyncAdapter"; \r
-    \r
-    /*  Commented code for ugly performance tests\r
-    private final static int MAX_DELAYS = 100;\r
-    private static long[] mResponseDelays = new long[MAX_DELAYS]; \r
-    private static long[] mSaveDelays = new long[MAX_DELAYS];\r
-    private int mDelaysIndex = 0;\r
-    private int mDelaysCount = 0;\r
-    */\r
-    \r
-    private long mCurrentSyncTime;\r
-    private boolean mCancellation;\r
-    private Account mAccount;\r
-    \r
-    public FileSyncAdapter(Context context, boolean autoInitialize) {\r
-        super(context, autoInitialize);\r
-    }\r
-\r
-    @Override\r
-    public synchronized void onPerformSync(Account account, Bundle extras,\r
-            String authority, ContentProviderClient provider,\r
-            SyncResult syncResult) {\r
-\r
-        mCancellation = false;\r
-        mAccount = account;\r
-        \r
-        this.setAccount(mAccount);\r
-        this.setContentProvider(provider);\r
-        this.setStorageManager(new FileDataStorageManager(mAccount,\r
-                getContentProvider()));\r
-        \r
-        /*  Commented code for ugly performance tests\r
-        mDelaysIndex = 0;\r
-        mDelaysCount = 0;\r
-        */\r
-        \r
-        \r
-        Log.d(TAG, "syncing owncloud account " + mAccount.name);\r
-\r
-        sendStickyBroadcast(true, null);  // message to signal the start to the UI\r
-\r
-        PropFindMethod query;\r
-        try {\r
-            mCurrentSyncTime = System.currentTimeMillis();\r
-            query = new PropFindMethod(getUri().toString() + "/");\r
-            getClient().executeMethod(query);\r
-            MultiStatus resp = null;\r
-            resp = query.getResponseBodyAsMultiStatus();\r
-\r
-            if (resp.getResponses().length > 0) {\r
-                WebdavEntry we = new WebdavEntry(resp.getResponses()[0], getUri().getPath());\r
-                OCFile file = fillOCFile(we);\r
-                file.setParentId(0);\r
-                getStorageManager().saveFile(file);\r
-                if (!mCancellation) {\r
-                    fetchData(getUri().toString(), syncResult, file.getFileId());\r
-                }\r
-            }\r
-        } catch (OperationCanceledException e) {\r
-            e.printStackTrace();\r
-        } catch (AuthenticatorException e) {\r
-            syncResult.stats.numAuthExceptions++;\r
-            e.printStackTrace();\r
-        } catch (IOException e) {\r
-            syncResult.stats.numIoExceptions++;\r
-            e.printStackTrace();\r
-        } catch (DavException e) {\r
-            syncResult.stats.numIoExceptions++;\r
-            e.printStackTrace();\r
-        } catch (Throwable t) {\r
-            // TODO update syncResult\r
-            Log.e(TAG, "problem while synchronizing owncloud account " + account.name, t);\r
-            t.printStackTrace();\r
-        }\r
-        \r
-        /*  Commented code for ugly performance tests\r
-        long sum = 0, mean = 0, max = 0, min = Long.MAX_VALUE;\r
-        for (int i=0; i<MAX_DELAYS && i<mDelaysCount; i++) {\r
-            sum += mResponseDelays[i];\r
-            max = Math.max(max, mResponseDelays[i]);\r
-            min = Math.min(min, mResponseDelays[i]);\r
-        }\r
-        mean = sum / mDelaysCount;\r
-        Log.e(TAG, "SYNC STATS - response: mean time = " + mean + " ; max time = " + max + " ; min time = " + min);\r
-        \r
-        sum = 0; max = 0; min = Long.MAX_VALUE;\r
-        for (int i=0; i<MAX_DELAYS && i<mDelaysCount; i++) {\r
-            sum += mSaveDelays[i];\r
-            max = Math.max(max, mSaveDelays[i]);\r
-            min = Math.min(min, mSaveDelays[i]);\r
-        }\r
-        mean = sum / mDelaysCount;\r
-        Log.e(TAG, "SYNC STATS - save:     mean time = " + mean + " ; max time = " + max + " ; min time = " + min);\r
-        Log.e(TAG, "SYNC STATS - folders measured: " + mDelaysCount);\r
-        */\r
-        \r
-        sendStickyBroadcast(false, null);        \r
-    }\r
-\r
-    private void fetchData(String uri, SyncResult syncResult, long parentId) {\r
-        try {\r
-            Log.d(TAG, "fetching " + uri);\r
-            \r
-            // remote request \r
-            PropFindMethod query = new PropFindMethod(uri);\r
-            /*  Commented code for ugly performance tests\r
-            long responseDelay = System.currentTimeMillis();\r
-            */\r
-            getClient().executeMethod(query);\r
-            /*  Commented code for ugly performance tests\r
-            responseDelay = System.currentTimeMillis() - responseDelay;\r
-            Log.e(TAG, "syncing: RESPONSE TIME for " + uri + " contents, " + responseDelay + "ms");\r
-            */\r
-            MultiStatus resp = null;\r
-            resp = query.getResponseBodyAsMultiStatus();\r
-            \r
-            // insertion or update of files\r
-            List<OCFile> updatedFiles = new Vector<OCFile>(resp.getResponses().length - 1);\r
-            for (int i = 1; i < resp.getResponses().length; ++i) {\r
-                WebdavEntry we = new WebdavEntry(resp.getResponses()[i], getUri().getPath());\r
-                OCFile file = fillOCFile(we);\r
-                file.setParentId(parentId);\r
-                if (getStorageManager().getFileByPath(file.getRemotePath()) != null &&\r
-                    getStorageManager().getFileByPath(file.getRemotePath()).keepInSync() &&\r
-                    file.getModificationTimestamp() > getStorageManager().getFileByPath(file.getRemotePath())\r
-                                                                         .getModificationTimestamp()) {\r
-                    Intent intent = new Intent(this.getContext(), FileDownloader.class);\r
-                    intent.putExtra(FileDownloader.EXTRA_ACCOUNT, getAccount());\r
-                    intent.putExtra(FileDownloader.EXTRA_FILE_PATH, file.getRemotePath());\r
-                    intent.putExtra(FileDownloader.EXTRA_REMOTE_PATH, file.getRemotePath());\r
-                    intent.putExtra(FileDownloader.EXTRA_FILE_SIZE, file.getFileLength());\r
-                    file.setKeepInSync(true);\r
-                    getContext().startService(intent);\r
-                }\r
-                if (getStorageManager().getFileByPath(file.getRemotePath()) != null)\r
-                    file.setKeepInSync(getStorageManager().getFileByPath(file.getRemotePath()).keepInSync());\r
-                \r
-                //Log.v(TAG, "adding file: " + file);\r
-                updatedFiles.add(file);\r
-                if (parentId == 0)\r
-                    parentId = file.getFileId();\r
-            }\r
-            /*  Commented code for ugly performance tests\r
-            long saveDelay = System.currentTimeMillis();\r
-            */            \r
-            getStorageManager().saveFiles(updatedFiles);    // all "at once" ; trying to get a best performance in database update\r
-            /*  Commented code for ugly performance tests\r
-            saveDelay = System.currentTimeMillis() - saveDelay;\r
-            Log.e(TAG, "syncing: SAVE TIME for " + uri + " contents, " + mSaveDelays[mDelaysIndex] + "ms");\r
-            */\r
-            \r
-            // removal of obsolete files\r
-            Vector<OCFile> files = getStorageManager().getDirectoryContent(\r
-                    getStorageManager().getFileById(parentId));\r
-            OCFile file;\r
-            for (int i=0; i < files.size(); ) {\r
-                file = files.get(i);\r
-                if (file.getLastSyncDate() != mCurrentSyncTime) {\r
-                    Log.v(TAG, "removing file: " + file);\r
-                    getStorageManager().removeFile(file);\r
-                    files.remove(i);\r
-                } else {\r
-                    i++;\r
-                }\r
-            }\r
-            \r
-            // synchronized folder -> notice to UI\r
-            sendStickyBroadcast(true, getStorageManager().getFileById(parentId).getRemotePath());\r
-\r
-            // recursive fetch\r
-            for (int i=0; i < files.size() && !mCancellation; i++) {\r
-                OCFile newFile = files.get(i);\r
-                if (newFile.getMimetype().equals("DIR")) {\r
-                    fetchData(getUri().toString() + WebdavUtils.encodePath(newFile.getRemotePath()), syncResult, newFile.getFileId());\r
-                }\r
-            }\r
-            if (mCancellation) Log.d(TAG, "Leaving " + uri + " because cancelation request");\r
-                \r
-            /*  Commented code for ugly performance tests\r
-            mResponseDelays[mDelaysIndex] = responseDelay;\r
-            mSaveDelays[mDelaysIndex] = saveDelay;\r
-            mDelaysCount++;\r
-            mDelaysIndex++;\r
-            if (mDelaysIndex >= MAX_DELAYS)\r
-                mDelaysIndex = 0;\r
-             */\r
-            \r
-\r
-\r
-        } catch (OperationCanceledException e) {\r
-            e.printStackTrace();\r
-        } catch (AuthenticatorException e) {\r
-            syncResult.stats.numAuthExceptions++;\r
-            e.printStackTrace();\r
-        } catch (IOException e) {\r
-            syncResult.stats.numIoExceptions++;\r
-            e.printStackTrace();\r
-        } catch (DavException e) {\r
-            syncResult.stats.numIoExceptions++;\r
-            e.printStackTrace();\r
-        } catch (Throwable t) {\r
-            // TODO update syncResult\r
-            Log.e(TAG, "problem while synchronizing owncloud account " + mAccount.name, t);\r
-            t.printStackTrace();\r
-        }\r
-    }\r
-\r
-    private OCFile fillOCFile(WebdavEntry we) {\r
-        OCFile file = new OCFile(we.decodedPath());\r
-        file.setCreationTimestamp(we.createTimestamp());\r
-        file.setFileLength(we.contentLength());\r
-        file.setMimetype(we.contentType());\r
-        file.setModificationTimestamp(we.modifiedTimesamp());\r
-        file.setLastSyncDate(mCurrentSyncTime);\r
-        return file;\r
-    }\r
-    \r
-    \r
-    private void sendStickyBroadcast(boolean inProgress, String dirRemotePath) {\r
-        Intent i = new Intent(FileSyncService.SYNC_MESSAGE);\r
-        i.putExtra(FileSyncService.IN_PROGRESS, inProgress);\r
-        i.putExtra(FileSyncService.ACCOUNT_NAME, getAccount().name);\r
-        if (dirRemotePath != null) {\r
-            i.putExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH, dirRemotePath);\r
-        }\r
-        getContext().sendStickyBroadcast(i);\r
-    }\r
-    \r
-    /**\r
-     * Called by system SyncManager when a synchronization is required to be cancelled.\r
-     * \r
-     * Sets the mCancellation flag to 'true'. THe synchronization will be stopped when before a new folder is fetched. Data of the last folder\r
-     * fetched will be still saved in the database. See onPerformSync implementation.\r
-     */\r
-    @Override\r
-    public void onSyncCanceled() {\r
-        Log.d(TAG, "Synchronization of " + mAccount.name + " has been requested to cancell");\r
-        mCancellation = true;\r
-        super.onSyncCanceled();\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java b/src/eu/alefzero/owncloud/syncadapter/FileSyncService.java
deleted file mode 100644 (file)
index 5396f58..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.syncadapter;\r
-\r
-import android.app.Service;\r
-import android.content.Intent;\r
-import android.os.IBinder;\r
-\r
-/**\r
- * Background service for syncing files to our local Database\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class FileSyncService extends Service {\r
-    public static final String SYNC_MESSAGE = "ACCOUNT_SYNC";\r
-    public static final String SYNC_FOLDER_REMOTE_PATH = "SYNC_FOLDER_REMOTE_PATH";\r
-    public static final String IN_PROGRESS = "SYNC_IN_PROGRESS";\r
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";\r
-\r
-    /*\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onCreate() {\r
-    }\r
-\r
-    /*\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public IBinder onBind(Intent intent) {\r
-       return new FileSyncAdapter(getApplicationContext(), true).getSyncAdapterBinder();\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/ActionItem.java b/src/eu/alefzero/owncloud/ui/ActionItem.java
deleted file mode 100644 (file)
index 6f96f19..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui;\r
-\r
-import android.graphics.drawable.Drawable;\r
-import android.view.View.OnClickListener;\r
-\r
-/**\r
- * Represents an Item on the ActionBar.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class ActionItem {\r
-    private Drawable mIcon;\r
-    private String mTitle;\r
-    private OnClickListener mClickListener;\r
-\r
-    public ActionItem() {\r
-    }\r
-\r
-    public void setTitle(String title) {\r
-        mTitle = title;\r
-    }\r
-\r
-    public String getTitle() {\r
-        return mTitle;\r
-    }\r
-\r
-    public void setIcon(Drawable icon) {\r
-        mIcon = icon;\r
-    }\r
-\r
-    public Drawable getIcon() {\r
-        return mIcon;\r
-    }\r
-\r
-    public void setOnClickListener(OnClickListener listener) {\r
-        mClickListener = listener;\r
-    }\r
-\r
-    public OnClickListener getOnClickListerner() {\r
-        return mClickListener;\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/CustomPopup.java b/src/eu/alefzero/owncloud/ui/CustomPopup.java
deleted file mode 100644 (file)
index cd8d845..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui;\r
-\r
-import android.content.Context;\r
-import android.graphics.Rect;\r
-import android.graphics.drawable.BitmapDrawable;\r
-import android.graphics.drawable.Drawable;\r
-import android.view.Gravity;\r
-import android.view.LayoutInflater;\r
-import android.view.MotionEvent;\r
-import android.view.View;\r
-import android.view.WindowManager;\r
-import android.view.View.OnTouchListener;\r
-import android.view.ViewGroup.LayoutParams;\r
-import android.widget.PopupWindow;\r
-\r
-/**\r
- * Represents a custom PopupWindows\r
- * \r
- * @author Lorensius. W. T\r
- * \r
- */\r
-public class CustomPopup {\r
-    protected final View mAnchor;\r
-    protected final PopupWindow mWindow;\r
-    private View root;\r
-    private Drawable background = null;\r
-    protected final WindowManager mWManager;\r
-\r
-    public CustomPopup(View anchor) {\r
-        mAnchor = anchor;\r
-        mWindow = new PopupWindow(anchor.getContext());\r
-\r
-        mWindow.setTouchInterceptor(new OnTouchListener() {\r
-\r
-            public boolean onTouch(View v, MotionEvent event) {\r
-                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {\r
-                    CustomPopup.this.dismiss();\r
-                    return true;\r
-                }\r
-                return false;\r
-            }\r
-        });\r
-\r
-        mWManager = (WindowManager) anchor.getContext().getSystemService(\r
-                Context.WINDOW_SERVICE);\r
-        onCreate();\r
-    }\r
-\r
-    public void onCreate() {\r
-    }\r
-\r
-    public void onShow() {\r
-    }\r
-\r
-    public void preShow() {\r
-        if (root == null) {\r
-            throw new IllegalStateException(\r
-                    "setContentView called with a view to display");\r
-        }\r
-\r
-        onShow();\r
-\r
-        if (background == null) {\r
-            mWindow.setBackgroundDrawable(new BitmapDrawable());\r
-        } else {\r
-            mWindow.setBackgroundDrawable(background);\r
-        }\r
-\r
-        mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);\r
-        mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);\r
-        mWindow.setTouchable(true);\r
-        mWindow.setFocusable(true);\r
-        mWindow.setOutsideTouchable(true);\r
-\r
-        mWindow.setContentView(root);\r
-    }\r
-\r
-    public void setBackgroundDrawable(Drawable background) {\r
-        this.background = background;\r
-    }\r
-\r
-    public void setContentView(View root) {\r
-        this.root = root;\r
-        mWindow.setContentView(root);\r
-    }\r
-\r
-    public void setContentView(int layoutResId) {\r
-        LayoutInflater inflater = (LayoutInflater) mAnchor.getContext()\r
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
-        setContentView(inflater.inflate(layoutResId, null));\r
-    }\r
-\r
-    public void showDropDown() {\r
-        showDropDown(0, 0);\r
-    }\r
-\r
-    public void showDropDown(int x, int y) {\r
-        preShow();\r
-        mWindow.setAnimationStyle(android.R.style.Animation_Dialog);\r
-        mWindow.showAsDropDown(mAnchor, x, y);\r
-    }\r
-\r
-    public void showLikeQuickAction() {\r
-        showLikeQuickAction(0, 0);\r
-    }\r
-\r
-    public void showLikeQuickAction(int x, int y) {\r
-        preShow();\r
-\r
-        mWindow.setAnimationStyle(android.R.style.Animation_Dialog);\r
-        int[] location = new int[2];\r
-        mAnchor.getLocationOnScreen(location);\r
-\r
-        Rect anchorRect = new Rect(location[0], location[1], location[0]\r
-                + mAnchor.getWidth(), location[1] + mAnchor.getHeight());\r
-\r
-        root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,\r
-                LayoutParams.WRAP_CONTENT));\r
-        root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
-\r
-        int rootW = root.getWidth(), rootH = root.getHeight();\r
-        int screenW = mWManager.getDefaultDisplay().getWidth();\r
-\r
-        int xpos = ((screenW - rootW) / 2) + x;\r
-        int ypos = anchorRect.top - rootH + y;\r
-\r
-        if (rootH > anchorRect.top) {\r
-            ypos = anchorRect.bottom + y;\r
-        }\r
-        mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);\r
-    }\r
-\r
-    public void dismiss() {\r
-        mWindow.dismiss();\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/FragmentListView.java b/src/eu/alefzero/owncloud/ui/FragmentListView.java
deleted file mode 100644 (file)
index 17e6483..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-package eu.alefzero.owncloud.ui;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.AdapterView.OnItemClickListener;
-
-public class FragmentListView extends SherlockFragment implements
-        OnItemClickListener, OnItemLongClickListener {
-    ListView mList;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-    }
-
-    public void setListAdapter(ListAdapter listAdapter) {
-        mList.setAdapter(listAdapter);
-        mList.invalidate();
-    }
-
-    public ListView getListView() {
-        return mList;
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        mList = new ListView(getActivity());
-        mList.setOnItemClickListener(this);
-        mList.setOnItemLongClickListener(this);
-        return mList;
-        // return super.onCreateView(inflater, container, savedInstanceState);
-    }
-
-    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
-    }
-
-    @Override
-    public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2,
-            long arg3) {
-        return false;
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/QuickAction.java b/src/eu/alefzero/owncloud/ui/QuickAction.java
deleted file mode 100644 (file)
index e1d97d2..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui;\r
-\r
-import android.content.Context;\r
-\r
-import android.graphics.Rect;\r
-import android.graphics.drawable.Drawable;\r
-\r
-import android.widget.ImageView;\r
-import android.widget.TextView;\r
-import android.widget.LinearLayout;\r
-import android.widget.ScrollView;\r
-\r
-import android.view.Gravity;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.View.OnClickListener;\r
-import android.view.ViewGroup.LayoutParams;\r
-import android.view.ViewGroup;\r
-\r
-import java.util.ArrayList;\r
-\r
-import eu.alefzero.owncloud.R;\r
-\r
-/**\r
- * Popup window, shows action list as icon and text like the one in Gallery3D\r
- * app.\r
- * \r
- * @author Lorensius. W. T\r
- */\r
-public class QuickAction extends CustomPopup {\r
-    private final View root;\r
-    private final ImageView mArrowUp;\r
-    private final ImageView mArrowDown;\r
-    private final LayoutInflater inflater;\r
-    private final Context context;\r
-\r
-    protected static final int ANIM_GROW_FROM_LEFT = 1;\r
-    protected static final int ANIM_GROW_FROM_RIGHT = 2;\r
-    protected static final int ANIM_GROW_FROM_CENTER = 3;\r
-    protected static final int ANIM_REFLECT = 4;\r
-    protected static final int ANIM_AUTO = 5;\r
-\r
-    private int animStyle;\r
-    private ViewGroup mTrack;\r
-    private ScrollView scroller;\r
-    private ArrayList<ActionItem> actionList;\r
-\r
-    /**\r
-     * Constructor\r
-     * \r
-     * @param anchor {@link View} on where the popup window should be displayed\r
-     */\r
-    public QuickAction(View anchor) {\r
-        super(anchor);\r
-\r
-        actionList = new ArrayList<ActionItem>();\r
-        context = anchor.getContext();\r
-        inflater = (LayoutInflater) context\r
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
-\r
-        root = (ViewGroup) inflater.inflate(R.layout.popup, null);\r
-\r
-        mArrowDown = (ImageView) root.findViewById(R.id.arrow_down);\r
-        mArrowUp = (ImageView) root.findViewById(R.id.arrow_up);\r
-\r
-        setContentView(root);\r
-\r
-        mTrack = (ViewGroup) root.findViewById(R.id.tracks);\r
-        scroller = (ScrollView) root.findViewById(R.id.scroller);\r
-        animStyle = ANIM_AUTO;\r
-    }\r
-\r
-    /**\r
-     * Set animation style\r
-     * \r
-     * @param animStyle animation style, default is set to ANIM_AUTO\r
-     */\r
-    public void setAnimStyle(int animStyle) {\r
-        this.animStyle = animStyle;\r
-    }\r
-\r
-    /**\r
-     * Add action item\r
-     * \r
-     * @param action {@link ActionItem} object\r
-     */\r
-    public void addActionItem(ActionItem action) {\r
-        actionList.add(action);\r
-    }\r
-\r
-    /**\r
-     * Show popup window. Popup is automatically positioned, on top or bottom of\r
-     * anchor view.\r
-     * \r
-     */\r
-    public void show() {\r
-        preShow();\r
-\r
-        int xPos, yPos;\r
-\r
-        int[] location = new int[2];\r
-\r
-        mAnchor.getLocationOnScreen(location);\r
-\r
-        Rect anchorRect = new Rect(location[0], location[1], location[0]\r
-                + mAnchor.getWidth(), location[1] + mAnchor.getHeight());\r
-\r
-        createActionList();\r
-\r
-        root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,\r
-                LayoutParams.WRAP_CONTENT));\r
-        root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
-\r
-        int rootHeight = root.getMeasuredHeight();\r
-        int rootWidth = root.getMeasuredWidth();\r
-\r
-        int screenWidth = mWManager.getDefaultDisplay().getWidth();\r
-        int screenHeight = mWManager.getDefaultDisplay().getHeight();\r
-\r
-        // automatically get X coord of popup (top left)\r
-        if ((anchorRect.left + rootWidth) > screenWidth) {\r
-            xPos = anchorRect.left - (rootWidth - mAnchor.getWidth());\r
-        } else {\r
-            if (mAnchor.getWidth() > rootWidth) {\r
-                xPos = anchorRect.centerX() - (rootWidth / 2);\r
-            } else {\r
-                xPos = anchorRect.left;\r
-            }\r
-        }\r
-\r
-        int dyTop = anchorRect.top;\r
-        int dyBottom = screenHeight - anchorRect.bottom;\r
-\r
-        boolean onTop = (dyTop > dyBottom) ? true : false;\r
-\r
-        if (onTop) {\r
-            if (rootHeight > dyTop) {\r
-                yPos = 15;\r
-                LayoutParams l = scroller.getLayoutParams();\r
-                l.height = dyTop - mAnchor.getHeight();\r
-            } else {\r
-                yPos = anchorRect.top - rootHeight;\r
-            }\r
-        } else {\r
-            yPos = anchorRect.bottom;\r
-\r
-            if (rootHeight > dyBottom) {\r
-                LayoutParams l = scroller.getLayoutParams();\r
-                l.height = dyBottom;\r
-            }\r
-        }\r
-\r
-        showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),\r
-                anchorRect.centerX() - xPos);\r
-\r
-        setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);\r
-\r
-        mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);\r
-    }\r
-\r
-    /**\r
-     * Set animation style\r
-     * \r
-     * @param screenWidth screen width\r
-     * @param requestedX distance from left edge\r
-     * @param onTop flag to indicate where the popup should be displayed. Set\r
-     *            TRUE if displayed on top of anchor view and vice versa\r
-     */\r
-    private void setAnimationStyle(int screenWidth, int requestedX,\r
-            boolean onTop) {\r
-        int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;\r
-\r
-        switch (animStyle) {\r
-        case ANIM_GROW_FROM_LEFT:\r
-            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left\r
-                    : R.style.Animations_PopDownMenu_Left);\r
-            break;\r
-\r
-        case ANIM_GROW_FROM_RIGHT:\r
-            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right\r
-                    : R.style.Animations_PopDownMenu_Right);\r
-            break;\r
-\r
-        case ANIM_GROW_FROM_CENTER:\r
-            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center\r
-                    : R.style.Animations_PopDownMenu_Center);\r
-            break;\r
-\r
-        case ANIM_REFLECT:\r
-            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect\r
-                    : R.style.Animations_PopDownMenu_Reflect);\r
-            break;\r
-\r
-        case ANIM_AUTO:\r
-            if (arrowPos <= screenWidth / 4) {\r
-                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left\r
-                        : R.style.Animations_PopDownMenu_Left);\r
-            } else if (arrowPos > screenWidth / 4\r
-                    && arrowPos < 3 * (screenWidth / 4)) {\r
-                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center\r
-                        : R.style.Animations_PopDownMenu_Center);\r
-            } else {\r
-                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right\r
-                        : R.style.Animations_PopDownMenu_Right);\r
-            }\r
-\r
-            break;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Create action list\r
-     */\r
-    private void createActionList() {\r
-        View view;\r
-        String title;\r
-        Drawable icon;\r
-        OnClickListener listener;\r
-\r
-        for (int i = 0; i < actionList.size(); i++) {\r
-            title = actionList.get(i).getTitle();\r
-            icon = actionList.get(i).getIcon();\r
-            listener = actionList.get(i).getOnClickListerner();\r
-\r
-            view = getActionItem(title, icon, listener);\r
-\r
-            view.setFocusable(true);\r
-            view.setClickable(true);\r
-\r
-            mTrack.addView(view);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Get action item {@link View}\r
-     * \r
-     * @param title action item title\r
-     * @param icon {@link Drawable} action item icon\r
-     * @param listener {@link View.OnClickListener} action item listener\r
-     * @return action item {@link View}\r
-     */\r
-    private View getActionItem(String title, Drawable icon,\r
-            OnClickListener listener) {\r
-        LinearLayout container = (LinearLayout) inflater.inflate(\r
-                R.layout.action_item, null);\r
-\r
-        ImageView img = (ImageView) container.findViewById(R.id.icon);\r
-        TextView text = (TextView) container.findViewById(R.id.title);\r
-\r
-        if (icon != null) {\r
-            img.setImageDrawable(icon);\r
-        }\r
-\r
-        if (title != null) {\r
-            text.setText(title);\r
-        }\r
-\r
-        if (listener != null) {\r
-            container.setOnClickListener(listener);\r
-        }\r
-\r
-        return container;\r
-    }\r
-\r
-    /**\r
-     * Show arrow\r
-     * \r
-     * @param whichArrow arrow type resource id\r
-     * @param requestedX distance from left screen\r
-     */\r
-    private void showArrow(int whichArrow, int requestedX) {\r
-        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp\r
-                : mArrowDown;\r
-        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown\r
-                : mArrowUp;\r
-\r
-        final int arrowWidth = mArrowUp.getMeasuredWidth();\r
-\r
-        showArrow.setVisibility(View.VISIBLE);\r
-\r
-        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow\r
-                .getLayoutParams();\r
-\r
-        param.leftMargin = requestedX - arrowWidth / 2;\r
-\r
-        hideArrow.setVisibility(View.INVISIBLE);\r
-    }\r
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java b/src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java
deleted file mode 100644 (file)
index 8600a47..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-package eu.alefzero.owncloud.ui.activity;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerCallback;
-import android.accounts.AccountManagerFuture;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.widget.AdapterView.OnItemLongClickListener;
-import android.widget.CheckedTextView;
-import android.widget.ListView;
-import android.widget.SimpleAdapter;
-import android.widget.TextView;
-
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.SherlockListActivity;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuInflater;
-import com.actionbarsherlock.view.MenuItem;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.AccountUtils;
-import eu.alefzero.owncloud.R;
-
-public class AccountSelectActivity extends SherlockListActivity implements
-        AccountManagerCallback<Boolean> {
-
-    private final Handler mHandler = new Handler();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        ActionBar action_bar = getSupportActionBar();
-        action_bar.setDisplayShowTitleEnabled(true);
-        action_bar.setDisplayHomeAsUpEnabled(false);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        populateAccountList();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getSherlock().getMenuInflater();
-        inflater.inflate(eu.alefzero.owncloud.R.menu.account_picker, menu);
-        return true;
-    }
-
-    @Override
-    public void onCreateContextMenu(ContextMenu menu, View v,
-            ContextMenuInfo menuInfo) {
-        getMenuInflater().inflate(R.menu.account_picker_long_click, menu);
-        super.onCreateContextMenu(menu, v, menuInfo);
-    }
-
-    @Override
-    protected void onListItemClick(ListView l, View v, int position, long id) {
-        String accountName = ((TextView) v.findViewById(android.R.id.text1))
-                .getText().toString();
-        AccountUtils.setCurrentOwnCloudAccount(this, accountName);
-
-        // trigger synchronization when current account is changed
-        ContentResolver.cancelSync(null, "org.owncloud");
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
-        ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this), "org.owncloud", bundle);
-        
-        Intent i = new Intent(this, FileDisplayActivity.class);
-        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        startActivity(i);
-        finish();
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        if (item.getItemId() == R.id.createAccount) {
-            Intent intent = new Intent(
-                    android.provider.Settings.ACTION_ADD_ACCOUNT);
-            intent.putExtra("authorities",
-                    new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
-            startActivity(intent);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public boolean onContextItemSelected(android.view.MenuItem item) {
-        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
-                .getMenuInfo();
-        int index = info.position;
-        HashMap<String, String> map = (HashMap<String, String>) getListAdapter()
-                .getItem(index);
-        String accountName = map.get("NAME");
-        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
-        Account accounts[] = am
-                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
-        for (Account a : accounts) {
-            if (a.name.equals(accountName)) {
-                am.removeAccount(a, this, mHandler);
-            }
-        }
-
-        return false;
-    }
-
-    private void populateAccountList() {
-        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
-        Account accounts[] = am
-                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
-        LinkedList<HashMap<String, String>> ll = new LinkedList<HashMap<String, String>>();
-        for (Account a : accounts) {
-            HashMap<String, String> h = new HashMap<String, String>();
-            h.put("NAME", a.name);
-            h.put("VER",
-                    "ownCloud version: "
-                            + am.getUserData(a,
-                                    AccountAuthenticator.KEY_OC_VERSION));
-            ll.add(h);
-        }
-
-        setListAdapter(new AccountCheckedSimpleAdepter(this, ll,
-                android.R.layout.simple_list_item_single_choice,
-                new String[] { "NAME" }, new int[] { android.R.id.text1 }));
-        registerForContextMenu(getListView());
-    }
-
-    @Override
-    public void run(AccountManagerFuture<Boolean> future) {
-        if (future.isDone()) {
-            Account a = AccountUtils.getCurrentOwnCloudAccount(this);
-            String accountName = "";
-            if (a == null) {
-                Account[] accounts = AccountManager.get(this)
-                        .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
-                if (accounts.length != 0)
-                    accountName = accounts[0].name;
-                AccountUtils.setCurrentOwnCloudAccount(this, accountName);
-            }
-            populateAccountList();
-        }
-    }
-
-    private class AccountCheckedSimpleAdepter extends SimpleAdapter {
-        private Account mCurrentAccount;
-        private List<? extends Map<String, ?>> mPrivateData;
-
-        public AccountCheckedSimpleAdepter(Context context,
-                List<? extends Map<String, ?>> data, int resource,
-                String[] from, int[] to) {
-            super(context, data, resource, from, to);
-            mCurrentAccount = AccountUtils
-                    .getCurrentOwnCloudAccount(AccountSelectActivity.this);
-            mPrivateData = data;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            View v = super.getView(position, convertView, parent);
-            CheckedTextView ctv = (CheckedTextView) v
-                    .findViewById(android.R.id.text1);
-            if (mPrivateData.get(position).get("NAME")
-                    .equals(mCurrentAccount.name)) {
-                ctv.setChecked(true);
-            }
-            return v;
-        }
-
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java b/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java
deleted file mode 100644 (file)
index caa9820..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2012  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.ui.activity;\r
-\r
-import java.net.MalformedURLException;\r
-import java.net.URL;\r
-import java.net.URLEncoder;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountAuthenticatorActivity;\r
-import android.accounts.AccountManager;\r
-import android.app.Dialog;\r
-import android.app.ProgressDialog;\r
-import android.content.ContentResolver;\r
-import android.content.DialogInterface;\r
-import android.content.Intent;\r
-import android.content.SharedPreferences;\r
-import android.os.Bundle;\r
-import android.os.Handler;\r
-import android.preference.PreferenceManager;\r
-import android.text.InputType;\r
-import android.util.Log;\r
-import android.view.View;\r
-import android.view.View.OnClickListener;\r
-import android.view.View.OnFocusChangeListener;\r
-import android.view.Window;\r
-import android.widget.ImageView;\r
-import android.widget.TextView;\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.authenticator.AuthenticationRunnable;\r
-import eu.alefzero.owncloud.authenticator.ConnectionCheckerRunnable;\r
-import eu.alefzero.owncloud.authenticator.OnAuthenticationResultListener;\r
-import eu.alefzero.owncloud.authenticator.OnConnectCheckListener;\r
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
-import eu.alefzero.owncloud.extensions.ExtensionsAvailableActivity;\r
-import eu.alefzero.owncloud.utils.OwnCloudVersion;\r
-\r
-/**\r
- * This Activity is used to add an ownCloud account to the App\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
-        implements OnAuthenticationResultListener, OnConnectCheckListener,\r
-        OnFocusChangeListener, OnClickListener {\r
-    private static final int DIALOG_LOGIN_PROGRESS = 0;\r
-\r
-    private static final String TAG = "AuthActivity";\r
-\r
-    private Thread mAuthThread;\r
-    private AuthenticationRunnable mAuthRunnable;\r
-    private ConnectionCheckerRunnable mConnChkRunnable;\r
-    private final Handler mHandler = new Handler();\r
-    private String mBaseUrl;\r
-\r
-    private static final String STATUS_TEXT = "STATUS_TEXT";\r
-    private static final String STATUS_ICON = "STATUS_ICON";\r
-    private static final String STATUS_CORRECT = "STATUS_CORRECT";\r
-    private static final String IS_SSL_CONN = "IS_SSL_CONN";\r
-    private int mStatusText, mStatusIcon;\r
-    private boolean mStatusCorrect, mIsSslConn;\r
-\r
-    public static final String PARAM_USERNAME = "param_Username";\r
-    public static final String PARAM_HOSTNAME = "param_Hostname";\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
-        setContentView(R.layout.account_setup);\r
-        ImageView iv = (ImageView) findViewById(R.id.refreshButton);\r
-        ImageView iv2 = (ImageView) findViewById(R.id.viewPassword);\r
-        TextView tv = (TextView) findViewById(R.id.host_URL);\r
-        TextView tv2 = (TextView) findViewById(R.id.account_password);\r
-\r
-        if (savedInstanceState != null) {\r
-            mStatusIcon = savedInstanceState.getInt(STATUS_ICON);\r
-            mStatusText = savedInstanceState.getInt(STATUS_TEXT);\r
-            mStatusCorrect = savedInstanceState.getBoolean(STATUS_CORRECT);\r
-            mIsSslConn = savedInstanceState.getBoolean(IS_SSL_CONN);\r
-            setResultIconAndText(mStatusIcon, mStatusText);\r
-            findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);\r
-            if (!mStatusCorrect)\r
-                iv.setVisibility(View.VISIBLE);\r
-            else\r
-                iv.setVisibility(View.INVISIBLE);\r
-\r
-        } else {\r
-            mStatusText = mStatusIcon = 0;\r
-            mStatusCorrect = false;\r
-            mIsSslConn = false;\r
-        }\r
-        iv.setOnClickListener(this);\r
-        iv2.setOnClickListener(this);\r
-        tv.setOnFocusChangeListener(this);\r
-        tv2.setOnFocusChangeListener(this);\r
-    }\r
-\r
-    @Override\r
-    protected void onSaveInstanceState(Bundle outState) {\r
-        outState.putInt(STATUS_ICON, mStatusIcon);\r
-        outState.putInt(STATUS_TEXT, mStatusText);\r
-        outState.putBoolean(STATUS_CORRECT, mStatusCorrect);\r
-        super.onSaveInstanceState(outState);\r
-    }\r
-\r
-    @Override\r
-    protected Dialog onCreateDialog(int id) {\r
-        Dialog dialog = null;\r
-        switch (id) {\r
-        case DIALOG_LOGIN_PROGRESS: {\r
-            ProgressDialog working_dialog = new ProgressDialog(this);\r
-            working_dialog.setMessage(getResources().getString(\r
-                    R.string.auth_trying_to_login));\r
-            working_dialog.setIndeterminate(true);\r
-            working_dialog.setCancelable(true);\r
-            working_dialog\r
-                    .setOnCancelListener(new DialogInterface.OnCancelListener() {\r
-                        @Override\r
-                        public void onCancel(DialogInterface dialog) {\r
-                            Log.i(TAG, "Login canceled");\r
-                            if (mAuthThread != null) {\r
-                                mAuthThread.interrupt();\r
-                                finish();\r
-                            }\r
-                        }\r
-                    });\r
-            dialog = working_dialog;\r
-            break;\r
-        }\r
-        default:\r
-            Log.e(TAG, "Incorrect dialog called with id = " + id);\r
-        }\r
-        return dialog;\r
-    }\r
-\r
-    public void onAuthenticationResult(boolean success, String message) {\r
-        if (success) {\r
-            TextView username_text = (TextView) findViewById(R.id.account_username), password_text = (TextView) findViewById(R.id.account_password);\r
-\r
-            URL url;\r
-            try {\r
-                url = new URL(message);\r
-            } catch (MalformedURLException e) {\r
-                // should never happen\r
-                Log.e(getClass().getName(), "Malformed URL: " + message);\r
-                return;\r
-            }\r
-\r
-            String username = username_text.getText().toString().trim();\r
-            String accountName = username + "@" + url.getHost();\r
-            if (url.getPort() >= 0) {\r
-                accountName += ":" + url.getPort();\r
-            }\r
-            Account account = new Account(accountName,\r
-                    AccountAuthenticator.ACCOUNT_TYPE);\r
-            AccountManager accManager = AccountManager.get(this);\r
-            accManager.addAccountExplicitly(account, password_text.getText()\r
-                    .toString(), null);\r
-\r
-            // Add this account as default in the preferences, if there is none\r
-            // already\r
-            Account defaultAccount = AccountUtils\r
-                    .getCurrentOwnCloudAccount(this);\r
-            if (defaultAccount == null) {\r
-                SharedPreferences.Editor editor = PreferenceManager\r
-                        .getDefaultSharedPreferences(this).edit();\r
-                editor.putString("select_oc_account", accountName);\r
-                editor.commit();\r
-            }\r
-\r
-            final Intent intent = new Intent();\r
-            intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,\r
-                    AccountAuthenticator.ACCOUNT_TYPE);\r
-            intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);\r
-            intent.putExtra(AccountManager.KEY_AUTHTOKEN,\r
-                    AccountAuthenticator.ACCOUNT_TYPE);\r
-            intent.putExtra(AccountManager.KEY_USERDATA, username);\r
-\r
-            accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,\r
-                    url.toString());\r
-            accManager.setUserData(account,\r
-                    AccountAuthenticator.KEY_OC_VERSION, mConnChkRunnable\r
-                            .getDiscoveredVersion().toString());\r
-            accManager.setUserData(account,\r
-                    AccountAuthenticator.KEY_OC_BASE_URL, mBaseUrl);\r
-\r
-            setAccountAuthenticatorResult(intent.getExtras());\r
-            setResult(RESULT_OK, intent);\r
-            Bundle bundle = new Bundle();\r
-            bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
-            //getContentResolver().startSync(ProviderTableMeta.CONTENT_URI,\r
-            //        bundle);\r
-            ContentResolver.requestSync(account, "org.owncloud", bundle);\r
-\r
-            /*\r
-             * if\r
-             * (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion\r
-             * .owncloud_v2) >= 0) { Intent i = new Intent(this,\r
-             * ExtensionsAvailableActivity.class); startActivity(i); }\r
-             */\r
-\r
-            finish();\r
-        } else {\r
-            dismissDialog(DIALOG_LOGIN_PROGRESS);\r
-            TextView tv = (TextView) findViewById(R.id.account_username);\r
-            tv.setError(message);\r
-        }\r
-    }\r
-    public void onCancelClick(View view) {\r
-        finish();\r
-    }\r
-    \r
-    public void onOkClick(View view) {\r
-        String prefix = "";\r
-        String url = ((TextView) findViewById(R.id.host_URL)).getText()\r
-                .toString();\r
-        if (mIsSslConn) {\r
-            prefix = "https://";\r
-        } else {\r
-            prefix = "http://";\r
-        }\r
-        if (url.toLowerCase().startsWith("http://")\r
-                || url.toLowerCase().startsWith("https://")) {\r
-            prefix = "";\r
-        }\r
-        continueConnection(prefix);\r
-    }\r
-\r
-    private void continueConnection(String prefix) {\r
-        String url = ((TextView) findViewById(R.id.host_URL)).getText()\r
-                .toString();\r
-        String username = ((TextView) findViewById(R.id.account_username))\r
-                .getText().toString();\r
-        String password = ((TextView) findViewById(R.id.account_password))\r
-                .getText().toString();\r
-        if (url.endsWith("/"))\r
-            url = url.substring(0, url.length() - 1);\r
-\r
-        URL uri = null;\r
-        String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable\r
-                .getDiscoveredVersion());\r
-\r
-        try {\r
-            mBaseUrl = prefix + url;\r
-            String url_str = prefix + url + webdav_path;\r
-            uri = new URL(url_str);\r
-        } catch (MalformedURLException e) {\r
-            // should not happend\r
-            e.printStackTrace();\r
-        }\r
-\r
-        showDialog(DIALOG_LOGIN_PROGRESS);\r
-        mAuthRunnable = new AuthenticationRunnable(uri, username, password);\r
-        mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);\r
-        mAuthThread = new Thread(mAuthRunnable);\r
-        mAuthThread.start();\r
-    }\r
-\r
-    @Override\r
-    public void onConnectionCheckResult(ResultType type) {\r
-        mStatusText = mStatusIcon = 0;\r
-        mStatusCorrect = false;\r
-        String t_url = ((TextView) findViewById(R.id.host_URL)).getText()\r
-                .toString().toLowerCase();\r
-\r
-        switch (type) {\r
-        case OK_SSL:\r
-            mIsSslConn = true;\r
-            mStatusIcon = android.R.drawable.ic_secure;\r
-            mStatusText = R.string.auth_secure_connection;\r
-            mStatusCorrect = true;\r
-            break;\r
-        case OK_NO_SSL:\r
-            mIsSslConn = false;\r
-            mStatusCorrect = true;\r
-            if (t_url.startsWith("http://") ) {\r
-                mStatusText = R.string.auth_connection_established;\r
-                mStatusIcon = R.drawable.ic_ok;\r
-            } else {\r
-                mStatusText = R.string.auth_nossl_plain_ok_title;\r
-                mStatusIcon = android.R.drawable.ic_partial_secure;\r
-            }\r
-            break;\r
-        case TIMEOUT:\r
-        case INORRECT_ADDRESS:\r
-        case SSL_INIT_ERROR:\r
-        case HOST_NOT_AVAILABLE:\r
-            mStatusIcon = R.drawable.common_error;\r
-            mStatusText = R.string.auth_unknow_host_title;\r
-            break;\r
-        case NO_NETWORK_CONNECTION:\r
-            mStatusIcon = R.drawable.no_network;\r
-            mStatusText = R.string.auth_no_net_conn_title;\r
-            break;\r
-        case INSTANCE_NOT_CONFIGURED:\r
-            mStatusIcon = R.drawable.common_error;\r
-            mStatusText = R.string.auth_not_configured_title;\r
-            break;\r
-        case UNKNOWN_ERROR:\r
-            mStatusIcon = R.drawable.common_error;\r
-            mStatusText = R.string.auth_unknow_error;\r
-            break;\r
-        case FILE_NOT_FOUND:\r
-            mStatusIcon = R.drawable.common_error;\r
-            mStatusText = R.string.auth_incorrect_path_title;\r
-            break;\r
-        default:\r
-            Log.e(TAG, "Incorrect connection checker result type: " + type);\r
-        }\r
-        setResultIconAndText(mStatusIcon, mStatusText);\r
-        if (!mStatusCorrect)\r
-            findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);\r
-        else\r
-            findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);\r
-        findViewById(R.id.buttonOK).setEnabled(mStatusCorrect);\r
-    }\r
-\r
-    @Override\r
-    public void onFocusChange(View view, boolean hasFocus) {\r
-        if (view.getId() == R.id.host_URL) {\r
-            if (!hasFocus) {\r
-                TextView tv = ((TextView) findViewById(R.id.host_URL));\r
-                String uri = tv.getText().toString();\r
-                if (uri.length() != 0) {\r
-                    setResultIconAndText(R.drawable.progress_small,\r
-                            R.string.auth_testing_connection);\r
-                    findViewById(R.id.buttonOK).setEnabled(false);  // avoid connect can be clicked if the test was previously passed\r
-                    mConnChkRunnable = new ConnectionCheckerRunnable(uri, this);\r
-                    mConnChkRunnable.setListener(this, mHandler);\r
-                    mAuthThread = new Thread(mConnChkRunnable);\r
-                    mAuthThread.start();\r
-                } else {\r
-                    findViewById(R.id.refreshButton).setVisibility(\r
-                            View.INVISIBLE);\r
-                    setResultIconAndText(0, 0);\r
-                }\r
-            }\r
-        } else if (view.getId() == R.id.account_password) {\r
-            ImageView iv = (ImageView) findViewById(R.id.viewPassword);\r
-            if (hasFocus) {\r
-                iv.setVisibility(View.VISIBLE);\r
-            } else {\r
-                TextView v = (TextView) findViewById(R.id.account_password);\r
-                int input_type = InputType.TYPE_CLASS_TEXT\r
-                        | InputType.TYPE_TEXT_VARIATION_PASSWORD;\r
-                v.setInputType(input_type);\r
-                iv.setVisibility(View.INVISIBLE);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void setResultIconAndText(int drawable_id, int text_id) {\r
-        ImageView iv = (ImageView) findViewById(R.id.action_indicator);\r
-        TextView tv = (TextView) findViewById(R.id.status_text);\r
-\r
-        if (drawable_id == 0 && text_id == 0) {\r
-            iv.setVisibility(View.INVISIBLE);\r
-            tv.setVisibility(View.INVISIBLE);\r
-        } else {\r
-            iv.setImageResource(drawable_id);\r
-            tv.setText(text_id);\r
-            iv.setVisibility(View.VISIBLE);\r
-            tv.setVisibility(View.VISIBLE);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void onClick(View v) {\r
-        if (v.getId() == R.id.refreshButton) {\r
-            onFocusChange(findViewById(R.id.host_URL), false);\r
-        } else if (v.getId() == R.id.viewPassword) {\r
-            TextView view = (TextView) findViewById(R.id.account_password);\r
-            int input_type = InputType.TYPE_CLASS_TEXT\r
-                    | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;\r
-            view.setInputType(input_type);\r
-        }\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java
deleted file mode 100644 (file)
index 461485c..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.activity;\r
-\r
-import android.accounts.Account;\r
-import android.app.Dialog;\r
-import android.app.ProgressDialog;\r
-import android.content.Intent;\r
-import android.content.res.Configuration;\r
-import android.os.Bundle;\r
-import android.support.v4.app.FragmentTransaction;\r
-\r
-import com.actionbarsherlock.app.ActionBar;\r
-import com.actionbarsherlock.app.SherlockFragmentActivity;\r
-import com.actionbarsherlock.view.MenuItem;\r
-\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.files.services.FileDownloader;\r
-import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;\r
-\r
-/**\r
- * This activity displays the details of a file like its name, its size and so\r
- * on.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class FileDetailActivity extends SherlockFragmentActivity implements FileDetailFragment.ContainerActivity {\r
-    \r
-    public static final int DIALOG_SHORT_WAIT = 0;\r
-    \r
-    private boolean mConfigurationChangedToLandscape = false;\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-\r
-        // check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity \r
-        Configuration conf = getResources().getConfiguration();\r
-        mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE && \r
-                                                (conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE\r
-                                           );\r
-\r
-        if (!mConfigurationChangedToLandscape) {\r
-            setContentView(R.layout.file_activity_details);\r
-        \r
-            ActionBar actionBar = getSupportActionBar();\r
-            actionBar.setDisplayHomeAsUpEnabled(true);\r
-        \r
-            OCFile file = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);\r
-            Account account = getIntent().getParcelableExtra(FileDownloader.EXTRA_ACCOUNT);\r
-            FileDetailFragment mFileDetail = new FileDetailFragment(file, account);\r
-        \r
-            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
-            ft.replace(R.id.fragment, mFileDetail, FileDetailFragment.FTAG);\r
-            ft.commit();\r
-            \r
-        }  else {\r
-            backToDisplayActivity();   // the 'back' won't be effective until this.onStart() and this.onResume() are completed;\r
-        }\r
-        \r
-        \r
-    }\r
-\r
-    @Override\r
-    public boolean onOptionsItemSelected(MenuItem item) {\r
-        boolean returnValue = false;\r
-        \r
-        switch(item.getItemId()){\r
-        case android.R.id.home:\r
-            backToDisplayActivity();\r
-            returnValue = true;\r
-        }\r
-        \r
-        return returnValue;\r
-    }\r
-\r
-\r
-\r
-    @Override\r
-    protected void onResume() {\r
-        \r
-        super.onResume();\r
-        if (!mConfigurationChangedToLandscape) { \r
-            FileDetailFragment fragment = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);\r
-            fragment.updateFileDetails();\r
-        }\r
-    }\r
-    \r
-\r
-    private void backToDisplayActivity() {\r
-        Intent intent = new Intent(this, FileDisplayActivity.class);\r
-        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);\r
-        intent.putExtra(FileDetailFragment.EXTRA_FILE, getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE));\r
-        startActivity(intent);\r
-        finish();\r
-    }\r
-    \r
-    \r
-    @Override\r
-    protected Dialog onCreateDialog(int id) {\r
-        Dialog dialog = null;\r
-        switch (id) {\r
-        case DIALOG_SHORT_WAIT: {\r
-            ProgressDialog working_dialog = new ProgressDialog(this);\r
-            working_dialog.setMessage(getResources().getString(\r
-                    R.string.wait_a_moment));\r
-            working_dialog.setIndeterminate(true);\r
-            working_dialog.setCancelable(false);\r
-            dialog = working_dialog;\r
-            break;\r
-        }\r
-        default:\r
-            dialog = null;\r
-        }\r
-        return dialog;\r
-    }\r
-    \r
-    \r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onFileStateChanged() {\r
-        // nothing to do here!\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
deleted file mode 100644 (file)
index c440847..0000000
+++ /dev/null
@@ -1,886 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.ui.activity;\r
-\r
-import java.io.File;\r
-import java.util.ArrayList;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.app.AlertDialog;\r
-import android.app.ProgressDialog;\r
-import android.app.AlertDialog.Builder;\r
-import android.app.Dialog;\r
-import android.content.BroadcastReceiver;\r
-import android.content.ContentResolver;\r
-import android.content.Context;\r
-import android.content.DialogInterface;\r
-import android.content.DialogInterface.OnClickListener;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.content.SharedPreferences;\r
-import android.content.pm.PackageInfo;\r
-import android.content.pm.PackageManager.NameNotFoundException;\r
-import android.content.res.Resources.NotFoundException;\r
-import android.database.Cursor;\r
-import android.net.Uri;\r
-import android.os.Bundle;\r
-import android.os.Handler;\r
-import android.preference.PreferenceManager;\r
-import android.provider.MediaStore;\r
-import android.support.v4.app.FragmentTransaction;\r
-import android.util.Log;\r
-import android.view.View;\r
-import android.view.ViewGroup;\r
-import android.widget.ArrayAdapter;\r
-import android.widget.EditText;\r
-import android.widget.TextView;\r
-import android.widget.Toast;\r
-\r
-import com.actionbarsherlock.app.ActionBar;\r
-import com.actionbarsherlock.app.ActionBar.OnNavigationListener;\r
-import com.actionbarsherlock.app.SherlockFragmentActivity;\r
-import com.actionbarsherlock.view.Menu;\r
-import com.actionbarsherlock.view.MenuInflater;\r
-import com.actionbarsherlock.view.MenuItem;\r
-import com.actionbarsherlock.view.Window;\r
-\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.CrashHandler;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.datamodel.DataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.files.services.FileDownloader;\r
-import eu.alefzero.owncloud.files.services.FileUploader;\r
-import eu.alefzero.owncloud.syncadapter.FileSyncService;\r
-import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;\r
-import eu.alefzero.owncloud.ui.fragment.FileListFragment;\r
-import eu.alefzero.webdav.WebdavClient;\r
-\r
-/**\r
- * Displays, what files the user has available in his ownCloud.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-\r
-public class FileDisplayActivity extends SherlockFragmentActivity implements\r
-    FileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener  {\r
-    \r
-    private ArrayAdapter<String> mDirectories;\r
-    private OCFile mCurrentDir;\r
-    private String[] mDirs = null;\r
-\r
-    private DataStorageManager mStorageManager;\r
-    private SyncBroadcastReceiver mSyncBroadcastReceiver;\r
-    private UploadFinishReceiver mUploadFinishReceiver;\r
-    private DownloadFinishReceiver mDownloadFinishReceiver;\r
-    \r
-    private View mLayoutView = null;\r
-    private FileListFragment mFileList;\r
-    \r
-    private boolean mDualPane;\r
-    \r
-    private boolean mForcedLoginToCreateFirstAccount = false;\r
-    \r
-    private static final String KEY_DIR_ARRAY = "DIR_ARRAY";\r
-    private static final String KEY_CURRENT_DIR = "DIR";\r
-    \r
-    private static final int DIALOG_SETUP_ACCOUNT = 0;\r
-    private static final int DIALOG_CREATE_DIR = 1;\r
-    private static final int DIALOG_ABOUT_APP = 2;\r
-    public static final int DIALOG_SHORT_WAIT = 3;\r
-    \r
-    private static final int ACTION_SELECT_FILE = 1;\r
-    \r
-    private static final String TAG = "FileDisplayActivity";\r
-    \r
-    \r
-    @Override\r
-    public void onCreate(Bundle savedInstanceState) {\r
-        Log.i(getClass().toString(), "onCreate() start");\r
-        super.onCreate(savedInstanceState);\r
-\r
-        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);\r
-\r
-        Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext()));\r
-\r
-        if(savedInstanceState != null) {\r
-            mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);\r
-            mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);\r
-            mDirectories.add(OCFile.PATH_SEPARATOR);\r
-            if (mDirs != null)\r
-                for (String s : mDirs)\r
-                    mDirectories.insert(s, 0);\r
-            mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);\r
-        }\r
-        \r
-        mLayoutView = getLayoutInflater().inflate(R.layout.files, null);  // always inflate this at onCreate() ; just once!\r
-        \r
-        if (AccountUtils.accountsAreSetup(this)) {\r
-            \r
-            initDelayedTilAccountAvailabe();\r
-            \r
-            // PIN CODE request ;  best location is to decide, let's try this first\r
-            //if (savedInstanceState == null) {\r
-            if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {\r
-                requestPinCode();\r
-            }\r
-            \r
-            \r
-        } else {\r
-            \r
-            setContentView(R.layout.no_account_available);\r
-            getSupportActionBar().setNavigationMode(ActionBar.DISPLAY_SHOW_TITLE);\r
-            findViewById(R.id.setup_account).setOnClickListener(this);\r
-\r
-            setSupportProgressBarIndeterminateVisibility(false);\r
-\r
-            Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);\r
-            intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
-            startActivity(intent);  // although the code is here, the activity won't be created until this.onStart() and this.onResume() are finished;\r
-            mForcedLoginToCreateFirstAccount = true;\r
-        }\r
-        \r
-        Log.i(getClass().toString(), "onCreate() end");\r
-    }\r
-\r
-    @Override\r
-    public boolean onCreateOptionsMenu(Menu menu) {\r
-        MenuInflater inflater = getSherlock().getMenuInflater();\r
-            inflater.inflate(R.menu.menu, menu);\r
-            return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean onOptionsItemSelected(MenuItem item) {\r
-        boolean retval = true;\r
-        switch (item.getItemId()) {\r
-            case R.id.createDirectoryItem: {\r
-                showDialog(DIALOG_CREATE_DIR);\r
-                break;\r
-            }\r
-            case R.id.startSync: {\r
-                ContentResolver.cancelSync(null, "org.owncloud");   // cancel the current synchronizations of any ownCloud account\r
-                Bundle bundle = new Bundle();\r
-                bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
-                ContentResolver.requestSync(\r
-                        AccountUtils.getCurrentOwnCloudAccount(this),\r
-                        "org.owncloud", bundle);\r
-                break;\r
-            }\r
-            case R.id.action_upload: {\r
-                Intent action = new Intent(Intent.ACTION_GET_CONTENT);\r
-                action = action.setType("*/*")\r
-                        .addCategory(Intent.CATEGORY_OPENABLE);\r
-                startActivityForResult(\r
-                        Intent.createChooser(action, getString(R.string.upload_chooser_title)),\r
-                        ACTION_SELECT_FILE);\r
-                break;\r
-            }\r
-            case R.id.action_settings: {\r
-                Intent settingsIntent = new Intent(this, Preferences.class);\r
-                startActivity(settingsIntent);\r
-                break;\r
-            }\r
-            case R.id.about_app : {\r
-                showDialog(DIALOG_ABOUT_APP);\r
-                break;\r
-            }\r
-            case android.R.id.home: {\r
-                if(mCurrentDir != null && mCurrentDir.getParentId() != 0){\r
-                    onBackPressed(); \r
-                }\r
-                break;\r
-            }\r
-            default:\r
-                retval = false;\r
-        }\r
-        return retval;\r
-    }\r
-\r
-    @Override\r
-    public boolean onNavigationItemSelected(int itemPosition, long itemId) {\r
-        int i = itemPosition;\r
-        while (i-- != 0) {\r
-            onBackPressed();\r
-        }\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Called, when the user selected something for uploading\r
-     */\r
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {\r
-        if (requestCode == ACTION_SELECT_FILE) {\r
-            if (resultCode == RESULT_OK) {\r
-                String filepath = null;\r
-                try {\r
-                    Uri selectedImageUri = data.getData();\r
-    \r
-                    String filemanagerstring = selectedImageUri.getPath();\r
-                    String selectedImagePath = getPath(selectedImageUri);\r
-    \r
-                    if (selectedImagePath != null)\r
-                        filepath = selectedImagePath;\r
-                    else\r
-                        filepath = filemanagerstring;\r
-                    \r
-                } catch (Exception e) {\r
-                    Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);\r
-                    e.printStackTrace();\r
-                    \r
-                } finally {\r
-                    if (filepath == null) {\r
-                        Log.e("FileDisplay", "Couldnt resolve path to file");\r
-                        Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);\r
-                        t.show();\r
-                        return;\r
-                    }\r
-                }\r
-    \r
-                Intent i = new Intent(this, FileUploader.class);\r
-                i.putExtra(FileUploader.KEY_ACCOUNT,\r
-                        AccountUtils.getCurrentOwnCloudAccount(this));\r
-                String remotepath = new String();\r
-                for (int j = mDirectories.getCount() - 2; j >= 0; --j) {\r
-                    remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);\r
-                }\r
-                if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))\r
-                    remotepath += OCFile.PATH_SEPARATOR;\r
-                remotepath += new File(filepath).getName();\r
-    \r
-                i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);\r
-                i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);\r
-                i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);\r
-                startService(i);\r
-            }\r
-            \r
-        }/* dvelasco: WIP - not working as expected ... yet :)\r
-             else if (requestCode == ACTION_CREATE_FIRST_ACCOUNT) {\r
-            if (resultCode != RESULT_OK) {\r
-                finish();   // the user cancelled the AuthenticatorActivity\r
-            }\r
-        }*/\r
-    }\r
-\r
-    @Override\r
-    public void onBackPressed() {\r
-        if (mDirectories == null || mDirectories.getCount() <= 1) {\r
-            finish();\r
-            return;\r
-        }\r
-        popDirname();\r
-        mFileList.onNavigateUp();\r
-        mCurrentDir = mFileList.getCurrentFile();\r
-        \r
-        if(mCurrentDir.getParentId() == 0){\r
-            ActionBar actionBar = getSupportActionBar(); \r
-            actionBar.setDisplayHomeAsUpEnabled(false);\r
-        } \r
-    }\r
-\r
-    @Override\r
-    protected void onSaveInstanceState(Bundle outState) {\r
-        // responsability of restore is prefered in onCreate() before than in onRestoreInstanceState when there are Fragments involved\r
-        Log.i(getClass().toString(), "onSaveInstanceState() start");\r
-        super.onSaveInstanceState(outState);\r
-        if(mDirectories != null && mDirectories.getCount() != 0){\r
-            mDirs = new String[mDirectories.getCount()-1];\r
-            for (int j = mDirectories.getCount() - 2, i = 0; j >= 0; --j, ++i) {\r
-                mDirs[i] = mDirectories.getItem(j);\r
-            }\r
-        }\r
-        outState.putStringArray(KEY_DIR_ARRAY, mDirs);\r
-        outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);\r
-        Log.i(getClass().toString(), "onSaveInstanceState() end");\r
-    }\r
-\r
-    @Override\r
-    protected void onResume() {\r
-        Log.i(getClass().toString(), "onResume() start");\r
-        super.onResume();\r
-\r
-        if (AccountUtils.accountsAreSetup(this)) {\r
-         // at least an account exist: normal operation\r
-            \r
-            // set the layout only if it couldn't be set in onCreate\r
-            if (mForcedLoginToCreateFirstAccount) {\r
-                initDelayedTilAccountAvailabe();\r
-                mForcedLoginToCreateFirstAccount = false;\r
-            }\r
-\r
-            // Listen for sync messages\r
-            IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);\r
-            mSyncBroadcastReceiver = new SyncBroadcastReceiver();\r
-            registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);\r
-            \r
-            // Listen for upload messages\r
-            IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);\r
-            mUploadFinishReceiver = new UploadFinishReceiver();\r
-            registerReceiver(mUploadFinishReceiver, uploadIntentFilter);\r
-            \r
-            // Listen for download messages\r
-            IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.DOWNLOAD_FINISH_MESSAGE);\r
-            mDownloadFinishReceiver = new DownloadFinishReceiver();\r
-            registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);\r
-        \r
-            // Storage manager initialization\r
-            mStorageManager = new FileDataStorageManager(\r
-                    AccountUtils.getCurrentOwnCloudAccount(this),\r
-                    getContentResolver());\r
-        \r
-            // File list fragments   \r
-            mFileList = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
-            \r
-            \r
-            // Figure out what directory to list. \r
-            // Priority: Intent (here), savedInstanceState (onCreate), root dir (dir is null)\r
-            if(getIntent().hasExtra(FileDetailFragment.EXTRA_FILE)){\r
-                mCurrentDir = (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);\r
-                if(mCurrentDir != null && !mCurrentDir.isDirectory()){\r
-                    mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());\r
-                }\r
-            \r
-                // Clear intent extra, so rotating the screen will not return us to this directory\r
-                getIntent().removeExtra(FileDetailFragment.EXTRA_FILE);\r
-            }\r
-            \r
-            if (mCurrentDir == null)\r
-                mCurrentDir = mStorageManager.getFileByPath("/");\r
-                \r
-            // Drop-Down navigation and file list restore\r
-            mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);\r
-        \r
-        \r
-            // Given the case we have a file to display:\r
-            if(mCurrentDir != null){\r
-                ArrayList<OCFile> files = new ArrayList<OCFile>();\r
-                OCFile currFile = mCurrentDir;\r
-                while(currFile != null){\r
-                    files.add(currFile);\r
-                    currFile = mStorageManager.getFileById(currFile.getParentId());\r
-                }\r
-            \r
-                // Insert in mDirs\r
-                mDirs = new String[files.size()];\r
-                for(int i = files.size() - 1; i >= 0; i--){\r
-                    mDirs[i] = files.get(i).getFileName();\r
-                }\r
-            }\r
-        \r
-            if (mDirs != null) {\r
-                for (String s : mDirs)\r
-                    mDirectories.add(s);\r
-            } else {\r
-                mDirectories.add(OCFile.PATH_SEPARATOR);\r
-            }\r
-               \r
-            // Actionbar setup\r
-            ActionBar action_bar = getSupportActionBar();\r
-            action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);\r
-            action_bar.setDisplayShowTitleEnabled(false);\r
-            action_bar.setListNavigationCallbacks(mDirectories, this);\r
-            if(mCurrentDir != null && mCurrentDir.getParentId() != 0){\r
-                action_bar.setDisplayHomeAsUpEnabled(true);\r
-            } else {\r
-                action_bar.setDisplayHomeAsUpEnabled(false);\r
-            }\r
-        \r
-            // List dir here\r
-            mFileList.listDirectory(mCurrentDir);\r
-        }\r
-        Log.i(getClass().toString(), "onResume() end");\r
-    }\r
-\r
-    @Override\r
-    protected void onPause() {\r
-        Log.i(getClass().toString(), "onPause() start");\r
-        super.onPause();\r
-        if (mSyncBroadcastReceiver != null) {\r
-            unregisterReceiver(mSyncBroadcastReceiver);\r
-            mSyncBroadcastReceiver = null;\r
-        }\r
-        if (mUploadFinishReceiver != null) {\r
-            unregisterReceiver(mUploadFinishReceiver);\r
-            mUploadFinishReceiver = null;\r
-        }\r
-        if (mDownloadFinishReceiver != null) {\r
-            unregisterReceiver(mDownloadFinishReceiver);\r
-            mDownloadFinishReceiver = null;\r
-        }\r
-        \r
-        getIntent().putExtra(FileDetailFragment.EXTRA_FILE, mCurrentDir);\r
-        Log.i(getClass().toString(), "onPause() end");\r
-    }\r
-\r
-    @Override\r
-    protected Dialog onCreateDialog(int id) {\r
-        Dialog dialog = null;\r
-        AlertDialog.Builder builder;\r
-        switch (id) {\r
-        case DIALOG_SETUP_ACCOUNT:\r
-            builder = new AlertDialog.Builder(this);\r
-            builder.setTitle(R.string.main_tit_accsetup);\r
-            builder.setMessage(R.string.main_wrn_accsetup);\r
-            builder.setCancelable(false);\r
-            builder.setPositiveButton(android.R.string.ok, this);\r
-            builder.setNegativeButton(android.R.string.cancel, this);\r
-            dialog = builder.create();\r
-            break;\r
-        case DIALOG_ABOUT_APP: {\r
-            builder = new AlertDialog.Builder(this);\r
-            builder.setTitle(getString(R.string.about_title));\r
-            PackageInfo pkg;\r
-            try {\r
-                pkg = getPackageManager().getPackageInfo(getPackageName(), 0);\r
-                builder.setMessage("ownCloud android client\n\nversion: " + pkg.versionName );\r
-                builder.setIcon(android.R.drawable.ic_menu_info_details);\r
-                dialog = builder.create();\r
-            } catch (NameNotFoundException e) {\r
-                builder = null;\r
-                dialog = null;\r
-                Log.e(TAG, "Error while showing about dialog", e);\r
-            }\r
-            break;\r
-        }\r
-        case DIALOG_CREATE_DIR: {\r
-            builder = new Builder(this);\r
-            final EditText dirNameInput = new EditText(getBaseContext());\r
-            final Account a = AccountUtils.getCurrentOwnCloudAccount(this);\r
-            builder.setView(dirNameInput);\r
-            builder.setTitle(R.string.uploader_info_dirname);\r
-            int typed_color = getResources().getColor(R.color.setup_text_typed);\r
-            dirNameInput.setTextColor(typed_color);\r
-            builder.setPositiveButton(android.R.string.ok,\r
-                    new OnClickListener() {\r
-                        public void onClick(DialogInterface dialog, int which) {\r
-                            String directoryName = dirNameInput.getText().toString();\r
-                            if (directoryName.trim().length() == 0) {\r
-                                dialog.cancel();\r
-                                return;\r
-                            }\r
-    \r
-                            // Figure out the path where the dir needs to be created\r
-                            String path;\r
-                            if (mCurrentDir == null) {\r
-                                // this is just a patch; we should ensure that mCurrentDir never is null\r
-                                if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {\r
-                                    OCFile file = new OCFile(OCFile.PATH_SEPARATOR);\r
-                                    mStorageManager.saveFile(file);\r
-                                }\r
-                                mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);\r
-                            }\r
-                            path = FileDisplayActivity.this.mCurrentDir.getRemotePath();\r
-                            \r
-                            // Create directory\r
-                            path += directoryName + OCFile.PATH_SEPARATOR;\r
-                            Thread thread = new Thread(new DirectoryCreator(path, a, new Handler()));\r
-                            thread.start();\r
-                            \r
-                            dialog.dismiss();\r
-                            \r
-                            showDialog(DIALOG_SHORT_WAIT);\r
-                        }\r
-                    });\r
-            builder.setNegativeButton(R.string.common_cancel,\r
-                    new OnClickListener() {\r
-                        public void onClick(DialogInterface dialog, int which) {\r
-                            dialog.cancel();\r
-                        }\r
-                    });\r
-            dialog = builder.create();\r
-            break;\r
-        }\r
-        case DIALOG_SHORT_WAIT: {\r
-            ProgressDialog working_dialog = new ProgressDialog(this);\r
-            working_dialog.setMessage(getResources().getString(\r
-                    R.string.wait_a_moment));\r
-            working_dialog.setIndeterminate(true);\r
-            working_dialog.setCancelable(false);\r
-            dialog = working_dialog;\r
-            break;\r
-        }\r
-        default:\r
-            dialog = null;\r
-        }\r
-    \r
-        return dialog;\r
-    }\r
-\r
-    \r
-    /**\r
-     * Responds to the "There are no ownCloud Accounts setup" dialog\r
-     * TODO: Dialog is 100% useless -> Remove\r
-     */\r
-    @Override\r
-    public void onClick(DialogInterface dialog, int which) {\r
-        // In any case - we won't need it anymore\r
-        dialog.dismiss();\r
-        switch (which) {\r
-        case DialogInterface.BUTTON_POSITIVE:\r
-            Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
-            intent.putExtra("authorities",\r
-                    new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
-            startActivity(intent);\r
-            break;\r
-        case DialogInterface.BUTTON_NEGATIVE:\r
-            finish();\r
-        }\r
-    \r
-    }\r
-\r
-    /**\r
-     * Translates a content URI of an image to a physical path\r
-     * on the disk\r
-     * @param uri The URI to resolve\r
-     * @return The path to the image or null if it could not be found\r
-     */\r
-    public String getPath(Uri uri) {\r
-        String[] projection = { MediaStore.Images.Media.DATA };\r
-        Cursor cursor = managedQuery(uri, projection, null, null, null);\r
-        if (cursor != null) {\r
-            int column_index = cursor\r
-                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);\r
-            cursor.moveToFirst();\r
-            return cursor.getString(column_index);\r
-        } \r
-        return null;\r
-    }\r
-    \r
-    /**\r
-     * Pushes a directory to the drop down list\r
-     * @param directory to push\r
-     * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.\r
-     */\r
-    public void pushDirname(OCFile directory) {\r
-        if(!directory.isDirectory()){\r
-            throw new IllegalArgumentException("Only directories may be pushed!");\r
-        }\r
-        mDirectories.insert(directory.getFileName(), 0);\r
-        mCurrentDir = directory;\r
-    }\r
-\r
-    /**\r
-     * Pops a directory name from the drop down list\r
-     * @return True, unless the stack is empty\r
-     */\r
-    public boolean popDirname() {\r
-        mDirectories.remove(mDirectories.getItem(0));\r
-        return !mDirectories.isEmpty();\r
-    }\r
-\r
-    private class DirectoryCreator implements Runnable {\r
-        private String mTargetPath;\r
-        private Account mAccount;\r
-        private AccountManager mAm;\r
-        private Handler mHandler; \r
-    \r
-        public DirectoryCreator(String targetPath, Account account, Handler handler) {\r
-            mTargetPath = targetPath;\r
-            mAccount = account;\r
-            mAm = (AccountManager) getSystemService(ACCOUNT_SERVICE);\r
-            mHandler = handler;\r
-        }\r
-    \r
-        @Override\r
-        public void run() {\r
-            WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());\r
-            \r
-            String username = mAccount.name.substring(0,\r
-                    mAccount.name.lastIndexOf('@'));\r
-            String password = mAm.getPassword(mAccount);\r
-    \r
-            wdc.setCredentials(username, password);\r
-            wdc.allowSelfsignedCertificates();\r
-            boolean created = wdc.createDirectory(mTargetPath);\r
-            if (created) {\r
-                mHandler.post(new Runnable() {\r
-                    @Override\r
-                    public void run() { \r
-                        dismissDialog(DIALOG_SHORT_WAIT);\r
-                        \r
-                        // Save new directory in local database\r
-                        OCFile newDir = new OCFile(mTargetPath);\r
-                        newDir.setMimetype("DIR");\r
-                        newDir.setParentId(mCurrentDir.getFileId());\r
-                        mStorageManager.saveFile(newDir);\r
-    \r
-                        // Display the new folder right away\r
-                        mFileList.listDirectory(mCurrentDir);\r
-                    }\r
-                });\r
-                \r
-            } else {\r
-                mHandler.post(new Runnable() {\r
-                    @Override\r
-                    public void run() {\r
-                        dismissDialog(DIALOG_SHORT_WAIT);\r
-                        try {\r
-                            Toast msg = Toast.makeText(FileDisplayActivity.this, R.string.create_dir_fail_msg, Toast.LENGTH_LONG); \r
-                            msg.show();\r
-                        \r
-                        } catch (NotFoundException e) {\r
-                            Log.e(TAG, "Error while trying to show fail message " , e);\r
-                        }\r
-                    }\r
-                });\r
-            }\r
-        }\r
-    \r
-    }\r
-\r
-    // Custom array adapter to override text colors\r
-    private class CustomArrayAdapter<T> extends ArrayAdapter<T> {\r
-    \r
-        public CustomArrayAdapter(FileDisplayActivity ctx, int view) {\r
-            super(ctx, view);\r
-        }\r
-    \r
-        public View getView(int position, View convertView, ViewGroup parent) {\r
-            View v = super.getView(position, convertView, parent);\r
-    \r
-            ((TextView) v).setTextColor(getResources().getColorStateList(\r
-                    android.R.color.white));\r
-            return v;\r
-        }\r
-    \r
-        public View getDropDownView(int position, View convertView,\r
-                ViewGroup parent) {\r
-            View v = super.getDropDownView(position, convertView, parent);\r
-    \r
-            ((TextView) v).setTextColor(getResources().getColorStateList(\r
-                    android.R.color.white));\r
-    \r
-            return v;\r
-        }\r
-    \r
-    }\r
-\r
-    private class SyncBroadcastReceiver extends BroadcastReceiver {\r
-        /**\r
-         * {@link BroadcastReceiver} to enable syncing feedback in UI\r
-         */\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            boolean inProgress = intent.getBooleanExtra(\r
-                    FileSyncService.IN_PROGRESS, false);\r
-            String accountName = intent\r
-                    .getStringExtra(FileSyncService.ACCOUNT_NAME);\r
-\r
-            Log.d("FileDisplay", "sync of account " + accountName\r
-                    + " is in_progress: " + inProgress);\r
-\r
-            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {  \r
-            \r
-                String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH); \r
-                 \r
-                boolean fillBlankRoot = false;\r
-                if (mCurrentDir == null) {\r
-                    mCurrentDir = mStorageManager.getFileByPath("/");\r
-                    fillBlankRoot = (mCurrentDir != null);\r
-                }\r
-\r
-                if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath().equals(synchFolderRemotePath)))\r
-                        || fillBlankRoot ) {\r
-                    if (!fillBlankRoot) \r
-                        mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);\r
-                    FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager()\r
-                            .findFragmentById(R.id.fileList);\r
-                    if (fileListFragment != null) {\r
-                        fileListFragment.listDirectory(mCurrentDir);  \r
-                    }\r
-                }\r
-                \r
-                setSupportProgressBarIndeterminateVisibility(inProgress);\r
-                \r
-            }\r
-        }\r
-    }\r
-    \r
-\r
-    private class UploadFinishReceiver extends BroadcastReceiver {\r
-        /**\r
-         * Once the file upload has finished -> update view\r
-         *  @author David A. Velasco\r
-         * {@link BroadcastReceiver} to enable upload feedback in UI\r
-         */\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            long parentDirId = intent.getLongExtra(FileUploader.EXTRA_PARENT_DIR_ID, -1);\r
-            OCFile parentDir = mStorageManager.getFileById(parentDirId);\r
-            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);\r
-\r
-            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&\r
-                    parentDir != null && \r
-                    (   (mCurrentDir == null && parentDir.getFileName().equals("/")) ||\r
-                            parentDir.equals(mCurrentDir)\r
-                    )\r
-                ) {\r
-                FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
-                if (fileListFragment != null) { \r
-                    fileListFragment.listDirectory();\r
-                }\r
-            }\r
-        }\r
-        \r
-    }\r
-    \r
-    \r
-    /**\r
-     * Once the file download has finished -> update view\r
-     */\r
-    private class DownloadFinishReceiver extends BroadcastReceiver {\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);\r
-            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);\r
-\r
-            if (accountName.equals(AccountUtils.getCurrentOwnCloudAccount(context).name) &&\r
-                     mCurrentDir != null && mCurrentDir.getFileId() == mStorageManager.getFileByPath(downloadedRemotePath).getParentId()) {\r
-                FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
-                if (fileListFragment != null) { \r
-                    fileListFragment.listDirectory();\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    \r
-    @Override\r
-    public void onClick(View v) {\r
-        if (v.getId() == R.id.setup_account) {\r
-            Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);\r
-            intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
-            startActivity(intent); \r
-            mForcedLoginToCreateFirstAccount = true;\r
-        }\r
-    }\r
-\r
-    \r
-    \r
-    \r
-    \r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public DataStorageManager getStorageManager() {\r
-        return mStorageManager;\r
-    }\r
-    \r
-    \r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onDirectoryClick(OCFile directory) {\r
-        pushDirname(directory);\r
-        ActionBar actionBar = getSupportActionBar();\r
-        actionBar.setDisplayHomeAsUpEnabled(true);\r
-        \r
-        if (mDualPane) {\r
-            // Resets the FileDetailsFragment on Tablets so that it always displays\r
-            FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);\r
-            if (fileDetails != null) {\r
-                FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\r
-                transaction.remove(fileDetails);\r
-                transaction.add(R.id.file_details_container, new FileDetailFragment(null, null));\r
-                transaction.commit();\r
-            }\r
-        }\r
-    }\r
-    \r
-    \r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onFileClick(OCFile file) {\r
-        \r
-        // If we are on a large device -> update fragment\r
-        if (mDualPane) {\r
-            // 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'\r
-            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\r
-            transaction.replace(R.id.file_details_container, new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG);\r
-            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);\r
-            transaction.commit();\r
-            \r
-        } else {    // small or medium screen device -> new Activity\r
-            Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);\r
-            showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);\r
-            showDetailsIntent.putExtra(FileDownloader.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));\r
-            startActivity(showDetailsIntent);\r
-        }\r
-    }\r
-    \r
-    \r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onFileStateChanged() {\r
-        FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);\r
-        if (fileListFragment != null) { \r
-            fileListFragment.listDirectory();\r
-        }\r
-    }\r
-    \r
-    \r
-    /**\r
-     *  Operations in this method should be preferably performed in onCreate to have a lighter onResume method. \r
-     * \r
-     *  But we need to delay them to onResume for the first start of the application, when no account exists and the login activity must be shown; and \r
-     *  put instead the ugly view that shows the 'Setup' button to restart the login activity.   \r
-     *  \r
-     *  In other way, if the users cancels or presses BACK in the login page that first time (users can be cruel sometimes) would show a blank view (the \r
-     *  FragmentList view empty).\r
-     *  \r
-     *  This is temporal, until we found out how to get a result in this activity after launching the ADD_ACCOUNT Intent with startActivityForResult (not trivial)\r
-     */\r
-    private void initDelayedTilAccountAvailabe() {\r
-        setContentView(mLayoutView);    \r
-        mDualPane = (findViewById(R.id.file_details_container) != null);\r
-        if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {\r
-            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();\r
-            transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment\r
-            transaction.commit();\r
-        }\r
-        setSupportProgressBarIndeterminateVisibility(false);\r
-    }\r
-    \r
-\r
-    /**\r
-     * Launch an intent to request the PIN code to the user before letting him use the app\r
-     */\r
-    private void requestPinCode() {\r
-        boolean pinStart = false;\r
-        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());\r
-        pinStart = appPrefs.getBoolean("set_pincode", false);\r
-        if (pinStart) {\r
-            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);\r
-            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");\r
-            startActivity(i);\r
-        }\r
-    }\r
-\r
-    \r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java b/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java
deleted file mode 100644 (file)
index d40d8d7..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011 Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.activity;\r
-\r
-import com.actionbarsherlock.app.SherlockFragmentActivity;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.app.AlertDialog;\r
-import android.app.Dialog;\r
-import android.content.DialogInterface;\r
-import android.content.DialogInterface.OnClickListener;\r
-import android.content.Intent;\r
-import android.os.Bundle;\r
-import android.view.View;\r
-import android.widget.AdapterView;\r
-import android.widget.AdapterView.OnItemClickListener;\r
-import android.widget.GridView;\r
-import android.widget.Toast;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;\r
-\r
-/**\r
- * This activity is used as a landing page when the user first opens this app.\r
- * \r
- * @author Lennart Rosam\r
- * \r
- */\r
-public class LandingActivity extends SherlockFragmentActivity implements\r
-        OnClickListener, OnItemClickListener {\r
-\r
-    public static final int DIALOG_SETUP_ACCOUNT = 1;\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        setContentView(R.layout.main);\r
-\r
-        // Fill the grid view of the landing screen with icons\r
-        GridView landingScreenItems = (GridView) findViewById(R.id.homeScreenGrid);\r
-        landingScreenItems.setAdapter(new LandingScreenAdapter(this));\r
-        landingScreenItems.setOnItemClickListener(this);\r
-\r
-        // Check, if there are ownCloud accounts\r
-        if (!accountsAreSetup()) {\r
-            showDialog(DIALOG_SETUP_ACCOUNT);\r
-        } else {\r
-            // Start device tracking service\r
-            Intent locationServiceIntent = new Intent();\r
-            locationServiceIntent\r
-                    .setAction("eu.alefzero.owncloud.location.LocationLauncher");\r
-            sendBroadcast(locationServiceIntent);\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    protected void onRestart() {\r
-        super.onRestart();\r
-        // Check, if there are ownCloud accounts\r
-        if (!accountsAreSetup()) {\r
-            showDialog(DIALOG_SETUP_ACCOUNT);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    protected void onRestoreInstanceState(Bundle savedInstanceState) {\r
-        super.onRestoreInstanceState(savedInstanceState);\r
-        // Check, if there are ownCloud accounts\r
-        if (!accountsAreSetup()) {\r
-            showDialog(DIALOG_SETUP_ACCOUNT);\r
-        }\r
-    }\r
-\r
-    @Override\r
-    protected Dialog onCreateDialog(int id) {\r
-        Dialog dialog;\r
-        switch (id) {\r
-        case DIALOG_SETUP_ACCOUNT:\r
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
-            builder.setTitle(R.string.main_tit_accsetup);\r
-            builder.setMessage(R.string.main_wrn_accsetup);\r
-            builder.setCancelable(false);\r
-            builder.setPositiveButton(R.string.common_ok, this);\r
-            builder.setNegativeButton(R.string.common_cancel, this);\r
-            dialog = builder.create();\r
-            break;\r
-        default:\r
-            dialog = null;\r
-        }\r
-\r
-        return dialog;\r
-    }\r
-\r
-    public void onClick(DialogInterface dialog, int which) {\r
-        // In any case - we won't need it anymore\r
-        dialog.dismiss();\r
-        switch (which) {\r
-        case DialogInterface.BUTTON_POSITIVE:\r
-            Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
-            intent.putExtra("authorities",\r
-                    new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
-            startActivity(intent);\r
-            break;\r
-        case DialogInterface.BUTTON_NEGATIVE:\r
-            finish();\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    /**\r
-     * Start an activity based on the selection\r
-     * the user made\r
-     */\r
-    public void onItemClick(AdapterView<?> parent, View view, int position,\r
-            long id) {\r
-        Intent intent;\r
-        intent = (Intent) parent.getAdapter().getItem(position);\r
-        if (intent != null) {\r
-            startActivity(intent);\r
-        } else {\r
-            // TODO: Implement all of this and make this text go away ;-)\r
-            Toast toast = Toast.makeText(this, "Not yet implemented!",\r
-                    Toast.LENGTH_SHORT);\r
-            toast.show();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Checks, whether or not there are any ownCloud accounts setup.\r
-     * \r
-     * @return true, if there is at least one account.\r
-     */\r
-    private boolean accountsAreSetup() {\r
-        AccountManager accMan = AccountManager.get(this);\r
-        Account[] accounts = accMan\r
-                .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
-        return accounts.length > 0;\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/PinCodeActivity.java b/src/eu/alefzero/owncloud/ui/activity/PinCodeActivity.java
deleted file mode 100644 (file)
index 5fd7213..0000000
+++ /dev/null
@@ -1,653 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011 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 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 eu.alefzero.owncloud.ui.activity;
-
-import java.util.Arrays;
-
-import com.actionbarsherlock.app.SherlockFragmentActivity;
-
-import eu.alefzero.owncloud.R;
-
-
-import android.app.AlertDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.graphics.Typeface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.preference.PreferenceManager;
-import android.text.Editable;
-import android.text.InputType;
-import android.text.TextWatcher;
-import android.text.method.PasswordTransformationMethod;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.View.OnKeyListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.TextView;
-
-
-public class PinCodeActivity extends SherlockFragmentActivity {
-
-  
-    public final static String EXTRA_ACTIVITY = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.ACTIVITY";
-    public final static String EXTRA_NEW_STATE = "eu.alefzero.owncloud.ui.activity.PinCodeActivity.NEW_STATE";
-    
-    Button bCancel;
-    TextView mPinHdr;
-    EditText mText1;
-    EditText mText2;
-    EditText mText3;
-    EditText mText4;
-    
-    String [] tempText ={"","","",""};
-    
-    String activity;
-    
-    boolean confirmingPinCode = false;
-    boolean pinCodeChecked = false;
-    boolean newPasswordEntered = false;
-    boolean bChange = true; // to control that only one blocks jump
-    int tCounter ; // Count the number of attempts an user could introduce the PIN code
-
-    
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.pincodelock); 
-        
-        Intent intent = getIntent();
-        activity = intent.getStringExtra(EXTRA_ACTIVITY);
-     
-        bCancel = (Button) findViewById(R.id.cancel);
-        mPinHdr = (TextView) findViewById(R.id.pinHdr);
-        mText1 = (EditText) findViewById(R.id.txt1);
-        mText1.requestFocus();
-        getWindow().setSoftInputMode(android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
-        mText2 = (EditText) findViewById(R.id.txt2);
-        mText3 = (EditText) findViewById(R.id.txt3);
-        mText4 = (EditText) findViewById(R.id.txt4);
-        
-        
-        
-        SharedPreferences appPrefs = PreferenceManager
-                .getDefaultSharedPreferences(getApplicationContext());
-        
-        // Not PIN Code defined yet.
-        // In a previous version settings is allow from start
-        if ( (appPrefs.getString("PrefPinCode1", null) == null ) ){
-            setChangePincodeView(true);
-            pinCodeChecked = true; 
-            newPasswordEntered = true;
-            
-        }else{ 
-            
-            if (appPrefs.getBoolean("set_pincode", false)){
-               // pincode activated
-               if (activity.equals("preferences")){
-                // PIN has been activated yet
-                 mPinHdr.setText(R.string.pincode_configure_your_pin);
-                 pinCodeChecked = true ; // No need to check it 
-                 setChangePincodeView(true);
-               }else{
-                // PIN active
-                 bCancel.setVisibility(View.INVISIBLE);
-                 bCancel.setVisibility(View.GONE);
-                 mPinHdr.setText(R.string.pincode_enter_pin_code);
-                 setChangePincodeView(false);
-              }
-            
-           }else {
-            // pincode removal
-              mPinHdr.setText(R.string.pincode_remove_your_pincode);
-              pinCodeChecked = false;
-              setChangePincodeView(true); 
-           }
-           
-        }
-        setTextListeners();
-        
-        
-    }
-    
-
-     
-    protected void setInitVars(){
-        confirmingPinCode = false;
-        pinCodeChecked = false;
-        newPasswordEntered = false;
-
-    }
-    
-    protected void setInitView(){
-        bCancel.setVisibility(View.INVISIBLE);
-        bCancel.setVisibility(View.GONE);
-        mPinHdr.setText(R.string.pincode_enter_pin_code);
-    }
-    
-   
-    protected void setChangePincodeView(boolean state){
-       
-        if(state){
-        bCancel.setVisibility(View.VISIBLE);
-        bCancel.setOnClickListener(new OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            
-            SharedPreferences.Editor appPrefsE = PreferenceManager
-                    .getDefaultSharedPreferences(getApplicationContext()).edit();
-            
-            SharedPreferences appPrefs = PreferenceManager
-                    .getDefaultSharedPreferences(getApplicationContext());
-            
-            boolean state = appPrefs.getBoolean("set_pincode", false);
-            appPrefsE.putBoolean("set_pincode",!state); 
-            appPrefsE.commit();
-            setInitVars();
-            finish();
-            }
-        });
-        }  
-    
-    }
-    
-    
-    
-    /*
-     *  
-     */
-    protected void setTextListeners(){
-    
-        /*------------------------------------------------
-         *  FIRST BOX
-         -------------------------------------------------*/
-        
-        mText1.addTextChangedListener(new TextWatcher() {
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before,
-                    int count) {
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count,
-                    int after) {
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {
-                if (s.length() > 0) {
-                    if (!confirmingPinCode){
-                       tempText[0] = mText1.getText().toString();
-                       
-                    }
-                    mText2.requestFocus();
-                 }
-            }
-        });
-        
-        
-
-        /*------------------------------------------------
-         *  SECOND BOX 
-         -------------------------------------------------*/
-        mText2.addTextChangedListener(new TextWatcher() {
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before,
-                    int count) {
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count,
-                    int after) {
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {
-                if (s.length() > 0) {
-                    if (!confirmingPinCode){
-                        tempText[1] = mText2.getText().toString();
-                    }
-                    
-                    mText3.requestFocus();
-                }
-            }
-        });
-        mText2.setOnKeyListener(new OnKeyListener() {
-
-            @Override
-            public boolean onKey(View v, int keyCode, KeyEvent event) {
-                // TODO Auto-generated method stub
-
-                if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
-
-                    mText1.setText("");
-                    mText1.requestFocus();
-                    if (!confirmingPinCode)
-                       tempText[0] = "";
-                    bChange= false;
-                
-                }else if(!bChange){
-                    bChange=true;
-                    
-                }
-                return false;
-            }
-        });        
-        mText2.setOnFocusChangeListener(new OnFocusChangeListener() {
-               
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                // TODO Auto-generated method stub
-                
-                mText2.setCursorVisible(true);
-                if (mText1.getText().toString().equals("")){
-                    mText2.setSelected(false);
-                    mText2.setCursorVisible(false);
-                    mText1.requestFocus(); 
-                    mText1.setSelected(true);
-                    mText1.setSelection(0);
-                }
-                
-            }
-        });
-        
-        
-        /*------------------------------------------------
-         *  THIRD BOX
-         -------------------------------------------------*/
-        mText3.addTextChangedListener(new TextWatcher() {
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before,
-                    int count) {
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count,
-                    int after) {
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {
-                if (s.length() > 0) {
-                    if (!confirmingPinCode){
-                        tempText[2] = mText3.getText().toString();
-                    }
-                    mText4.requestFocus();
-                }
-            }
-        });
-        
-        mText3.setOnKeyListener(new OnKeyListener() {
-
-            @Override
-            public boolean onKey(View v, int keyCode, KeyEvent event) {
-                // TODO Auto-generated method stub
-
-                if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
-                    mText2.requestFocus();
-                    if (!confirmingPinCode)
-                        tempText[1] = "";
-                    mText2.setText("");
-                    bChange= false;
-                    
-                }else if(!bChange){
-                    bChange=true;                        
-                    
-                }
-                return false;
-            }
-        });
-        
-        mText3.setOnFocusChangeListener(new OnFocusChangeListener() {
-            
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                // TODO Auto-generated method stub
-                mText3.setCursorVisible(true);
-                if (mText1.getText().toString().equals("")){
-                    mText3.setSelected(false);
-                    mText3.setCursorVisible(false);
-                    mText1.requestFocus();
-                    mText1.setSelected(true);
-                    mText1.setSelection(0);
-                }else if (mText2.getText().toString().equals("")){
-                    mText3.setSelected(false);
-                    mText3.setCursorVisible(false);
-                    mText2.requestFocus();
-                    mText2.setSelected(true);
-                    mText2.setSelection(0);
-                }
-                
-            }
-        });
-        
-        /*------------------------------------------------
-         *  FOURTH BOX
-         -------------------------------------------------*/
-        mText4.addTextChangedListener(new TextWatcher() {
-
-            @Override
-            public void onTextChanged(CharSequence s, int start, int before,
-                    int count) {
-            }
-
-            @Override
-            public void beforeTextChanged(CharSequence s, int start, int count,
-                    int after) {
-            }
-
-            @Override
-            public void afterTextChanged(Editable s) {
-                if (s.length() > 0) {
-                    
-                    if (!confirmingPinCode){
-                       tempText[3] = mText4.getText().toString();
-                    }
-                    mText1.requestFocus();
-
-                    if (!pinCodeChecked){
-                        pinCodeChecked = checkPincode();
-                    }
-                    
-                    if (pinCodeChecked && activity.equals("FileDisplayActivity")){
-                        finish();
-                    } else if (pinCodeChecked){
-                        
-                        Intent intent = getIntent();
-                        String newState = intent.getStringExtra(EXTRA_NEW_STATE);
-                        
-                        if (newState.equals("false")){
-                            SharedPreferences.Editor appPrefs = PreferenceManager
-                                    .getDefaultSharedPreferences(getApplicationContext()).edit();
-                            appPrefs.putBoolean("set_pincode",false);
-                            appPrefs.commit();
-                            
-                            setInitVars();
-                            pinCodeEnd(false);
-                            
-                        }else{
-                        
-                            if (!confirmingPinCode){
-                                pinCodeChangeRequest();
-                             
-                            } else {
-                                confirmPincode();
-                            }
-                        }
-                   
-                        
-                    }    
-                }
-            }
-        });
-
-        
-        
-        mText4.setOnKeyListener(new OnKeyListener() {
-
-            @Override
-            public boolean onKey(View v, int keyCode, KeyEvent event) {
-                // TODO Auto-generated method stub
-
-                if (keyCode == KeyEvent.KEYCODE_DEL && bChange) {
-                    mText3.requestFocus();
-                    if (!confirmingPinCode)
-                        tempText[2]="";
-                    mText3.setText("");
-                    bChange= false;
-                    
-                }else if(!bChange){
-                    bChange=true;    
-                }
-                return false;
-            }
-        });
-        
-       mText4.setOnFocusChangeListener(new OnFocusChangeListener() {
-            
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                // TODO Auto-generated method stub
-                
-                mText4.setCursorVisible(true);
-                
-                if (mText1.getText().toString().equals("")){
-                    mText4.setSelected(false);
-                    mText4.setCursorVisible(false);
-                    mText1.requestFocus();
-                    mText1.setSelected(true);
-                    mText1.setSelection(0);
-                }else if (mText2.getText().toString().equals("")){
-                    mText4.setSelected(false);
-                    mText4.setCursorVisible(false);
-                    mText2.requestFocus();
-                    mText2.setSelected(true);
-                    mText2.setSelection(0);
-                }else if (mText3.getText().toString().equals("")){
-                    mText4.setSelected(false);
-                    mText4.setCursorVisible(false);
-                    mText3.requestFocus();
-                    mText3.setSelected(true);
-                    mText3.setSelection(0);
-                }
-                
-            }
-        });
-        
-        
-        
-    } // end setTextListener
-    
-    
-    protected void pinCodeChangeRequest(){
-    
-        clearBoxes(); 
-        mPinHdr.setText(R.string.pincode_reenter_your_pincode); 
-        confirmingPinCode =true;
-        
-    }
-    
-    
-    protected boolean checkPincode(){
-        
-        
-        SharedPreferences appPrefs = PreferenceManager
-                .getDefaultSharedPreferences(getApplicationContext());
-        
-       String pText1 = appPrefs.getString("PrefPinCode1", null);
-        String pText2 = appPrefs.getString("PrefPinCode2", null);
-        String pText3 = appPrefs.getString("PrefPinCode3", null);
-        String pText4 = appPrefs.getString("PrefPinCode4", null);
-
-        if ( tempText[0].equals(pText1) && 
-             tempText[1].equals(pText2) &&
-             tempText[2].equals(pText3) &&
-             tempText[3].equals(pText4) ) {
-            
-            return true;
-        
-        
-        }else {
-            Arrays.fill(tempText, null);
-            AlertDialog aDialog = new AlertDialog.Builder(this).create();
-            CharSequence errorSeq = getString(R.string.common_error);
-            aDialog.setTitle(errorSeq);
-            CharSequence cseq = getString(R.string.pincode_wrong);
-            aDialog.setMessage(cseq);
-            CharSequence okSeq = getString(R.string.common_ok);
-            aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
-
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    // TODO Auto-generated method stub("");
-                   return; 
-                }
-                
-            });
-            aDialog.show();
-            clearBoxes(); 
-            mPinHdr.setText(R.string.pincode_enter_pin_code);
-            newPasswordEntered = true;
-            confirmingPinCode = false;
-            
-        }
-     
-        
-        return false;
-    }
-    
-    protected void confirmPincode(){
-        
-        confirmingPinCode = false;
-        
-        String rText1 = mText1.getText().toString();
-        String rText2 = mText2.getText().toString();
-        String rText3 = mText3.getText().toString();
-        String rText4 = mText4.getText().toString();
-        
-        if ( tempText[0].equals(rText1) && 
-             tempText[1].equals(rText2) &&
-             tempText[2].equals(rText3) &&
-             tempText[3].equals(rText4) ) {
-                        
-            savePincodeAndExit();
-            
-        } else {
-            
-            Arrays.fill(tempText, null);
-            AlertDialog aDialog = new AlertDialog.Builder(this).create();
-            CharSequence errorSeq = getString(R.string.common_error);
-            aDialog.setTitle(errorSeq);
-            CharSequence cseq = getString(R.string.pincode_mismatch);
-            aDialog.setMessage(cseq);
-            CharSequence okSeq = getString(R.string.common_ok);
-            aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
-
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    // TODO Auto-generated method stub("");
-                   return; 
-                }
-                
-            });
-            aDialog.show();
-            mPinHdr.setText(R.string.pincode_configure_your_pin);
-            clearBoxes();
-        }
-    
-    }
-   
-    
-    protected void pinCodeEnd(boolean state){
-        AlertDialog aDialog = new AlertDialog.Builder(this).create();
-        
-        if (state){
-            CharSequence saveSeq = getString(R.string.common_save_exit);
-            aDialog.setTitle(saveSeq);
-            CharSequence cseq = getString(R.string.pincode_stored);
-            aDialog.setMessage(cseq);
-            
-        }else{
-            CharSequence saveSeq = getString(R.string.common_save_exit);
-            aDialog.setTitle(saveSeq);
-            CharSequence cseq = getString(R.string.pincode_removed);
-            aDialog.setMessage(cseq);
-            
-        }
-        CharSequence okSeq = getString(R.string.common_ok);
-        aDialog.setButton(okSeq, new DialogInterface.OnClickListener(){
-
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                // TODO Auto-generated method stub("");
-                finish();
-                return; 
-            }
-            
-        });
-        aDialog.show(); 
-    }
-    
-    protected void savePincodeAndExit(){
-        SharedPreferences.Editor appPrefs = PreferenceManager
-                .getDefaultSharedPreferences(getApplicationContext()).edit();
-        
-        appPrefs.putString("PrefPinCode1", tempText[0]);
-        appPrefs.putString("PrefPinCode2",tempText[1]);
-        appPrefs.putString("PrefPinCode3", tempText[2]);
-        appPrefs.putString("PrefPinCode4", tempText[3]);
-        appPrefs.putBoolean("set_pincode",true);
-        appPrefs.commit();
-        
-        pinCodeEnd(true);
-        
-        
-        
-    }
-    
-    
-    protected void clearBoxes(){
-        
-        mText1.setText("");
-        mText2.setText("");
-        mText3.setText("");
-        mText4.setText("");
-        mText1.requestFocus(); 
-    }
-    
-    
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event){
-        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount()== 0){
-            
-            if (activity.equals("preferences")){
-                SharedPreferences.Editor appPrefsE = PreferenceManager
-            
-                    .getDefaultSharedPreferences(getApplicationContext()).edit();
-            
-                SharedPreferences appPrefs = PreferenceManager
-                    .getDefaultSharedPreferences(getApplicationContext());
-            
-                boolean state = appPrefs.getBoolean("set_pincode", false);
-                appPrefsE.putBoolean("set_pincode",!state); 
-                appPrefsE.commit();
-                setInitVars();
-                finish();
-            }
-            return true; 
-            
-        }
-        
-        return super.onKeyDown(keyCode, event);
-    }
-    
-   
-
-    
-            
-}
diff --git a/src/eu/alefzero/owncloud/ui/activity/Preferences.java b/src/eu/alefzero/owncloud/ui/activity/Preferences.java
deleted file mode 100644 (file)
index c217395..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.activity;\r
-\r
-import java.util.Vector;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.content.Intent;\r
-import android.content.SharedPreferences;\r
-import android.os.Bundle;\r
-import android.preference.CheckBoxPreference;\r
-import android.preference.ListPreference;\r
-import android.preference.Preference;\r
-import android.preference.PreferenceManager;\r
-import android.preference.Preference.OnPreferenceChangeListener;\r
-import android.preference.Preference.OnPreferenceClickListener;\r
-import android.util.Log;\r
-\r
-import com.actionbarsherlock.app.ActionBar;\r
-import com.actionbarsherlock.app.SherlockPreferenceActivity;\r
-import com.actionbarsherlock.view.Menu;\r
-import com.actionbarsherlock.view.MenuItem;\r
-\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.OwnCloudSession;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.db.DbHandler;\r
-\r
-/**\r
- * An Activity that allows the user to change the application's settings.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class Preferences extends SherlockPreferenceActivity implements\r
-        OnPreferenceChangeListener{\r
-    private static final String TAG = "OwnCloudPreferences";\r
-    private final int mNewSession = 47;\r
-    private final int mEditSession = 48;\r
-    private DbHandler mDbHandler;\r
-    private Vector<OwnCloudSession> mSessions;\r
-    //private Account[] mAccounts;\r
-    //private ListPreference mAccountList;\r
-    private ListPreference mTrackingUpdateInterval;\r
-    private CheckBoxPreference mDeviceTracking;\r
-    private CheckBoxPreference pCode;\r
-    private int mSelectedMenuItem;\r
-\r
-    @Override\r
-    public void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        mDbHandler = new DbHandler(getBaseContext());\r
-        mSessions = new Vector<OwnCloudSession>();\r
-        addPreferencesFromResource(R.xml.preferences);\r
-        //populateAccountList();\r
-        ActionBar actionBar = getSherlock().getActionBar();\r
-        actionBar.setDisplayHomeAsUpEnabled(true);\r
-        Preference p = findPreference("manage_account");\r
-        if (p != null)\r
-        p.setOnPreferenceClickListener(new OnPreferenceClickListener() {\r
-            @Override\r
-            public boolean onPreferenceClick(Preference preference) {\r
-                Intent i = new Intent(getApplicationContext(), AccountSelectActivity.class);\r
-                startActivity(i);\r
-                return true;\r
-            }\r
-        });\r
-        \r
-        pCode = (CheckBoxPreference) findPreference("set_pincode");\r
-         \r
-        \r
-        if (pCode != null){\r
-            \r
-            pCode.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {\r
-                @Override\r
-                public boolean onPreferenceChange(Preference preference, Object newValue) {\r
-                                          \r
-                    Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);\r
-                    i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "preferences");\r
-                    i.putExtra(PinCodeActivity.EXTRA_NEW_STATE, newValue.toString());\r
-                    \r
-                    startActivity(i);\r
-                    \r
-                    return true;\r
-                }\r
-            });            \r
-            \r
-        }\r
-        \r
-    }\r
-\r
-\r
-    @Override\r
-    protected void onResume() {\r
-        // TODO Auto-generated method stub\r
-        SharedPreferences appPrefs = PreferenceManager\r
-                .getDefaultSharedPreferences(getApplicationContext());\r
-        \r
-        boolean state = appPrefs.getBoolean("set_pincode", false);\r
-        pCode.setChecked(state);\r
-        \r
-        super.onResume();\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * Populates the account selector\r
-     *-/\r
-    private void populateAccountList() {\r
-        AccountManager accMan = AccountManager.get(this);\r
-        mAccounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
-        mAccountList = (ListPreference) findPreference("select_oc_account");\r
-        mAccountList.setOnPreferenceChangeListener(this);\r
-\r
-        // Display the name of the current account if there is any\r
-        Account defaultAccount = AccountUtils.getCurrentOwnCloudAccount(this);\r
-        if (defaultAccount != null) {\r
-            mAccountList.setSummary(defaultAccount.name);\r
-        }\r
-        \r
-        // Transform accounts into array of string for preferences to use\r
-        String[] accNames = new String[mAccounts.length];\r
-        for (int i = 0; i < mAccounts.length; i++) {\r
-            Account account = mAccounts[i];\r
-            accNames[i] = account.name;\r
-        }\r
-\r
-        mAccountList.setEntries(accNames);\r
-        mAccountList.setEntryValues(accNames);\r
-    }*/\r
-\r
-    \r
-    \r
-    @Override\r
-    public boolean onCreateOptionsMenu(Menu menu) {\r
-        super.onCreateOptionsMenu(menu);\r
-        //MenuInflater inflater = getSherlock().getMenuInflater();\r
-        //inflater.inflate(R.menu.prefs_menu, menu);\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {\r
-        super.onMenuItemSelected(featureId, item);\r
-        Intent intent;\r
-\r
-        switch (item.getItemId()) {\r
-        //case R.id.addSessionItem:\r
-        case 1:\r
-            intent = new Intent(this, PreferencesNewSession.class);\r
-            startActivityForResult(intent, mNewSession);\r
-            break;\r
-        case R.id.SessionContextEdit:\r
-            intent = new Intent(this, PreferencesNewSession.class);\r
-            intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem)\r
-                    .getEntryId());\r
-            intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem)\r
-                    .getName());\r
-            intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem)\r
-                    .getUrl());\r
-            startActivityForResult(intent, mEditSession);\r
-            break;\r
-        case android.R.id.home:\r
-            intent = new Intent(getBaseContext(), FileDisplayActivity.class);\r
-            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);\r
-            startActivity(intent);\r
-            break;\r
-        default:\r
-            Log.w(TAG, "Unknown menu item triggered");\r
-            return false;\r
-        }\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
-        super.onActivityResult(requestCode, resultCode, data);\r
-    }\r
-\r
-    @Override\r
-    protected void onDestroy() {\r
-        mDbHandler.close();\r
-        super.onDestroy();\r
-    }\r
-\r
-    \r
-    \r
-    @Override\r
-    /**\r
-     * Updates various summaries after updates. Also starts and stops \r
-     * the\r
-     */\r
-    public boolean onPreferenceChange(Preference preference, Object newValue) {\r
-        // Update current account summary\r
-        /*if (preference.equals(mAccountList)) {\r
-            mAccountList.setSummary(newValue.toString());\r
-        }\r
-\r
-        // Update tracking interval summary\r
-        else*/ if (preference.equals(mTrackingUpdateInterval)) {\r
-            String trackingSummary = getResources().getString(\r
-                    R.string.prefs_trackmydevice_interval_summary);\r
-            trackingSummary = String.format(trackingSummary,\r
-                    newValue.toString());\r
-            mTrackingUpdateInterval.setSummary(trackingSummary);\r
-        }\r
-\r
-        // Start or stop tracking service\r
-        else if (preference.equals(mDeviceTracking)) {\r
-            Intent locationServiceIntent = new Intent();\r
-            locationServiceIntent\r
-                    .setAction("eu.alefzero.owncloud.location.LocationLauncher");\r
-            locationServiceIntent.putExtra("TRACKING_SETTING",\r
-                    (Boolean) newValue);\r
-            sendBroadcast(locationServiceIntent);\r
-        } \r
-        return true;\r
-    }\r
-    \r
-    \r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java b/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java
deleted file mode 100644 (file)
index 35d65da..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-package eu.alefzero.owncloud.ui.activity;\r
-\r
-import android.accounts.AccountAuthenticatorActivity;\r
-import android.app.Activity;\r
-import android.os.Bundle;\r
-import android.view.View;\r
-import android.view.View.OnClickListener;\r
-\r
-public class PreferencesNewSession extends AccountAuthenticatorActivity\r
-        implements OnClickListener {\r
-    @Override\r
-    public void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        // setContentView(R.layout.add_new_session);\r
-        /*\r
-         * EditText et;// = (EditText)\r
-         * findViewById(R.id.newSession_sessionName);\r
-         * \r
-         * et = (EditText) findViewById(R.id.newSession_URL); if\r
-         * (getIntent().hasExtra("sessionURL")) { try { URI uri = new\r
-         * URI(getIntent().getStringExtra("sessionURL")); String url =\r
-         * uri.getHost(); if (uri.getPort() != -1) { url += ":" +\r
-         * String.valueOf(uri.getPort()); } if (uri.getPath() != null) { url +=\r
-         * uri.getPath(); } else { url += "/"; } et.setText(url); et =\r
-         * (EditText) findViewById(R.id.newSession_username); if\r
-         * (uri.getAuthority() != null) { if (uri.getUserInfo().indexOf(':') !=\r
-         * -1) { et.setText(uri.getUserInfo().substring(0,\r
-         * uri.getUserInfo().indexOf(':'))); et = (EditText)\r
-         * findViewById(R.id.newSession_password);\r
-         * et.setText(uri.getUserInfo().substring\r
-         * (uri.getUserInfo().indexOf(':')+1)); } else {\r
-         * et.setText(uri.getUserInfo()); } }\r
-         * \r
-         * } catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +\r
-         * e.getLocalizedMessage()); } }\r
-         * \r
-         * mReturnData = new Intent(); setResult(Activity.RESULT_OK,\r
-         * mReturnData); ((Button)\r
-         * findViewById(R.id.button1)).setOnClickListener(this); ((Button)\r
-         * findViewById(R.id.button2)).setOnClickListener(this);\r
-         */\r
-    }\r
-\r
-    @Override\r
-    protected void onResume() {\r
-        super.onResume();\r
-    }\r
-\r
-    public void onClick(View v) {\r
-        /*\r
-         * switch (v.getId()) { case R.id.button1: Intent intent = new Intent();\r
-         * if (getIntent().hasExtra("sessionId")) { intent.putExtra("sessionId",\r
-         * getIntent().getIntExtra("sessionId", -1)); } //String sessionName =\r
-         * ((EditText)\r
-         * findViewById(R.id.newSession_sessionName)).getText().toString(); //\r
-         * if (sessionName.trim().equals("") || !isNameValid(sessionName)) { //\r
-         * Toast.makeText(this, R.string.new_session_session_name_error,\r
-         * Toast.LENGTH_LONG).show(); // break; // } URI uri = prepareURI(); if\r
-         * (uri != null) { //intent.putExtra("sessionName", sessionName);\r
-         * intent.putExtra("sessionURL", uri.toString());\r
-         * setResult(Activity.RESULT_OK, intent); AccountManager accMgr =\r
-         * AccountManager.get(this); Account a = new Account("OwnCloud",\r
-         * AccountAuthenticatorService.ACCOUNT_TYPE);\r
-         * accMgr.addAccountExplicitly(a, "asd", null); finish(); } break; case\r
-         * R.id.button2: setResult(Activity.RESULT_CANCELED); finish(); break; }\r
-         */\r
-    }\r
-\r
-    /*\r
-     * private URI prepareURI() { URI uri = null; String url = ""; try { String\r
-     * username = ((EditText)\r
-     * findViewById(R.id.newSession_username)).getText().toString().trim();\r
-     * String password = ((EditText)\r
-     * findViewById(R.id.newSession_password)).getText().toString().trim();\r
-     * String hostname = ((EditText)\r
-     * findViewById(R.id.newSession_URL)).getText().toString().trim(); String\r
-     * scheme; if (hostname.matches("[A-Za-z]://")) { scheme =\r
-     * hostname.substring(0, hostname.indexOf("://")+3); hostname =\r
-     * hostname.substring(hostname.indexOf("://")+3); } else { scheme =\r
-     * "http://"; } if (!username.equals("")) { if (!password.equals("")) {\r
-     * username += ":" + password + "@"; } else { username += "@"; } } url =\r
-     * scheme + username + hostname; Log.i(TAG, url); uri = new URI(url); }\r
-     * catch (URISyntaxException e) { Log.e(TAG, "Incorrect URI syntax " +\r
-     * e.getLocalizedMessage()); Toast.makeText(this,\r
-     * R.string.new_session_uri_error, Toast.LENGTH_LONG).show(); } return uri;\r
-     * }\r
-     * \r
-     * private boolean isNameValid(String string) { return\r
-     * string.matches("[A-Za-z0-9 _-]*"); }\r
-     */\r
-\r
-    @Override\r
-    public void onBackPressed() {\r
-        setResult(Activity.RESULT_CANCELED);\r
-        super.onBackPressed();\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java b/src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java
deleted file mode 100644 (file)
index 1556e0d..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  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 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 eu.alefzero.owncloud.ui.adapter;
-
-import java.io.File;
-
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.webdav.WebdavUtils;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.DataSetObserver;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-public class FileListActionListAdapter implements ListAdapter {
-
-    private Context mContext;
-    private Account mAccount;
-    private String mFilename, mFileType, mFilePath, mFileStoragePath;
-
-    private final int ITEM_DOWNLOAD = 0;
-
-    // private final int ITEM_SHARE = 1;
-
-    public FileListActionListAdapter(Cursor c, Context co, Account account) {
-        mContext = co;
-        mFilename = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_NAME));
-        mFileType = c.getString(c
-                .getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE));
-        mFilePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_PATH));
-        mFileStoragePath = c.getString(c
-                .getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
-        // mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
-        mAccount = account;
-    }
-
-    public boolean areAllItemsEnabled() {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    public boolean isEnabled(int position) {
-        // TODO Auto-generated method stub
-        return true;
-    }
-
-    public int getCount() {
-        // TODO Auto-generated method stub
-        return 1;
-    }
-
-    public Object getItem(int position) {
-        if (position == 0) {
-            Intent intent = new Intent(Intent.ACTION_VIEW);
-            if (TextUtils.isEmpty(mFileStoragePath)) {
-                intent.putExtra("toDownload", true);
-                AccountManager accm = (AccountManager) mContext
-                        .getSystemService(Context.ACCOUNT_SERVICE);
-                String ocurl = accm.getUserData(mAccount,
-                        AccountAuthenticator.KEY_OC_URL);
-                ocurl += WebdavUtils.encodePath(mFilePath + mFilename);
-                intent.setData(Uri.parse(ocurl));
-            } else {
-                intent.putExtra("toDownload", false);
-                intent.setDataAndType(Uri.fromFile(new File(mFileStoragePath)),
-                        mFileType);
-            }
-            return intent;
-        }
-        return null;
-    }
-
-    public long getItemId(int position) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    public int getItemViewType(int position) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    public View getView(int position, View convertView, ViewGroup parent) {
-        View v = convertView;
-        if (v == null) {
-            LayoutInflater vi = (LayoutInflater) mContext
-                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            v = vi.inflate(R.layout.file_display_action_list_element, null);
-        }
-
-        TextView tv;
-        ImageView iv;
-        switch (position) {
-        case ITEM_DOWNLOAD:
-            tv = (TextView) v.findViewById(R.id.textView1);
-            if (mFileStoragePath == null) {
-                tv.setText("Download");
-            } else {
-                setActionName(tv);
-            }
-            iv = (ImageView) v.findViewById(R.id.imageView1);
-            iv.setImageResource(R.drawable.download);
-            break;
-        }
-
-        return v;
-    }
-
-    public int getViewTypeCount() {
-        // TODO Auto-generated method stub
-        return 2;
-    }
-
-    public boolean hasStableIds() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public boolean isEmpty() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public void registerDataSetObserver(DataSetObserver observer) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        // TODO Auto-generated method stub
-
-    }
-
-    private void setActionName(TextView tv) {
-        if (mFileType.matches("image/.*")) {
-            tv.setText("View");
-        } else if (mFileType.matches("audio/.*")
-                || mFileType.matches("video/.*")) {
-            tv.setText("Play");
-        } else {
-            tv.setText("Open");
-        }
-    }
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java b/src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java
deleted file mode 100644 (file)
index 9ab68db..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.adapter;\r
-\r
-import java.util.Vector;\r
-\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.DisplayUtils;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.datamodel.DataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.files.services.FileDownloader;\r
-import eu.alefzero.owncloud.files.services.FileUploader;\r
-\r
-import android.accounts.Account;\r
-import android.content.Context;\r
-import android.database.DataSetObserver;\r
-import android.util.Log;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.ViewGroup;\r
-import android.widget.ImageView;\r
-import android.widget.ListAdapter;\r
-import android.widget.TextView;\r
-\r
-/**\r
- * This Adapter populates a ListView with all files and folders in an ownCloud\r
- * instance.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class FileListListAdapter implements ListAdapter {\r
-    private Context mContext;\r
-    private OCFile mFile;\r
-    private Vector<OCFile> mFiles;\r
-    private DataStorageManager mStorageManager;\r
-    private Account mAccount;\r
-\r
-    public FileListListAdapter(OCFile file, DataStorageManager storage_man,\r
-            Context context) {\r
-        mFile = file;\r
-        mStorageManager = storage_man;\r
-        mFiles = mStorageManager.getDirectoryContent(mFile);\r
-        mContext = context;\r
-        mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext);\r
-    }\r
-\r
-    @Override\r
-    public boolean areAllItemsEnabled() {\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean isEnabled(int position) {\r
-        // TODO Auto-generated method stub\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public int getCount() {\r
-        return mFiles != null ? mFiles.size() : 0;\r
-    }\r
-\r
-    @Override\r
-    public Object getItem(int position) {\r
-        if (mFiles.size() <= position)\r
-            return null;\r
-        return mFiles.get(position);\r
-    }\r
-\r
-    @Override\r
-    public long getItemId(int position) {\r
-        return mFiles != null ? mFiles.get(position).getFileId() : 0;\r
-    }\r
-\r
-    @Override\r
-    public int getItemViewType(int position) {\r
-        // TODO Auto-generated method stub\r
-        return 0;\r
-    }\r
-\r
-    @Override\r
-    public View getView(int position, View convertView, ViewGroup parent) {\r
-        View view = convertView;\r
-        if (view == null) {\r
-            LayoutInflater inflator = (LayoutInflater) mContext\r
-                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
-            view = inflator.inflate(R.layout.list_layout, null);\r
-        }\r
-        if (mFiles.size() > position) {\r
-            OCFile file = mFiles.get(position);\r
-            TextView fileName = (TextView) view.findViewById(R.id.Filename);\r
-            String name = file.getFileName();\r
-\r
-            fileName.setText(name);\r
-            ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
-            if (file.getMimetype() == null || !file.getMimetype().equals("DIR")) {\r
-                fileIcon.setImageResource(R.drawable.file);\r
-            } else {\r
-                fileIcon.setImageResource(R.drawable.ic_menu_archive);\r
-            }\r
-            ImageView localStateView = (ImageView) view.findViewById(R.id.imageView2);\r
-            if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {\r
-                localStateView.setImageResource(R.drawable.downloading_file_indicator);\r
-                localStateView.setVisibility(View.VISIBLE);\r
-            } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {\r
-                localStateView.setImageResource(R.drawable.uploading_file_indicator);\r
-                localStateView.setVisibility(View.VISIBLE);\r
-            } else if (file.isDown()) {\r
-                localStateView.setImageResource(R.drawable.local_file_indicator);\r
-                localStateView.setVisibility(View.VISIBLE);\r
-            } else {\r
-                localStateView.setVisibility(View.INVISIBLE);\r
-            }\r
-                /*\r
-            ImageView down = (ImageView) view.findViewById(R.id.imageView2);\r
-            ImageView downloading = (ImageView) view.findViewById(R.id.imageView4);\r
-            ImageView uploading = (ImageView) view.findViewById(R.id.imageView5);\r
-            if (FileDownloader.isDownloading(mAccount, file.getRemotePath())) {\r
-                down.setVisibility(View.INVISIBLE);\r
-                downloading.setVisibility(View.VISIBLE);\r
-                uploading.setVisibility(View.INVISIBLE);\r
-            } else if (FileUploader.isUploading(mAccount, file.getRemotePath())) {\r
-                down.setVisibility(View.INVISIBLE);\r
-                downloading.setVisibility(View.INVISIBLE);\r
-                uploading.setVisibility(View.VISIBLE);\r
-            } else if (file.isDown()) {\r
-                 down.setVisibility(View.VISIBLE);\r
-                 downloading.setVisibility(View.INVISIBLE);\r
-                 uploading.setVisibility(View.INVISIBLE);\r
-            } else {\r
-                down.setVisibility(View.INVISIBLE);\r
-                downloading.setVisibility(View.INVISIBLE);\r
-                uploading.setVisibility(View.INVISIBLE);\r
-            }*/\r
-                \r
-            if (!file.isDirectory()) {\r
-                view.findViewById(R.id.file_size).setVisibility(View.VISIBLE);\r
-                view.findViewById(R.id.last_mod).setVisibility(View.VISIBLE);\r
-                ((TextView)view.findViewById(R.id.file_size)).setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));\r
-                ((TextView)view.findViewById(R.id.last_mod)).setText(DisplayUtils.unixTimeToHumanReadable(file.getModificationTimestamp()));\r
-                // this if-else is needed even thoe fav icon is visible by default\r
-                // because android reuses views in listview\r
-                if (!file.keepInSync()) {\r
-                    view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
-                } else {\r
-                    view.findViewById(R.id.imageView3).setVisibility(View.VISIBLE);\r
-                }\r
-            } else {\r
-               view.findViewById(R.id.file_size).setVisibility(View.GONE);\r
-               view.findViewById(R.id.last_mod).setVisibility(View.GONE);\r
-               view.findViewById(R.id.imageView3).setVisibility(View.GONE);\r
-            }\r
-        }\r
-\r
-        return view;\r
-    }\r
-\r
-    @Override\r
-    public int getViewTypeCount() {\r
-        return 4;\r
-    }\r
-\r
-    @Override\r
-    public boolean hasStableIds() {\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean isEmpty() {\r
-        return mFiles != null ? mFiles.isEmpty() : false;\r
-    }\r
-\r
-    @Override\r
-    public void registerDataSetObserver(DataSetObserver observer) {\r
-        // TODO Auto-generated method stub\r
-\r
-    }\r
-\r
-    @Override\r
-    public void unregisterDataSetObserver(DataSetObserver observer) {\r
-        // TODO Auto-generated method stub\r
-\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java b/src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java
deleted file mode 100644 (file)
index 7128886..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.adapter;\r
-\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.ViewGroup;\r
-import android.widget.BaseAdapter;\r
-import android.widget.ImageView;\r
-import android.widget.TextView;\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;\r
-import eu.alefzero.owncloud.ui.activity.Preferences;\r
-\r
-/**\r
- * Populates the landing screen icons.\r
- * \r
- * @author Lennart Rosam\r
- * \r
- */\r
-public class LandingScreenAdapter extends BaseAdapter {\r
-\r
-    private Context mContext;\r
-\r
-    private final Integer[] mLandingScreenIcons = { R.drawable.home,\r
-            R.drawable.music, R.drawable.contacts, R.drawable.calendar,\r
-            android.R.drawable.ic_menu_agenda, R.drawable.settings };\r
-\r
-    private final Integer[] mLandingScreenTexts = { R.string.main_files,\r
-            R.string.main_music, R.string.main_contacts,\r
-            R.string.main_calendar, R.string.main_bookmarks,\r
-            R.string.main_settings };\r
-\r
-    public LandingScreenAdapter(Context context) {\r
-        mContext = context;\r
-    }\r
-\r
-    @Override\r
-    public int getCount() {\r
-        return mLandingScreenIcons.length;\r
-    }\r
-\r
-    @Override\r
-    /**\r
-     * Returns the Intent associated with this object\r
-     * or null if the functionality is not yet implemented\r
-     */\r
-    public Object getItem(int position) {\r
-        Intent intent = new Intent();\r
-\r
-        switch (position) {\r
-        case 0:\r
-            /*\r
-             * The FileDisplayActivity requires the ownCloud account as an\r
-             * parcableExtra. We will put in the one that is selected in the\r
-             * preferences\r
-             */\r
-            intent.setClass(mContext, FileDisplayActivity.class);\r
-            intent.putExtra("ACCOUNT",\r
-                    AccountUtils.getCurrentOwnCloudAccount(mContext));\r
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);\r
-            break;\r
-        case 5:\r
-            intent.setClass(mContext, Preferences.class);\r
-            break;\r
-        default:\r
-            intent = null;\r
-        }\r
-        return intent;\r
-    }\r
-\r
-    @Override\r
-    public long getItemId(int position) {\r
-        return position;\r
-    }\r
-\r
-    @Override\r
-    public View getView(int position, View convertView, ViewGroup parent) {\r
-        if (convertView == null) {\r
-            LayoutInflater inflator = LayoutInflater.from(mContext);\r
-            convertView = inflator.inflate(R.layout.landing_page_item, null);\r
-\r
-            ImageView icon = (ImageView) convertView\r
-                    .findViewById(R.id.gridImage);\r
-            TextView iconText = (TextView) convertView\r
-                    .findViewById(R.id.gridText);\r
-\r
-            icon.setImageResource(mLandingScreenIcons[position]);\r
-            iconText.setText(mLandingScreenTexts[position]);\r
-        }\r
-        return convertView;\r
-    }\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java b/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java
deleted file mode 100644 (file)
index e17cf79..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-public class AuthenticatorAccountDetailsFragment extends SherlockFragment {
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java b/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java
deleted file mode 100644 (file)
index 84ef887..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import com.actionbarsherlock.app.SherlockFragment;
-
-public class AuthenticatorGetStartedFragment extends SherlockFragment {
-
-}
diff --git a/src/eu/alefzero/owncloud/ui/fragment/ConfirmationDialogFragment.java b/src/eu/alefzero/owncloud/ui/fragment/ConfirmationDialogFragment.java
deleted file mode 100644 (file)
index cc6a0f7..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.util.Log;
-
-import com.actionbarsherlock.app.SherlockDialogFragment;
-
-import eu.alefzero.owncloud.R;
-
-public class ConfirmationDialogFragment extends SherlockDialogFragment {
-
-    public final static String ARG_CONF_RESOURCE_ID = "resource_id";
-    public final static String ARG_CONF_ARGUMENTS = "string_array";
-    
-    public final static String ARG_POSITIVE_BTN_RES = "positive_btn_res";
-    public final static String ARG_NEUTRAL_BTN_RES = "neutral_btn_res";
-    public final static String ARG_NEGATIVE_BTN_RES = "negative_btn_res";
-    
-    private ConfirmationDialogFragmentListener mListener;
-    
-    public static ConfirmationDialogFragment newInstance(int string_id, String[] arguments, int posBtn, int neuBtn, int negBtn) {
-        ConfirmationDialogFragment frag = new ConfirmationDialogFragment();
-        Bundle args = new Bundle();
-        args.putInt(ARG_CONF_RESOURCE_ID, string_id);
-        args.putStringArray(ARG_CONF_ARGUMENTS, arguments);
-        args.putInt(ARG_POSITIVE_BTN_RES, posBtn);
-        args.putInt(ARG_NEUTRAL_BTN_RES, neuBtn);
-        args.putInt(ARG_NEGATIVE_BTN_RES, negBtn);
-        frag.setArguments(args);
-        return frag;
-    }
-    
-    public void setOnConfirmationListener(ConfirmationDialogFragmentListener listener) {
-        mListener = listener;
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        Object[] confirmationTarget = getArguments().getStringArray(ARG_CONF_ARGUMENTS);
-        int resourceId = getArguments().getInt(ARG_CONF_RESOURCE_ID, -1);
-        int posBtn = getArguments().getInt(ARG_POSITIVE_BTN_RES, -1);
-        int neuBtn = getArguments().getInt(ARG_NEUTRAL_BTN_RES, -1);
-        int negBtn = getArguments().getInt(ARG_NEGATIVE_BTN_RES, -1);
-        
-        if (confirmationTarget == null || resourceId == -1) {
-            Log.wtf(getTag(), "Calling confirmation dialog without resource or arguments");
-            return null;
-        }
-
-        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
-            .setIcon(android.R.drawable.ic_dialog_alert)
-            .setMessage(String.format(getString(resourceId), confirmationTarget))
-            .setTitle(android.R.string.dialog_alert_title);
-        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
-            builder.setIconAttribute(android.R.attr.alertDialogIcon);
-        }
-        
-        if (posBtn != -1)
-            builder.setPositiveButton(posBtn,
-                    new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int whichButton) {
-                            mListener.onConfirmation(getTag()); 
-                        }
-                    });
-        if (neuBtn != -1)
-            builder.setNeutralButton(neuBtn,
-                    new DialogInterface.OnClickListener() {
-                        public void onClick(DialogInterface dialog, int whichButton) {
-                            mListener.onNeutral(getTag()); 
-                        }
-                    });
-        if (negBtn != -1)
-            builder.setNegativeButton(negBtn,
-                    new DialogInterface.OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            mListener.onCancel(getTag());
-                        }
-                    });
-      return builder.create();
-    }
-    
-    
-    public interface ConfirmationDialogFragmentListener {
-        public void onConfirmation(String callerTag);
-        public void onNeutral(String callerTag);
-        public void onCancel(String callerTag);
-    }
-    
-}
-
diff --git a/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java b/src/eu/alefzero/owncloud/ui/fragment/FileDetailFragment.java
deleted file mode 100644 (file)
index f8f4206..0000000
+++ /dev/null
@@ -1,1126 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.fragment;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.apache.commons.httpclient.HttpException;\r
-import org.apache.commons.httpclient.methods.GetMethod;\r
-import org.apache.commons.httpclient.methods.PostMethod;\r
-import org.apache.commons.httpclient.methods.StringRequestEntity;\r
-import org.apache.commons.httpclient.params.HttpConnectionManagerParams;\r
-import org.apache.http.HttpStatus;\r
-import org.apache.http.NameValuePair;\r
-import org.apache.http.client.utils.URLEncodedUtils;\r
-import org.apache.http.message.BasicNameValuePair;\r
-import org.apache.http.protocol.HTTP;\r
-import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;\r
-import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;\r
-import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;\r
-import org.json.JSONException;\r
-import org.json.JSONObject;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.annotation.SuppressLint;\r
-import android.app.Activity;\r
-import android.content.ActivityNotFoundException;\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.content.res.Resources.NotFoundException;\r
-import android.graphics.Bitmap;\r
-import android.graphics.BitmapFactory;\r
-import android.graphics.BitmapFactory.Options;\r
-import android.graphics.Point;\r
-import android.net.Uri;\r
-import android.os.AsyncTask;\r
-import android.os.Bundle;\r
-import android.os.Handler;\r
-import android.support.v4.app.FragmentTransaction;\r
-import android.util.Log;\r
-import android.view.Display;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.View.OnClickListener;\r
-import android.view.ViewGroup;\r
-import android.view.WindowManager.LayoutParams;\r
-import android.webkit.MimeTypeMap;\r
-import android.widget.Button;\r
-import android.widget.CheckBox;\r
-import android.widget.ImageView;\r
-import android.widget.TextView;\r
-import android.widget.Toast;\r
-\r
-import com.actionbarsherlock.app.SherlockDialogFragment;\r
-import com.actionbarsherlock.app.SherlockFragment;\r
-\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.DisplayUtils;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.datamodel.FileDataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.files.services.FileDownloader;\r
-import eu.alefzero.owncloud.files.services.FileUploader;\r
-import eu.alefzero.owncloud.ui.activity.FileDetailActivity;\r
-import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;\r
-import eu.alefzero.owncloud.utils.OwnCloudVersion;\r
-import eu.alefzero.webdav.WebdavClient;\r
-import eu.alefzero.webdav.WebdavUtils;\r
-\r
-/**\r
- * This Fragment is used to display the details about a file.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class FileDetailFragment extends SherlockFragment implements\r
-        OnClickListener, ConfirmationDialogFragment.ConfirmationDialogFragmentListener {\r
-\r
-    public static final String EXTRA_FILE = "FILE";\r
-    public static final String EXTRA_ACCOUNT = "ACCOUNT";\r
-\r
-    private FileDetailFragment.ContainerActivity mContainerActivity;\r
-    \r
-    private int mLayout;\r
-    private View mView;\r
-    private OCFile mFile;\r
-    private Account mAccount;\r
-    private ImageView mPreview;\r
-    \r
-    private DownloadFinishReceiver mDownloadFinishReceiver;\r
-    private UploadFinishReceiver mUploadFinishReceiver;\r
-\r
-    private static final String TAG = "FileDetailFragment";\r
-    public static final String FTAG = "FileDetails"; \r
-    public static final String FTAG_CONFIRMATION = "REMOVE_CONFIRMATION_FRAGMENT";\r
-\r
-    \r
-    /**\r
-     * Creates an empty details fragment.\r
-     * \r
-     * It's necessary to keep a public constructor without parameters; the system uses it when tries to reinstantiate a fragment automatically. \r
-     */\r
-    public FileDetailFragment() {\r
-        mFile = null;\r
-        mAccount = null;\r
-        mLayout = R.layout.file_details_empty;\r
-    }\r
-    \r
-    \r
-    /**\r
-     * Creates a details fragment.\r
-     * \r
-     * When 'fileToDetail' or 'ocAccount' are null, creates a dummy layout (to use when a file wasn't tapped before).\r
-     * \r
-     * @param fileToDetail      An {@link OCFile} to show in the fragment\r
-     * @param ocAccount         An ownCloud account; needed to start downloads\r
-     */\r
-    public FileDetailFragment(OCFile fileToDetail, Account ocAccount){\r
-        mFile = fileToDetail;\r
-        mAccount = ocAccount;\r
-        mLayout = R.layout.file_details_empty;\r
-        \r
-        if(fileToDetail != null && ocAccount != null) {\r
-            mLayout = R.layout.file_details_fragment;\r
-        }\r
-    }\r
-    \r
-\r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onAttach(Activity activity) {\r
-        super.onAttach(activity);\r
-        try {\r
-            mContainerActivity = (ContainerActivity) activity;\r
-        } catch (ClassCastException e) {\r
-            throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");\r
-        }\r
-    }\r
-    \r
-    \r
-    @Override\r
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
-            Bundle savedInstanceState) {\r
-        super.onCreateView(inflater, container, savedInstanceState);\r
-        \r
-        if (savedInstanceState != null) {\r
-            mFile = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);\r
-            mAccount = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_ACCOUNT);\r
-        }\r
-        \r
-        View view = null;\r
-        view = inflater.inflate(mLayout, container, false);\r
-        mView = view;\r
-        \r
-        if (mLayout == R.layout.file_details_fragment) {\r
-            mView.findViewById(R.id.fdKeepInSync).setOnClickListener(this);\r
-            mView.findViewById(R.id.fdRenameBtn).setOnClickListener(this);\r
-            mView.findViewById(R.id.fdDownloadBtn).setOnClickListener(this);\r
-            mView.findViewById(R.id.fdOpenBtn).setOnClickListener(this);\r
-            mView.findViewById(R.id.fdRemoveBtn).setOnClickListener(this);\r
-            //mView.findViewById(R.id.fdShareBtn).setOnClickListener(this);\r
-            mPreview = (ImageView)mView.findViewById(R.id.fdPreview);\r
-        }\r
-        \r
-        updateFileDetails();\r
-        return view;\r
-    }\r
-    \r
-\r
-    @Override\r
-    public void onSaveInstanceState(Bundle outState) {\r
-        Log.i(getClass().toString(), "onSaveInstanceState() start");\r
-        super.onSaveInstanceState(outState);\r
-        outState.putParcelable(FileDetailFragment.EXTRA_FILE, mFile);\r
-        outState.putParcelable(FileDetailFragment.EXTRA_ACCOUNT, mAccount);\r
-        Log.i(getClass().toString(), "onSaveInstanceState() end");\r
-    }\r
-\r
-    \r
-    @Override\r
-    public void onResume() {\r
-        super.onResume();\r
-        \r
-        mDownloadFinishReceiver = new DownloadFinishReceiver();\r
-        IntentFilter filter = new IntentFilter(\r
-                FileDownloader.DOWNLOAD_FINISH_MESSAGE);\r
-        getActivity().registerReceiver(mDownloadFinishReceiver, filter);\r
-        \r
-        mUploadFinishReceiver = new UploadFinishReceiver();\r
-        filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);\r
-        getActivity().registerReceiver(mUploadFinishReceiver, filter);\r
-        \r
-        mPreview = (ImageView)mView.findViewById(R.id.fdPreview);\r
-    }\r
-\r
-    @Override\r
-    public void onPause() {\r
-        super.onPause();\r
-        \r
-        getActivity().unregisterReceiver(mDownloadFinishReceiver);\r
-        mDownloadFinishReceiver = null;\r
-        \r
-        getActivity().unregisterReceiver(mUploadFinishReceiver);\r
-        mUploadFinishReceiver = null;\r
-        \r
-        if (mPreview != null) {\r
-            mPreview = null;\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public View getView() {\r
-        return super.getView() == null ? mView : super.getView();\r
-    }\r
-\r
-    \r
-    \r
-    @Override\r
-    public void onClick(View v) {\r
-        switch (v.getId()) {\r
-            case R.id.fdDownloadBtn: {\r
-                Intent i = new Intent(getActivity(), FileDownloader.class);\r
-                i.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);\r
-                i.putExtra(FileDownloader.EXTRA_REMOTE_PATH, mFile.getRemotePath());\r
-                i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());\r
-                i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());\r
-                \r
-                // update ui \r
-                setButtonsForTransferring();\r
-                \r
-                getActivity().startService(i);\r
-                mContainerActivity.onFileStateChanged();    // this is not working; it is performed before the fileDownloadService registers it as 'in progress'\r
-                break;\r
-            }\r
-            case R.id.fdKeepInSync: {\r
-                CheckBox cb = (CheckBox) getView().findViewById(R.id.fdKeepInSync);\r
-                mFile.setKeepInSync(cb.isChecked());\r
-                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());\r
-                fdsm.saveFile(mFile);\r
-                if (mFile.keepInSync()) {\r
-                    onClick(getView().findViewById(R.id.fdDownloadBtn));\r
-                } else {    \r
-                    mContainerActivity.onFileStateChanged();    // put inside 'else' to not call it twice (here, and in the virtual click on fdDownloadBtn)\r
-                }\r
-                break;\r
-            }\r
-            case R.id.fdRenameBtn: {\r
-                EditNameFragment dialog = EditNameFragment.newInstance(mFile.getFileName());\r
-                dialog.show(getFragmentManager(), "nameeditdialog");\r
-                dialog.setOnDismissListener(this);\r
-                break;\r
-            }   \r
-            case R.id.fdRemoveBtn: {\r
-                ConfirmationDialogFragment confDialog = ConfirmationDialogFragment.newInstance(\r
-                        R.string.confirmation_remove_alert,\r
-                        new String[]{mFile.getFileName()},\r
-                        mFile.isDown() ? R.string.confirmation_remove_remote_and_local : R.string.confirmation_remove_remote,\r
-                        mFile.isDown() ? R.string.confirmation_remove_local : -1,\r
-                        R.string.common_cancel);\r
-                confDialog.setOnConfirmationListener(this);\r
-                confDialog.show(getFragmentManager(), FTAG_CONFIRMATION);\r
-                break;\r
-            }\r
-            case R.id.fdOpenBtn: {\r
-                String storagePath = mFile.getStoragePath();\r
-                String encodedStoragePath = WebdavUtils.encodePath(storagePath);\r
-                try {\r
-                    Intent i = new Intent(Intent.ACTION_VIEW);\r
-                    i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mFile.getMimetype());\r
-                    i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);\r
-                    startActivity(i);\r
-                    \r
-                } catch (Throwable t) {\r
-                    Log.e(TAG, "Fail when trying to open with the mimeType provided from the ownCloud server: " + mFile.getMimetype());\r
-                    boolean toastIt = true; \r
-                    String mimeType = "";\r
-                    try {\r
-                        Intent i = new Intent(Intent.ACTION_VIEW);\r
-                        mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(storagePath.substring(storagePath.lastIndexOf('.') + 1));\r
-                        if (mimeType != null && !mimeType.equals(mFile.getMimetype())) {\r
-                            i.setDataAndType(Uri.parse("file://"+ encodedStoragePath), mimeType);\r
-                            i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);\r
-                            startActivity(i);\r
-                            toastIt = false;\r
-                        }\r
-                        \r
-                    } catch (IndexOutOfBoundsException e) {\r
-                        Log.e(TAG, "Trying to find out MIME type of a file without extension: " + storagePath);\r
-                        \r
-                    } catch (ActivityNotFoundException e) {\r
-                        Log.e(TAG, "No activity found to handle: " + storagePath + " with MIME type " + mimeType + " obtained from extension");\r
-                        \r
-                    } catch (Throwable th) {\r
-                        Log.e(TAG, "Unexpected problem when opening: " + storagePath, th);\r
-                        \r
-                    } finally {\r
-                        if (toastIt) {\r
-                            Toast.makeText(getActivity(), "There is no application to handle file " + mFile.getFileName(), Toast.LENGTH_SHORT).show();\r
-                        }\r
-                    }\r
-                    \r
-                }\r
-                break;\r
-            }\r
-            default:\r
-                Log.e(TAG, "Incorrect view clicked!");\r
-        }\r
-        \r
-        /* else if (v.getId() == R.id.fdShareBtn) {\r
-            Thread t = new Thread(new ShareRunnable(mFile.getRemotePath()));\r
-            t.start();\r
-        }*/\r
-    }\r
-    \r
-    \r
-    @Override\r
-    public void onConfirmation(String callerTag) {\r
-        if (callerTag.equals(FTAG_CONFIRMATION)) {\r
-            FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
-            if (fdsm.getFileById(mFile.getFileId()) != null) {\r
-                new Thread(new RemoveRunnable(mFile, mAccount, new Handler())).start();\r
-                boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
-                getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
-            }\r
-        }\r
-    }\r
-    \r
-    @Override\r
-    public void onNeutral(String callerTag) {\r
-        FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
-        File f = null;\r
-        if (mFile.isDown() && (f = new File(mFile.getStoragePath())).exists()) {\r
-            f.delete();\r
-            mFile.setStoragePath(null);\r
-            fdsm.saveFile(mFile);\r
-            updateFileDetails(mFile, mAccount);\r
-        }\r
-    }\r
-    \r
-    @Override\r
-    public void onCancel(String callerTag) {\r
-        Log.d(TAG, "REMOVAL CANCELED");\r
-    }\r
-    \r
-    \r
-    /**\r
-     * Check if the fragment was created with an empty layout. An empty fragment can't show file details, must be replaced.\r
-     * \r
-     * @return  True when the fragment was created with the empty layout.\r
-     */\r
-    public boolean isEmpty() {\r
-        return mLayout == R.layout.file_details_empty;\r
-    }\r
-\r
-    \r
-    /**\r
-     * Can be used to get the file that is currently being displayed.\r
-     * @return The file on the screen.\r
-     */\r
-    public OCFile getDisplayedFile(){\r
-        return mFile;\r
-    }\r
-    \r
-    /**\r
-     * Use this method to signal this Activity that it shall update its view.\r
-     * \r
-     * @param file : An {@link OCFile}\r
-     */\r
-    public void updateFileDetails(OCFile file, Account ocAccount) {\r
-        mFile = file;\r
-        mAccount = ocAccount;\r
-        updateFileDetails();\r
-    }\r
-    \r
-\r
-    /**\r
-     * Updates the view with all relevant details about that file.\r
-     */\r
-    public void updateFileDetails() {\r
-\r
-        if (mFile != null && mAccount != null && mLayout == R.layout.file_details_fragment) {\r
-            \r
-            // set file details\r
-            setFilename(mFile.getFileName());\r
-            setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile\r
-                    .getMimetype()));\r
-            setFilesize(mFile.getFileLength());\r
-            if(ocVersionSupportsTimeCreated()){\r
-                setTimeCreated(mFile.getCreationTimestamp());\r
-            }\r
-           \r
-            setTimeModified(mFile.getModificationTimestamp());\r
-            \r
-            CheckBox cb = (CheckBox)getView().findViewById(R.id.fdKeepInSync);\r
-            cb.setChecked(mFile.keepInSync());\r
-\r
-            // configure UI for depending upon local state of the file\r
-            if (FileDownloader.isDownloading(mAccount, mFile.getRemotePath()) || FileUploader.isUploading(mAccount, mFile.getRemotePath())) {\r
-                setButtonsForTransferring();\r
-                \r
-            } else if (mFile.isDown()) {\r
-                // Update preview\r
-                if (mFile.getMimetype().startsWith("image/")) {\r
-                    BitmapLoader bl = new BitmapLoader();\r
-                    bl.execute(new String[]{mFile.getStoragePath()});\r
-                }\r
-                \r
-                setButtonsForDown();\r
-                \r
-            } else {\r
-                setButtonsForRemote();\r
-            }\r
-        }\r
-    }\r
-    \r
-    \r
-    /**\r
-     * Updates the filename in view\r
-     * @param filename to set\r
-     */\r
-    private void setFilename(String filename) {\r
-        TextView tv = (TextView) getView().findViewById(R.id.fdFilename);\r
-        if (tv != null)\r
-            tv.setText(filename);\r
-    }\r
-\r
-    /**\r
-     * Updates the MIME type in view\r
-     * @param mimetype to set\r
-     */\r
-    private void setFiletype(String mimetype) {\r
-        TextView tv = (TextView) getView().findViewById(R.id.fdType);\r
-        if (tv != null)\r
-            tv.setText(mimetype);\r
-    }\r
-\r
-    /**\r
-     * Updates the file size in view\r
-     * @param filesize in bytes to set\r
-     */\r
-    private void setFilesize(long filesize) {\r
-        TextView tv = (TextView) getView().findViewById(R.id.fdSize);\r
-        if (tv != null)\r
-            tv.setText(DisplayUtils.bytesToHumanReadable(filesize));\r
-    }\r
-    \r
-    /**\r
-     * Updates the time that the file was created in view\r
-     * @param milliseconds Unix time to set\r
-     */\r
-    private void setTimeCreated(long milliseconds){\r
-        TextView tv = (TextView) getView().findViewById(R.id.fdCreated);\r
-        TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);\r
-        if(tv != null){\r
-            tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));\r
-            tv.setVisibility(View.VISIBLE);\r
-            tvLabel.setVisibility(View.VISIBLE);\r
-        }\r
-    }\r
-    \r
-    /**\r
-     * Updates the time that the file was last modified\r
-     * @param milliseconds Unix time to set\r
-     */\r
-    private void setTimeModified(long milliseconds){\r
-        TextView tv = (TextView) getView().findViewById(R.id.fdModified);\r
-        if(tv != null){\r
-            tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));\r
-        }\r
-    }\r
-    \r
-    /**\r
-     * Enables or disables buttons for a file being downloaded\r
-     */\r
-    private void setButtonsForTransferring() {\r
-        if (!isEmpty()) {\r
-            Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);\r
-            //downloadButton.setText(R.string.filedetails_download_in_progress);    // ugly\r
-            downloadButton.setEnabled(false);   // TODO replace it with a 'cancel download' button\r
-        \r
-            // let's protect the user from himself ;)\r
-            ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);\r
-            ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(false);\r
-            ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(false);\r
-        }\r
-    }\r
-    \r
-    /**\r
-     * Enables or disables buttons for a file locally available \r
-     */\r
-    private void setButtonsForDown() {\r
-        if (!isEmpty()) {\r
-            Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);\r
-            //downloadButton.setText(R.string.filedetails_redownload);      // ugly\r
-            downloadButton.setEnabled(true);\r
-        \r
-            ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(true);\r
-            ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);\r
-            ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Enables or disables buttons for a file not locally available \r
-     */\r
-    private void setButtonsForRemote() {\r
-        if (!isEmpty()) {\r
-            Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);\r
-            //downloadButton.setText(R.string.filedetails_download);    // unnecessary\r
-            downloadButton.setEnabled(true);\r
-            \r
-            ((Button) getView().findViewById(R.id.fdOpenBtn)).setEnabled(false);\r
-            ((Button) getView().findViewById(R.id.fdRenameBtn)).setEnabled(true);\r
-            ((Button) getView().findViewById(R.id.fdRemoveBtn)).setEnabled(true);\r
-        }\r
-    }\r
-    \r
-\r
-    /**\r
-     * In ownCloud 3.X.X and 4.X.X there is a bug that SabreDAV does not return\r
-     * the time that the file was created. There is a chance that this will\r
-     * be fixed in future versions. Use this method to check if this version of\r
-     * ownCloud has this fix.\r
-     * @return True, if ownCloud the ownCloud version is supporting creation time\r
-     */\r
-    private boolean ocVersionSupportsTimeCreated(){\r
-        /*if(mAccount != null){\r
-            AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);\r
-            OwnCloudVersion ocVersion = new OwnCloudVersion(accManager\r
-                    .getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
-            if(ocVersion.compareTo(new OwnCloudVersion(0x030000)) < 0) {\r
-                return true;\r
-            }\r
-        }*/\r
-        return false;\r
-    }\r
-    \r
-    \r
-    /**\r
-     * Interface to implement by any Activity that includes some instance of FileDetailFragment\r
-     * \r
-     * @author David A. Velasco\r
-     */\r
-    public interface ContainerActivity {\r
-\r
-        /**\r
-         * Callback method invoked when the detail fragment wants to notice its container \r
-         * activity about a relevant state the file shown by the fragment.\r
-         * \r
-         * Added to notify to FileDisplayActivity about the need of refresh the files list. \r
-         * \r
-         * Currently called when:\r
-         *  - a download is started;\r
-         *  - a rename is completed;\r
-         *  - a deletion is completed;\r
-         *  - the 'inSync' flag is changed;\r
-         */\r
-        public void onFileStateChanged();\r
-        \r
-    }\r
-    \r
-\r
-    /**\r
-     * Once the file download has finished -> update view\r
-     * @author Bartek Przybylski\r
-     */\r
-    private class DownloadFinishReceiver extends BroadcastReceiver {\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);\r
-\r
-            if (!isEmpty() && accountName.equals(mAccount.name)) {\r
-                boolean downloadWasFine = intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false);\r
-                String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);\r
-                if (mFile.getRemotePath().equals(downloadedRemotePath)) {\r
-                    if (downloadWasFine) {\r
-                        mFile.setStoragePath(intent.getStringExtra(FileDownloader.EXTRA_FILE_PATH));    // updates the local object without accessing the database again\r
-                    }\r
-                    updateFileDetails();    // it updates the buttons; must be called although !downloadWasFine\r
-                }\r
-            }\r
-        }\r
-    }\r
-    \r
-    \r
-    /**\r
-     * Once the file upload has finished -> update view\r
-     * \r
-     * Being notified about the finish of an upload is necessary for the next sequence:\r
-     *   1. Upload a big file.\r
-     *   2. Force a synchronization; if it finished before the upload, the file in transfer will be included in the local database and in the file list\r
-     *      of its containing folder; the the server includes it in the PROPFIND requests although it's not fully upload. \r
-     *   3. Click the file in the list to see its details.\r
-     *   4. Wait for the upload finishes; at this moment, the details view must be refreshed to enable the action buttons.\r
-     */\r
-    private class UploadFinishReceiver extends BroadcastReceiver {\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);\r
-\r
-            if (!isEmpty() && accountName.equals(mAccount.name)) {\r
-                boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);\r
-                String uploadRemotePath = intent.getStringExtra(FileUploader.EXTRA_REMOTE_PATH);\r
-                if (mFile.getRemotePath().equals(uploadRemotePath)) {\r
-                    if (uploadWasFine) {\r
-                        FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());\r
-                        mFile = fdsm.getFileByPath(mFile.getRemotePath());\r
-                    }\r
-                    updateFileDetails();    // it updates the buttons; must be called although !uploadWasFine; interrupted uploads still leave an incomplete file in the server\r
-                }\r
-            }\r
-        }\r
-    }\r
-    \r
-\r
-    // this is a temporary class for sharing purposes, it need to be replaced in transfer service\r
-    private class ShareRunnable implements Runnable {\r
-        private String mPath;\r
-\r
-        public ShareRunnable(String path) {\r
-            mPath = path;\r
-        }\r
-        \r
-        public void run() {\r
-            AccountManager am = AccountManager.get(getActivity());\r
-            Account account = AccountUtils.getCurrentOwnCloudAccount(getActivity());\r
-            OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(account, AccountAuthenticator.KEY_OC_VERSION));\r
-            String url = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + AccountUtils.getWebdavPath(ocv);\r
-\r
-            Log.d("share", "sharing for version " + ocv.toString());\r
-\r
-            if (ocv.compareTo(new OwnCloudVersion(0x040000)) >= 0) {\r
-                String APPS_PATH = "/apps/files_sharing/";\r
-                String SHARE_PATH = "ajax/share.php";\r
-\r
-                String SHARED_PATH = "/apps/files_sharing/get.php?token=";\r
-                \r
-                final String WEBDAV_SCRIPT = "webdav.php";\r
-                final String WEBDAV_FILES_LOCATION = "/files/";\r
-                \r
-                WebdavClient wc = new WebdavClient();\r
-                HttpConnectionManagerParams params = new HttpConnectionManagerParams();\r
-                params.setMaxConnectionsPerHost(wc.getHostConfiguration(), 5);\r
-\r
-                //wc.getParams().setParameter("http.protocol.single-cookie-header", true);\r
-                //wc.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);\r
-\r
-                PostMethod post = new PostMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + APPS_PATH + SHARE_PATH);\r
-\r
-                post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8" );\r
-                post.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));\r
-                List<NameValuePair> formparams = new ArrayList<NameValuePair>();\r
-                Log.d("share", mPath+"");\r
-                formparams.add(new BasicNameValuePair("sources",mPath));\r
-                formparams.add(new BasicNameValuePair("uid_shared_with", "public"));\r
-                formparams.add(new BasicNameValuePair("permissions", "0"));\r
-                post.setRequestEntity(new StringRequestEntity(URLEncodedUtils.format(formparams, HTTP.UTF_8)));\r
-\r
-                int status;\r
-                try {\r
-                    PropFindMethod find = new PropFindMethod(url+"/");\r
-                    find.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));\r
-                    Log.d("sharer", ""+ url+"/");\r
-                    wc.setCredentials(account.name.substring(0, account.name.lastIndexOf('@')), am.getPassword(account));\r
-                    \r
-                    for (org.apache.commons.httpclient.Header a : find.getRequestHeaders()) {\r
-                        Log.d("sharer-h", a.getName() + ":"+a.getValue());\r
-                    }\r
-                    \r
-                    int status2 = wc.executeMethod(find);\r
-\r
-                    Log.d("sharer", "propstatus "+status2);\r
-                    \r
-                    GetMethod get = new GetMethod(am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + "/");\r
-                    get.addRequestHeader("Referer", am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL));\r
-                    \r
-                    status2 = wc.executeMethod(get);\r
-\r
-                    Log.d("sharer", "getstatus "+status2);\r
-                    Log.d("sharer", "" + get.getResponseBodyAsString());\r
-                    \r
-                    for (org.apache.commons.httpclient.Header a : get.getResponseHeaders()) {\r
-                        Log.d("sharer", a.getName() + ":"+a.getValue());\r
-                    }\r
-\r
-                    status = wc.executeMethod(post);\r
-                    for (org.apache.commons.httpclient.Header a : post.getRequestHeaders()) {\r
-                        Log.d("sharer-h", a.getName() + ":"+a.getValue());\r
-                    }\r
-                    for (org.apache.commons.httpclient.Header a : post.getResponseHeaders()) {\r
-                        Log.d("sharer", a.getName() + ":"+a.getValue());\r
-                    }\r
-                    String resp = post.getResponseBodyAsString();\r
-                    Log.d("share", ""+post.getURI().toString());\r
-                    Log.d("share", "returned status " + status);\r
-                    Log.d("share", " " +resp);\r
-                    \r
-                    if(status != HttpStatus.SC_OK ||resp == null || resp.equals("") || resp.startsWith("false")) {\r
-                        return;\r
-                     }\r
-\r
-                    JSONObject jsonObject = new JSONObject (resp);\r
-                    String jsonStatus = jsonObject.getString("status");\r
-                    if(!jsonStatus.equals("success")) throw new Exception("Error while sharing file status != success");\r
-                    \r
-                    String token = jsonObject.getString("data");\r
-                    String uri = am.getUserData(account, AccountAuthenticator.KEY_OC_BASE_URL) + SHARED_PATH + token; \r
-                    Log.d("Actions:shareFile ok", "url: " + uri);   \r
-                    \r
-                } catch (HttpException e) {\r
-                    // TODO Auto-generated catch block\r
-                    e.printStackTrace();\r
-                } catch (IOException e) {\r
-                    // TODO Auto-generated catch block\r
-                    e.printStackTrace();\r
-                } catch (JSONException e) {\r
-                    // TODO Auto-generated catch block\r
-                    e.printStackTrace();\r
-                } catch (Exception e) {\r
-                    // TODO Auto-generated catch block\r
-                    e.printStackTrace();\r
-                }\r
-                \r
-            } else if (ocv.compareTo(new OwnCloudVersion(0x030000)) >= 0) {\r
-                \r
-            }\r
-        }\r
-    }\r
-    \r
-    public void onDismiss(EditNameFragment dialog) {\r
-        if (dialog instanceof EditNameFragment) {\r
-            if (((EditNameFragment)dialog).getResult()) {\r
-                String newFilename = ((EditNameFragment)dialog).getNewFilename();\r
-                Log.d(TAG, "name edit dialog dismissed with new name " + newFilename);\r
-                if (!newFilename.equals(mFile.getFileName())) {\r
-                    FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
-                    if (fdsm.getFileById(mFile.getFileId()) != null) {\r
-                        OCFile newFile = new OCFile(fdsm.getFileById(mFile.getParentId()).getRemotePath() + newFilename);\r
-                        newFile.setCreationTimestamp(mFile.getCreationTimestamp());\r
-                        newFile.setFileId(mFile.getFileId());\r
-                        newFile.setFileLength(mFile.getFileLength());\r
-                        newFile.setKeepInSync(mFile.keepInSync());\r
-                        newFile.setLastSyncDate(mFile.getLastSyncDate());\r
-                        newFile.setMimetype(mFile.getMimetype());\r
-                        newFile.setModificationTimestamp(mFile.getModificationTimestamp());\r
-                        newFile.setParentId(mFile.getParentId());\r
-                        boolean localRenameFails = false;\r
-                        if (mFile.isDown()) {\r
-                            File f = new File(mFile.getStoragePath());\r
-                            Log.e(TAG, f.getAbsolutePath());\r
-                            localRenameFails = !(f.renameTo(new File(f.getParent() + File.separator + newFilename)));\r
-                            Log.e(TAG, f.getParent() + File.separator + newFilename);\r
-                            newFile.setStoragePath(f.getParent() + File.separator + newFilename);\r
-                        }\r
-                        \r
-                        if (localRenameFails) {\r
-                            Toast msg = Toast.makeText(getActivity(), R.string.rename_local_fail_msg, Toast.LENGTH_LONG); \r
-                            msg.show();\r
-                            \r
-                        } else {\r
-                            new Thread(new RenameRunnable(mFile, newFile, mAccount, new Handler())).start();\r
-                            boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
-                            getActivity().showDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
-                        }\r
-\r
-                    }\r
-                }\r
-            }\r
-        } else {\r
-            Log.e(TAG, "Unknown dialog instance passed to onDismissDalog: " + dialog.getClass().getCanonicalName());\r
-        }\r
-        \r
-    }\r
-    \r
-    private class RenameRunnable implements Runnable {\r
-        \r
-        Account mAccount;\r
-        OCFile mOld, mNew;\r
-        Handler mHandler;\r
-        \r
-        public RenameRunnable(OCFile oldFile, OCFile newFile, Account account, Handler handler) {\r
-            mOld = oldFile;\r
-            mNew = newFile;\r
-            mAccount = account;\r
-            mHandler = handler;\r
-        }\r
-        \r
-        public void run() {\r
-            WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());\r
-            wc.allowSelfsignedCertificates();\r
-            AccountManager am = AccountManager.get(getSherlockActivity());\r
-            String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
-            OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
-            String webdav_path = AccountUtils.getWebdavPath(ocv);\r
-            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()));\r
-\r
-            Log.e("ASD", Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));\r
-            LocalMoveMethod move = new LocalMoveMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mOld.getRemotePath()),\r
-                                             Uri.parse(baseUrl).getPath() == null ? "" : Uri.parse(baseUrl).getPath() + webdav_path + WebdavUtils.encodePath(mNew.getRemotePath()));\r
-            \r
-            boolean success = false;\r
-            try {\r
-                int status = wc.executeMethod(move);\r
-                success = move.succeeded();\r
-                Log.d(TAG, "Move returned status: " + status);\r
-                \r
-            } catch (HttpException e) {\r
-                Log.e(TAG, "HTTP Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);\r
-                \r
-            } catch (IOException e) {\r
-                Log.e(TAG, "I/O Exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);\r
-                \r
-            } catch (Exception e) {\r
-                Log.e(TAG, "Unexpected exception renaming file " + mOld.getRemotePath() + " to " + mNew.getRemotePath(), e);\r
-            }\r
-            \r
-            if (success) {\r
-                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
-                fdsm.removeFile(mOld);\r
-                fdsm.saveFile(mNew);\r
-                mFile = mNew;\r
-                mHandler.post(new Runnable() {\r
-                    @Override\r
-                    public void run() { \r
-                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
-                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
-                        updateFileDetails(mFile, mAccount);\r
-                        mContainerActivity.onFileStateChanged();\r
-                    }\r
-                });\r
-                \r
-            } else {\r
-                mHandler.post(new Runnable() {\r
-                    @Override\r
-                    public void run() {\r
-                        // undo the local rename\r
-                        if (mNew.isDown()) {\r
-                            File f = new File(mNew.getStoragePath());\r
-                            if (!f.renameTo(new File(mOld.getStoragePath()))) {\r
-                                // the local rename undoing failed; last chance: save the new local storage path in the old file\r
-                                mFile.setStoragePath(mNew.getStoragePath());\r
-                                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
-                                fdsm.saveFile(mFile);\r
-                            }\r
-                        }\r
-                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
-                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
-                        try {\r
-                            Toast msg = Toast.makeText(getActivity(), R.string.rename_server_fail_msg, Toast.LENGTH_LONG); \r
-                            msg.show();\r
-                            \r
-                        } catch (NotFoundException e) {\r
-                            e.printStackTrace();\r
-                        }\r
-                    }\r
-                });\r
-            }\r
-        }\r
-        private class LocalMoveMethod extends DavMethodBase {\r
-\r
-            public LocalMoveMethod(String uri, String dest) {\r
-                super(uri);\r
-                addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest));\r
-            }\r
-\r
-            @Override\r
-            public String getName() {\r
-                return "MOVE";\r
-            }\r
-\r
-            @Override\r
-            protected boolean isSuccess(int status) {\r
-                return status == 201 || status == 204;\r
-            }\r
-            \r
-        }\r
-    }\r
-    \r
-    private static class EditNameFragment extends SherlockDialogFragment implements OnClickListener {\r
-\r
-        private String mNewFilename;\r
-        private boolean mResult;\r
-        private FileDetailFragment mListener;\r
-        \r
-        static public EditNameFragment newInstance(String filename) {\r
-            EditNameFragment f = new EditNameFragment();\r
-            Bundle args = new Bundle();\r
-            args.putString("filename", filename);\r
-            f.setArguments(args);\r
-            return f;\r
-        }\r
-        \r
-        @Override\r
-        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\r
-            View v = inflater.inflate(R.layout.edit_box_dialog, container, false);\r
-\r
-            String currentName = getArguments().getString("filename");\r
-            if (currentName == null)\r
-                currentName = "";\r
-            \r
-            ((Button)v.findViewById(R.id.cancel)).setOnClickListener(this);\r
-            ((Button)v.findViewById(R.id.ok)).setOnClickListener(this);\r
-            ((TextView)v.findViewById(R.id.user_input)).setText(currentName);\r
-            ((TextView)v.findViewById(R.id.user_input)).requestFocus();\r
-            getDialog().getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);\r
-\r
-            mResult = false;\r
-            return v;\r
-        }\r
-        \r
-        @Override\r
-        public void onClick(View view) {\r
-            switch (view.getId()) {\r
-                case R.id.ok: {\r
-                    mNewFilename = ((TextView)getView().findViewById(R.id.user_input)).getText().toString();\r
-                    mResult = true;\r
-                }\r
-                case R.id.cancel: { // fallthought\r
-                    dismiss();\r
-                    mListener.onDismiss(this);\r
-                }\r
-            }\r
-        }\r
-        \r
-        void setOnDismissListener(FileDetailFragment listener) {\r
-            mListener = listener;\r
-        }\r
-        \r
-        public String getNewFilename() {\r
-            return mNewFilename;\r
-        }\r
-        \r
-        // true if user click ok\r
-        public boolean getResult() {\r
-            return mResult;\r
-        }\r
-        \r
-    }\r
-    \r
-    private class RemoveRunnable implements Runnable {\r
-        \r
-        Account mAccount;\r
-        OCFile mFileToRemove;\r
-        Handler mHandler;\r
-        \r
-        public RemoveRunnable(OCFile fileToRemove, Account account, Handler handler) {\r
-            mFileToRemove = fileToRemove;\r
-            mAccount = account;\r
-            mHandler = handler;\r
-        }\r
-        \r
-        public void run() {\r
-            WebdavClient wc = new WebdavClient(mAccount, getSherlockActivity().getApplicationContext());\r
-            wc.allowSelfsignedCertificates();\r
-            AccountManager am = AccountManager.get(getSherlockActivity());\r
-            String baseUrl = am.getUserData(mAccount, AccountAuthenticator.KEY_OC_BASE_URL);\r
-            OwnCloudVersion ocv = new OwnCloudVersion(am.getUserData(mAccount, AccountAuthenticator.KEY_OC_VERSION));\r
-            String webdav_path = AccountUtils.getWebdavPath(ocv);\r
-            Log.d("ASD", ""+baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));\r
-\r
-            DeleteMethod delete = new DeleteMethod(baseUrl + webdav_path + WebdavUtils.encodePath(mFileToRemove.getRemotePath()));\r
-            \r
-            boolean success = false;\r
-            int status = -1;\r
-            try {\r
-                status = wc.executeMethod(delete);\r
-                success = (delete.succeeded());\r
-                Log.d(TAG, "Delete: returned status " + status);\r
-                \r
-            } catch (HttpException e) {\r
-                Log.e(TAG, "HTTP Exception removing file " + mFileToRemove.getRemotePath(), e);\r
-                \r
-            } catch (IOException e) {\r
-                Log.e(TAG, "I/O Exception removing file " + mFileToRemove.getRemotePath(), e);\r
-                \r
-            } catch (Exception e) {\r
-                Log.e(TAG, "Unexpected exception removing file " + mFileToRemove.getRemotePath(), e);\r
-            }\r
-            \r
-            if (success) {\r
-                FileDataStorageManager fdsm = new FileDataStorageManager(mAccount, getActivity().getContentResolver());\r
-                fdsm.removeFile(mFileToRemove);\r
-                mHandler.post(new Runnable() {\r
-                    @Override\r
-                    public void run() {\r
-                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
-                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
-                        try {\r
-                            Toast msg = Toast.makeText(getActivity().getApplicationContext(), R.string.remove_success_msg, Toast.LENGTH_LONG);\r
-                            msg.show();\r
-                            if (inDisplayActivity) {\r
-                                // double pane\r
-                                FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();\r
-                                transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment\r
-                                transaction.commit();\r
-                                mContainerActivity.onFileStateChanged();\r
-                                \r
-                            } else {\r
-                                getActivity().finish();\r
-                            }\r
-                            \r
-                        } catch (NotFoundException e) {\r
-                            e.printStackTrace();\r
-                        }\r
-                    }\r
-                });\r
-                \r
-            } else {\r
-                mHandler.post(new Runnable() {\r
-                    @Override\r
-                    public void run() {\r
-                        boolean inDisplayActivity = getActivity() instanceof FileDisplayActivity;\r
-                        getActivity().dismissDialog((inDisplayActivity)? FileDisplayActivity.DIALOG_SHORT_WAIT : FileDetailActivity.DIALOG_SHORT_WAIT);\r
-                        try {\r
-                            Toast msg = Toast.makeText(getActivity(), R.string.remove_fail_msg, Toast.LENGTH_LONG); \r
-                            msg.show();\r
-                            \r
-                        } catch (NotFoundException e) {\r
-                            e.printStackTrace();\r
-                        }\r
-                    }\r
-                });\r
-            }\r
-        }\r
-        \r
-    }\r
-    \r
-    class BitmapLoader extends AsyncTask<String, Void, Bitmap> {\r
-        @SuppressLint({ "NewApi", "NewApi", "NewApi" }) // to avoid Lint errors since Android SDK r20\r
-               @Override\r
-        protected Bitmap doInBackground(String... params) {\r
-            Bitmap result = null;\r
-            if (params.length != 1) return result;\r
-            String storagePath = params[0];\r
-            try {\r
-\r
-                BitmapFactory.Options options = new Options();\r
-                options.inScaled = true;\r
-                options.inPurgeable = true;\r
-                options.inJustDecodeBounds = true;\r
-                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {\r
-                    options.inPreferQualityOverSpeed = false;\r
-                }\r
-                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {\r
-                    options.inMutable = false;\r
-                }\r
-\r
-                result = BitmapFactory.decodeFile(storagePath, options);\r
-                options.inJustDecodeBounds = false;\r
-\r
-                int width = options.outWidth;\r
-                int height = options.outHeight;\r
-                int scale = 1;\r
-                if (width >= 2048 || height >= 2048) {\r
-                    scale = (int) Math.ceil((Math.ceil(Math.max(height, width) / 2048.)));\r
-                    options.inSampleSize = scale;\r
-                }\r
-                Display display = getActivity().getWindowManager().getDefaultDisplay();\r
-                Point size = new Point();\r
-                int screenwidth;\r
-                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) {\r
-                    display.getSize(size);\r
-                    screenwidth = size.x;\r
-                } else {\r
-                    screenwidth = display.getWidth();\r
-                }\r
-\r
-                Log.e("ASD", "W " + width + " SW " + screenwidth);\r
-\r
-                if (width > screenwidth) {\r
-                    scale = (int) Math.ceil((float)width / screenwidth);\r
-                    options.inSampleSize = scale;\r
-                }\r
-\r
-                result = BitmapFactory.decodeFile(storagePath, options);\r
-\r
-                Log.e("ASD", "W " + options.outWidth + " SW " + options.outHeight);\r
-\r
-            } catch (OutOfMemoryError e) {\r
-                result = null;\r
-                Log.e(TAG, "Out of memory occured for file with size " + storagePath);\r
-                \r
-            } catch (NoSuchFieldError e) {\r
-                result = null;\r
-                Log.e(TAG, "Error from access to unexisting field despite protection " + storagePath);\r
-                \r
-            } catch (Throwable t) {\r
-                result = null;\r
-                Log.e(TAG, "Unexpected error while creating image preview " + storagePath, t);\r
-            }\r
-            return result;\r
-        }\r
-        @Override\r
-        protected void onPostExecute(Bitmap result) {\r
-            if (result != null && mPreview != null) {\r
-                mPreview.setImageBitmap(result);\r
-            }\r
-        }\r
-        \r
-    }\r
-    \r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java b/src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java
deleted file mode 100644 (file)
index 66d0af8..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.fragment;\r
-\r
-import java.util.Vector;\r
-\r
-import android.app.Activity;\r
-import android.os.Bundle;\r
-import android.util.Log;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.ViewGroup;\r
-import android.widget.AdapterView;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.datamodel.DataStorageManager;\r
-import eu.alefzero.owncloud.datamodel.OCFile;\r
-import eu.alefzero.owncloud.ui.FragmentListView;\r
-import eu.alefzero.owncloud.ui.adapter.FileListListAdapter;\r
-\r
-/**\r
- * A Fragment that lists all files and folders in a given path.\r
- * \r
- * @author Bartek Przybylski\r
- * \r
- */\r
-public class FileListFragment extends FragmentListView {\r
-    private static final String TAG = "FileListFragment";\r
-    \r
-    private FileListFragment.ContainerActivity mContainerActivity;\r
-    \r
-    private OCFile mFile = null;\r
-    private FileListListAdapter mAdapter;\r
-\r
-    \r
-    /**\r
-     * {@inheritDoc}\r
-     */\r
-    @Override\r
-    public void onAttach(Activity activity) {\r
-        super.onAttach(activity);\r
-        try {\r
-            mContainerActivity = (ContainerActivity) activity;\r
-        } catch (ClassCastException e) {\r
-            throw new ClassCastException(activity.toString() + " must implement FileListFragment.ContainerActivity");\r
-        }\r
-    }\r
-    \r
-    \r
-    @Override\r
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
-            Bundle savedInstanceState) {\r
-        Log.i(getClass().toString(), "onCreateView() start");\r
-        super.onCreateView(inflater, container, savedInstanceState);\r
-        getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));\r
-        getListView().setDividerHeight(1);\r
-        \r
-        Log.i(getClass().toString(), "onCreateView() end");\r
-        return getListView();\r
-    }    \r
-\r
-\r
-    @Override\r
-    public void onActivityCreated(Bundle savedInstanceState) {\r
-        Log.i(getClass().toString(), "onActivityCreated() start");\r
-        \r
-        super.onCreate(savedInstanceState);\r
-        //mAdapter = new FileListListAdapter();\r
-        \r
-        Log.i(getClass().toString(), "onActivityCreated() stop");\r
-    }\r
-    \r
-    \r
-    @Override\r
-    public void onItemClick(AdapterView<?> l, View v, int position, long id) {\r
-        OCFile file = (OCFile) mAdapter.getItem(position);\r
-        if (file != null) {\r
-            /// Click on a directory\r
-            if (file.getMimetype().equals("DIR")) {\r
-                // just local updates\r
-                mFile = file;\r
-                listDirectory(file);\r
-                // any other updates are let to the container Activity\r
-                mContainerActivity.onDirectoryClick(file);\r
-            \r
-            } else {    /// Click on a file\r
-                mContainerActivity.onFileClick(file);\r
-            }\r
-            \r
-        } else {\r
-            Log.d(TAG, "Null object in ListAdapter!!");\r
-        }\r
-        \r
-    }\r
-\r
-    /**\r
-     * Call this, when the user presses the up button\r
-     */\r
-    public void onNavigateUp() {\r
-        OCFile parentDir = null;\r
-        \r
-        if(mFile != null){\r
-            DataStorageManager storageManager = mContainerActivity.getStorageManager();\r
-            parentDir = storageManager.getFileById(mFile.getParentId());\r
-            mFile = parentDir;\r
-        }\r
-        listDirectory(parentDir);\r
-    }\r
-\r
-    /**\r
-     * Use this to query the {@link OCFile} that is currently\r
-     * being displayed by this fragment\r
-     * @return The currently viewed OCFile\r
-     */\r
-    public OCFile getCurrentFile(){\r
-        return mFile;\r
-    }\r
-    \r
-    /**\r
-     * Calls {@link FileListFragment#listDirectory(OCFile)} with a null parameter\r
-     */\r
-    public void listDirectory(){\r
-        listDirectory(null);\r
-    }\r
-    \r
-    /**\r
-     * Lists the given directory on the view. When the input parameter is null,\r
-     * it will either refresh the last known directory, or list the root\r
-     * if there never was a directory.\r
-     * \r
-     * @param directory File to be listed\r
-     */\r
-    public void listDirectory(OCFile directory) {\r
-        \r
-        DataStorageManager storageManager = mContainerActivity.getStorageManager();\r
-\r
-        // Check input parameters for null\r
-        if(directory == null){\r
-            if(mFile != null){\r
-                directory = mFile;\r
-            } else {\r
-                directory = storageManager.getFileByPath("/");\r
-                if (directory == null) return; // no files, wait for sync\r
-            }\r
-        }\r
-        \r
-        \r
-        // If that's not a directory -> List its parent\r
-        if(!directory.isDirectory()){\r
-            Log.w(TAG, "You see, that is not a directory -> " + directory.toString());\r
-            directory = storageManager.getFileById(directory.getParentId());\r
-        }\r
-\r
-        mFile = directory;\r
-        \r
-        mAdapter = new FileListListAdapter(directory, storageManager, getActivity());\r
-        setListAdapter(mAdapter);\r
-    }\r
-    \r
-    \r
-    \r
-    /**\r
-     * Interface to implement by any Activity that includes some instance of FileListFragment\r
-     * \r
-     * @author David A. Velasco\r
-     */\r
-    public interface ContainerActivity {\r
-\r
-        /**\r
-         * Callback method invoked when a directory is clicked by the user on the files list\r
-         *  \r
-         * @param file\r
-         */\r
-        public void onDirectoryClick(OCFile file);\r
-        \r
-        /**\r
-         * Callback method invoked when a file (non directory) is clicked by the user on the files list\r
-         *  \r
-         * @param file\r
-         */\r
-        public void onFileClick(OCFile file);\r
-\r
-        /**\r
-         * Getter for the current DataStorageManager in the container activity\r
-         */\r
-        public DataStorageManager getStorageManager();\r
-        \r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java b/src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java
deleted file mode 100644 (file)
index f5649a0..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui.fragment;\r
-\r
-import com.actionbarsherlock.app.SherlockFragment;\r
-\r
-import android.os.Bundle;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.ViewGroup;\r
-import android.widget.ListView;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.ui.activity.LandingActivity;\r
-import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;\r
-\r
-/**\r
- * Used on the Landing page to display what Components of the ownCloud there\r
- * are. Like Files, Music, Contacts, etc.\r
- * \r
- * @author Lennart Rosam\r
- * \r
- */\r
-public class LandingPageFragment extends SherlockFragment {\r
-\r
-    @Override\r
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
-            Bundle savedInstanceState) {\r
-        View root = inflater.inflate(R.layout.landing_page_fragment, container);\r
-        return root;\r
-    }\r
-\r
-    @Override\r
-    public void onActivityCreated(Bundle savedInstanceState) {\r
-        super.onActivityCreated(savedInstanceState);\r
-\r
-        ListView landingScreenItems = (ListView) getView().findViewById(\r
-                R.id.homeScreenList);\r
-        landingScreenItems.setAdapter(new LandingScreenAdapter(getActivity()));\r
-        landingScreenItems\r
-                .setOnItemClickListener((LandingActivity) getActivity());\r
-    }\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java b/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java
deleted file mode 100644 (file)
index a772667..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 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 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 eu.alefzero.owncloud.utils;
-
-public class OwnCloudVersion implements Comparable<OwnCloudVersion> {
-    public static final OwnCloudVersion owncloud_v1 = new OwnCloudVersion(
-            0x010000);
-    public static final OwnCloudVersion owncloud_v2 = new OwnCloudVersion(
-            0x020000);
-    public static final OwnCloudVersion owncloud_v3 = new OwnCloudVersion(
-            0x030000);
-    public static final OwnCloudVersion owncloud_v4 = new OwnCloudVersion(
-            0x040000);
-
-    // format is in version
-    // 0xAABBCC
-    // for version AA.BB.CC
-    // ie version 3.0.3 will be stored as 0x030003
-    private int mVersion;
-    private boolean mIsValid;
-
-    public OwnCloudVersion(int version) {
-        mVersion = version;
-        mIsValid = true;
-    }
-
-    public OwnCloudVersion(String version) {
-        mVersion = 0;
-        mIsValid = false;
-        parseVersionString(version);
-    }
-
-    public String toString() {
-        return ((mVersion >> 16) % 256) + "." + ((mVersion >> 8) % 256) + "."
-                + ((mVersion) % 256);
-    }
-
-    public boolean isVersionValid() {
-        return mIsValid;
-    }
-
-    @Override
-    public int compareTo(OwnCloudVersion another) {
-        return another.mVersion == mVersion ? 0
-                : another.mVersion < mVersion ? 1 : -1;
-    }
-
-    private void parseVersionString(String version) {
-        try {
-            String[] nums = version.split("\\.");
-            if (nums.length > 0) {
-                mVersion += Integer.parseInt(nums[0]);
-            }
-            mVersion = mVersion << 8;
-            if (nums.length > 1) {
-                mVersion += Integer.parseInt(nums[1]);
-            }
-            mVersion = mVersion << 8;
-            if (nums.length > 2) {
-                mVersion += Integer.parseInt(nums[2]);
-            }
-            mIsValid = true;
-        } catch (Exception e) {
-            mIsValid = false;
-        }
-    }
-}
diff --git a/src/eu/alefzero/owncloud/widgets/ActionEditText.java b/src/eu/alefzero/owncloud/widgets/ActionEditText.java
deleted file mode 100644 (file)
index 4b11b6c..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-package eu.alefzero.owncloud.widgets;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import eu.alefzero.owncloud.R;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.EditText;
-
-public class ActionEditText extends EditText {
-    private String s;
-    private String optionOneString;
-    private int optionOneColor;
-    private String optionTwoString;
-    private int optionTwoColor;
-    private Rect mTextBounds, mButtonRect;
-
-    private String badgeClickCallback;
-    private Rect btn_rect;
-
-    public ActionEditText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        getAttrs(attrs);
-        s = optionOneString;
-        mTextBounds = new Rect();
-        mButtonRect = new Rect();
-    }
-
-    public ActionEditText(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        getAttrs(attrs);
-        s = optionOneString;
-        mTextBounds = new Rect();
-        mButtonRect = new Rect();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        Paint p = getPaint();
-
-        p.getTextBounds(s, 0, s.length(), mTextBounds);
-
-        getDrawingRect(mButtonRect);
-        mButtonRect.top += 10;
-        mButtonRect.bottom -= 10;
-        mButtonRect.left = (int) (getWidth() - mTextBounds.width() - 18);
-        mButtonRect.right = getWidth() - 10;
-        btn_rect = mButtonRect;
-
-        if (s.equals(optionOneString))
-            p.setColor(optionOneColor);
-        else
-            p.setColor(optionTwoColor);
-        canvas.drawRect(mButtonRect, p);
-        p.setColor(Color.GRAY);
-
-        canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom
-                - (mTextBounds.height() / 2), p);
-
-        invalidate();
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        int touchX = (int) event.getX();
-        int touchY = (int) event.getY();
-        boolean r = super.onTouchEvent(event);
-        if (event.getAction() == MotionEvent.ACTION_UP) {
-            if (btn_rect.contains(touchX, touchY)) {
-                if (s.equals(optionTwoString))
-                    s = optionOneString;
-                else
-                    s = optionTwoString;
-                if (badgeClickCallback != null) {
-                    @SuppressWarnings("rawtypes")
-                    Class[] paramtypes = new Class[2];
-                    paramtypes[0] = android.view.View.class;
-                    paramtypes[1] = String.class;
-                    Method method;
-                    try {
-
-                        method = getContext().getClass().getMethod(
-                                badgeClickCallback, paramtypes);
-                        method.invoke(getContext(), this, s);
-
-                    } catch (NoSuchMethodException e) {
-                        e.printStackTrace();
-                    } catch (IllegalArgumentException e) {
-                        e.printStackTrace();
-                    } catch (IllegalAccessException e) {
-                        e.printStackTrace();
-                    } catch (InvocationTargetException e) {
-                        e.printStackTrace();
-                    }
-
-                    invalidate();
-                }
-            }
-        }
-        return r;
-    }
-
-    private void getAttrs(AttributeSet attr) {
-        TypedArray a = getContext().obtainStyledAttributes(attr,
-                R.styleable.ActionEditText);
-        optionOneString = a
-                .getString(R.styleable.ActionEditText_optionOneString);
-        optionTwoString = a
-                .getString(R.styleable.ActionEditText_optionTwoString);
-        optionOneColor = a.getColor(R.styleable.ActionEditText_optionOneColor,
-                0x00ff00);
-        optionTwoColor = a.getColor(R.styleable.ActionEditText_optionTwoColor,
-                0xff0000);
-        badgeClickCallback = a
-                .getString(R.styleable.ActionEditText_onBadgeClick);
-    }
-
-}
index 3e7977c..61ba456 100644 (file)
@@ -8,9 +8,10 @@ import java.io.OutputStream;
 
 import org.apache.commons.httpclient.methods.RequestEntity;
 
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;
+
 import android.util.Log;
 
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;
 
 /**
  * A RequestEntity that represents a File.
index 1135daf..1e64bdf 100644 (file)
@@ -41,16 +41,17 @@ import org.apache.jackrabbit.webdav.client.methods.DavMethod;
 import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;\r
 import org.apache.jackrabbit.webdav.client.methods.MkColMethod;\r
 \r
+import com.owncloud.android.AccountUtils;\r
+import com.owncloud.android.authenticator.AccountAuthenticator;\r
+import com.owncloud.android.authenticator.EasySSLSocketFactory;\r
+import com.owncloud.android.files.interfaces.OnDatatransferProgressListener;\r
+import com.owncloud.android.utils.OwnCloudVersion;\r
+\r
 import android.accounts.Account;\r
 import android.accounts.AccountManager;\r
 import android.content.Context;\r
 import android.net.Uri;\r
 import android.util.Log;\r
-import eu.alefzero.owncloud.AccountUtils;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;\r
-import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;\r
-import eu.alefzero.owncloud.utils.OwnCloudVersion;\r
 \r
 public class WebdavClient extends HttpClient {\r
     private Uri mUri;\r