adjusting design to holo, stability for account setup
authorBartek Przybylski <bart.p.pl@gmail.com>
Sun, 13 May 2012 14:13:13 +0000 (16:13 +0200)
committerBartek Przybylski <bart.p.pl@gmail.com>
Sun, 13 May 2012 14:13:13 +0000 (16:13 +0200)
81 files changed:
AndroidManifest.xml
proguard.cfg
res/drawable-hdpi/ic_action_refresh.png [new file with mode: 0644]
res/drawable-hdpi/ic_action_refresh_black.png [new file with mode: 0644]
res/drawable-hdpi/ic_action_search.png [new file with mode: 0644]
res/drawable-hdpi/ic_action_upload.png [new file with mode: 0644]
res/drawable-ldpi/ic_action_refresh.png [new file with mode: 0644]
res/drawable-ldpi/ic_action_refresh_black.png [new file with mode: 0644]
res/drawable-ldpi/ic_action_search.png [new file with mode: 0644]
res/drawable-ldpi/ic_action_upload.png [new file with mode: 0644]
res/drawable-mdpi/ic_action_refresh.png [new file with mode: 0644]
res/drawable-mdpi/ic_action_refresh_black.png [new file with mode: 0644]
res/drawable-mdpi/ic_action_search.png [new file with mode: 0644]
res/drawable-mdpi/ic_action_upload.png [new file with mode: 0644]
res/drawable/common_error.png [new file with mode: 0644]
res/drawable/connection_secure.xml [new file with mode: 0644]
res/drawable/ic_ok.png [new file with mode: 0644]
res/drawable/icon_list_selector.xml [new file with mode: 0644]
res/drawable/list_selector.xml [new file with mode: 0644]
res/drawable/local_file_indicator.png [new file with mode: 0644]
res/drawable/logo_inverted.png [new file with mode: 0644]
res/drawable/main_header_bg.xml
res/drawable/no_network.png [new file with mode: 0644]
res/drawable/progress_small.xml [new file with mode: 0644]
res/drawable/spinner_inner.png [new file with mode: 0644]
res/drawable/uploader_list_separator.xml
res/layout-land/account_setup.xml [new file with mode: 0644]
res/layout-large-land/files.xml
res/layout/account_setup.xml
res/layout/authenticator_getting_started_fragment.xml [new file with mode: 0644]
res/layout/extensions_available_dialog.xml [new file with mode: 0644]
res/layout/file_activity_details.xml
res/layout/file_details_empty.xml
res/layout/file_details_fragment.xml
res/layout/file_display_action_list_element.xml
res/layout/files.xml
res/layout/landing_page_fragment.xml
res/layout/landing_page_item.xml
res/layout/list_layout.xml
res/layout/main.xml
res/layout/pick_account_layout.xml [new file with mode: 0644]
res/layout/selected_account_element.xml [new file with mode: 0644]
res/layout/uploader_layout.xml
res/layout/uploader_list_item_layout.xml
res/menu/account_picker.xml [new file with mode: 0644]
res/menu/menu.xml
res/values/colors.xml [new file with mode: 0644]
res/values/strings.xml
res/values/styles.xml
src/eu/alefzero/owncloud/AccountUtils.java
src/eu/alefzero/owncloud/FileDownloader.java
src/eu/alefzero/owncloud/Uploader.java
src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java
src/eu/alefzero/owncloud/authenticator/AuthenticationRunnable.java
src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java [new file with mode: 0644]
src/eu/alefzero/owncloud/authenticator/EasySSLSocketFactory.java
src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java [new file with mode: 0644]
src/eu/alefzero/owncloud/datamodel/FileDataStorageManager.java
src/eu/alefzero/owncloud/db/ProviderMeta.java
src/eu/alefzero/owncloud/extensions/ExtensionsAvailableActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/extensions/ExtensionsAvailableDialog.java [new file with mode: 0644]
src/eu/alefzero/owncloud/extensions/ExtensionsListActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
src/eu/alefzero/owncloud/ui/FragmentListView.java
src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
src/eu/alefzero/owncloud/ui/adapter/FileListActionListAdapter.java
src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java
src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/fragment/AuthenticatorGetStartedFragment.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/fragment/FileListFragment.java
src/eu/alefzero/owncloud/utils/OwnCloudVersion.java [new file with mode: 0644]
src/eu/alefzero/owncloud/widgets/ActionEditText.java
src/eu/alefzero/webdav/FileRequestEntity.java [new file with mode: 0644]
src/eu/alefzero/webdav/HttpMkCol.java [deleted file]
src/eu/alefzero/webdav/HttpPropFind.java [deleted file]
src/eu/alefzero/webdav/HttpPropPatch.java [deleted file]
src/eu/alefzero/webdav/WebdavClient.java
src/eu/alefzero/webdav/WebdavUtils.java

index ce11179..39d9085 100644 (file)
@@ -1,8 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>\r
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
-    package="eu.alefzero.owncloud"\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
+<manifest package="eu.alefzero.owncloud"\r
     android:versionCode="1"\r
-    android:versionName="1.0" >\r
+    android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">\r
 \r
     <uses-permission android:name="android.permission.GET_ACCOUNTS" />\r
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />\r
@@ -15,6 +31,7 @@
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />\r
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />\r
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />\r
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />\r
 \r
     <uses-sdk\r
         android:minSdkVersion="8"\r
 \r
     <application\r
         android:icon="@drawable/icon"\r
-        android:label="@string/app_name" >\r
+        android:label="@string/app_name"\r
+        android:theme="@style/Theme.ownCloud"\r
+        android:uiOptions="splitActionBarWhenNarrow"> \r
         <activity\r
             android:name=".ui.activity.FileDisplayActivity"\r
-            android:label="@string/app_name"\r
-            android:theme="@style/Theme.ownCloud" >\r
+            android:label="@string/app_name">\r
             <intent-filter>\r
                 <action android:name="android.intent.action.MAIN" />\r
 \r
@@ -69,7 +87,7 @@
 \r
         <service\r
             android:name=".authenticator.AccountAuthenticatorService"\r
-            android:exported="true" >\r
+            android:exported="true">\r
             <intent-filter>\r
                 <action android:name="android.accounts.AccountAuthenticator" />\r
             </intent-filter>\r
         <activity\r
             android:name=".ui.activity.AuthenticatorActivity"\r
             android:exported="true"\r
-            android:theme="@style/Theme.ownCloud" >\r
+            android:theme="@style/Theme.ownCloud.noActionBar" >\r
         </activity>\r
 \r
         <service android:name=".FileDownloader" >\r
         <activity\r
             android:name=".ui.activity.FileDetailActivity"\r
             android:theme="@style/Theme.ownCloud" >\r
-        </activity>\r
+        </activity>
+        <activity android:name=".extensions.ExtensionsAvailableActivity"></activity>
+        <activity android:name=".extensions.ExtensionsListActivity"></activity>\r
+        <activity android:name=".ui.activity.AccountSelectActivity" android:uiOptions="none" android:label="@string/prefs_accounts"></activity>\r
     </application>\r
 \r
 </manifest>
\ No newline at end of file
index 12dd039..3ad73fb 100644 (file)
     native <methods>;
 }
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet);
 }
 
--keepclasseswithmembernames class * {
+-keepclasseswithmembers class * {
     public <init>(android.content.Context, android.util.AttributeSet, int);
 }
 
diff --git a/res/drawable-hdpi/ic_action_refresh.png b/res/drawable-hdpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..804b8d4
Binary files /dev/null and b/res/drawable-hdpi/ic_action_refresh.png differ
diff --git a/res/drawable-hdpi/ic_action_refresh_black.png b/res/drawable-hdpi/ic_action_refresh_black.png
new file mode 100644 (file)
index 0000000..479aca4
Binary files /dev/null and b/res/drawable-hdpi/ic_action_refresh_black.png differ
diff --git a/res/drawable-hdpi/ic_action_search.png b/res/drawable-hdpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..720fc9b
Binary files /dev/null and b/res/drawable-hdpi/ic_action_search.png differ
diff --git a/res/drawable-hdpi/ic_action_upload.png b/res/drawable-hdpi/ic_action_upload.png
new file mode 100644 (file)
index 0000000..0faf43b
Binary files /dev/null and b/res/drawable-hdpi/ic_action_upload.png differ
diff --git a/res/drawable-ldpi/ic_action_refresh.png b/res/drawable-ldpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..a7fdc0d
Binary files /dev/null and b/res/drawable-ldpi/ic_action_refresh.png differ
diff --git a/res/drawable-ldpi/ic_action_refresh_black.png b/res/drawable-ldpi/ic_action_refresh_black.png
new file mode 100644 (file)
index 0000000..e6212cf
Binary files /dev/null and b/res/drawable-ldpi/ic_action_refresh_black.png differ
diff --git a/res/drawable-ldpi/ic_action_search.png b/res/drawable-ldpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..9fd8157
Binary files /dev/null and b/res/drawable-ldpi/ic_action_search.png differ
diff --git a/res/drawable-ldpi/ic_action_upload.png b/res/drawable-ldpi/ic_action_upload.png
new file mode 100644 (file)
index 0000000..2369348
Binary files /dev/null and b/res/drawable-ldpi/ic_action_upload.png differ
diff --git a/res/drawable-mdpi/ic_action_refresh.png b/res/drawable-mdpi/ic_action_refresh.png
new file mode 100644 (file)
index 0000000..bd611e8
Binary files /dev/null and b/res/drawable-mdpi/ic_action_refresh.png differ
diff --git a/res/drawable-mdpi/ic_action_refresh_black.png b/res/drawable-mdpi/ic_action_refresh_black.png
new file mode 100644 (file)
index 0000000..63e70e1
Binary files /dev/null and b/res/drawable-mdpi/ic_action_refresh_black.png differ
diff --git a/res/drawable-mdpi/ic_action_search.png b/res/drawable-mdpi/ic_action_search.png
new file mode 100644 (file)
index 0000000..90cf335
Binary files /dev/null and b/res/drawable-mdpi/ic_action_search.png differ
diff --git a/res/drawable-mdpi/ic_action_upload.png b/res/drawable-mdpi/ic_action_upload.png
new file mode 100644 (file)
index 0000000..2d4ba56
Binary files /dev/null and b/res/drawable-mdpi/ic_action_upload.png differ
diff --git a/res/drawable/common_error.png b/res/drawable/common_error.png
new file mode 100644 (file)
index 0000000..f1a804a
Binary files /dev/null and b/res/drawable/common_error.png differ
diff --git a/res/drawable/connection_secure.xml b/res/drawable/connection_secure.xml
new file mode 100644 (file)
index 0000000..b988c29
--- /dev/null
@@ -0,0 +1,13 @@
+<!--?xml version="1.0" encoding="utf-8"? -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+       <gradient android:endColor="#8dc73f" android:centerColor="#d4d4d4"
+               android:startColor="#d4d4d4">
+               <stroke android:width="1dp" color="#8dc73f">
+                       <corners android:radius="5dp">
+                               <padding android:left="7dp" android:top="7dp" android:right="7dp"
+                                       android:bottom="7dp">
+                               </padding>
+                       </corners>
+               </stroke>
+       </gradient>
+</shape>
diff --git a/res/drawable/ic_ok.png b/res/drawable/ic_ok.png
new file mode 100644 (file)
index 0000000..b28b3b5
Binary files /dev/null and b/res/drawable/ic_ok.png differ
diff --git a/res/drawable/icon_list_selector.xml b/res/drawable/icon_list_selector.xml
new file mode 100644 (file)
index 0000000..d9f8d68
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2010 The Android Open Source Project
+
+     Licensed 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:drawable="@color/filelist_backgorund" android:state_window_focused="false"/>
+
+    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="false" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true"/>
+
+</selector>
\ No newline at end of file
diff --git a/res/drawable/list_selector.xml b/res/drawable/list_selector.xml
new file mode 100644 (file)
index 0000000..d9f8d68
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2010 The Android Open Source Project
+
+     Licensed 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="@android:integer/config_mediumAnimTime">
+
+    <item android:drawable="@color/filelist_backgorund" android:state_window_focused="false"/>
+
+    <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. -->
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_enabled="false" android:state_focused="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="false" android:state_pressed="true"/>
+    <item android:drawable="@android:color/holo_blue_bright" android:state_focused="true"/>
+
+</selector>
\ No newline at end of file
diff --git a/res/drawable/local_file_indicator.png b/res/drawable/local_file_indicator.png
new file mode 100644 (file)
index 0000000..08a7b80
Binary files /dev/null and b/res/drawable/local_file_indicator.png differ
diff --git a/res/drawable/logo_inverted.png b/res/drawable/logo_inverted.png
new file mode 100644 (file)
index 0000000..d9fd119
Binary files /dev/null and b/res/drawable/logo_inverted.png differ
index 6549d0d..ba66621 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient 
-        android:startColor="#1D2D55" 
+    <gradient
+        android:startColor="#1D2D44"
+        android:centerColor="#1D2D55" 
         android:endColor="#1D2D44"
         android:angle="270"
      />
diff --git a/res/drawable/no_network.png b/res/drawable/no_network.png
new file mode 100644 (file)
index 0000000..1ff50ea
Binary files /dev/null and b/res/drawable/no_network.png differ
diff --git a/res/drawable/progress_small.xml b/res/drawable/progress_small.xml
new file mode 100644 (file)
index 0000000..7081727
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/spinner_inner"
+    android:pivotX="50%"
+    android:pivotY="50%" 
+    android:fromDegrees="0"
+    android:toDegrees="360"
+    android:interpolator="@android:anim/linear_interpolator"
+    android:duration="1000"
+    android:startOffset="0"/>
diff --git a/res/drawable/spinner_inner.png b/res/drawable/spinner_inner.png
new file mode 100644 (file)
index 0000000..4569fae
Binary files /dev/null and b/res/drawable/spinner_inner.png differ
index 25b9449..dfad4f1 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <shape
   xmlns:android="http://schemas.android.com/apk/res/android">
-    <gradient android:startColor="#fefefe" android:centerColor="#cccccc" android:endColor="#fefefe" android:angle="0"/>
+    <gradient android:startColor="@color/filelist_icon_backgorund" android:endColor="@color/filelist_icon_backgorund" android:angle="0"/>
 </shape>
\ No newline at end of file
diff --git a/res/layout-land/account_setup.xml b/res/layout-land/account_setup.xml
new file mode 100644 (file)
index 0000000..cdd3172
--- /dev/null
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:focusable="true"
+    android:gravity="center|fill"
+    android:orientation="vertical" >
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="16dip"
+        android:layout_weight="1" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" >
+
+            <ImageView
+                android:id="@+id/imageView1"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_margin="7dp"
+                android:layout_weight="1"
+                android:src="@drawable/logo_inverted" />
+
+            <LinearLayout
+                android:id="@+id/LinearLayout1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_weight="1"
+                android:orientation="vertical" >
+
+                <FrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1" >
+
+                    <EditText
+                        android:id="@+id/host_URL"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:ems="10"
+                        android:hint="@string/auth_host_url"
+                        android:singleLine="true" >
+
+                        <requestFocus />
+                    </EditText>
+
+                    <ImageView
+                        android:id="@+id/refreshButton"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="right|center_vertical"
+                        android:src="@drawable/ic_action_refresh_black"
+                        android:visibility="invisible" />
+                </FrameLayout>
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="50dp"
+                    android:layout_weight="1" >
+
+                    <ImageView
+                        android:id="@+id/action_indicator"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_marginLeft="5dp"
+                        android:layout_marginRight="5dp"
+                        android:src="@android:drawable/stat_notify_sync"
+                        android:visibility="invisible" />
+
+                    <TextView
+                        android:id="@+id/status_text"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="TextView"
+                        android:visibility="invisible" />
+                </LinearLayout>
+
+                <TextView
+                    android:id="@+id/textView2"
+                    android:layout_width="wrap_content"
+                    android:layout_height="0dp"
+                    android:layout_weight="1"
+                    android:text="@string/auth_login_details"
+                    android:textAppearance="?android:attr/textAppearanceSmall" />
+
+                <EditText
+                    android:id="@+id/account_username"
+                    android:layout_width="match_parent"
+                    android:layout_height="0dp"
+                    android:layout_weight="1"
+                    android:ems="10"
+                    android:hint="@string/auth_username"
+                    android:singleLine="true" />
+
+                <FrameLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1" >
+
+                    <EditText
+                        android:id="@+id/account_password"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:layout_weight="1"
+                        android:ems="10"
+                        android:hint="@string/auth_password"
+                        android:inputType="textPassword"
+                        android:singleLine="true" />
+
+                    <ImageView
+                        android:id="@+id/viewPassword"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_gravity="right|center_vertical"
+                        android:src="@android:drawable/ic_menu_view"
+                        android:visibility="invisible" />
+                </FrameLayout>
+            </LinearLayout>
+        </LinearLayout>
+    </FrameLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:weightSum="1" >
+
+            <Button
+                android:id="@+id/buttonCancel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:text="@string/common_cancel" />
+
+            <Button
+                android:id="@+id/buttonOK"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:enabled="false"
+                android:onClick="onOkClick"
+                android:text="@string/setup_btn_connect"
+                android:textColor="@android:color/black" />
+        </LinearLayout>
+    </RelativeLayout>
+
+</LinearLayout>
\ No newline at end of file
index c43feb9..d0ccfe8 100644 (file)
@@ -1,32 +1,40 @@
 <?xml version="1.0" encoding="utf-8"?>\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2011  Bartek Przybylski\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
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
     android:layout_width="fill_parent"\r
     android:layout_height="fill_parent"\r
-    android:background="#F7F7F7"\r
-    android:orientation="vertical" >\r
+    android:orientation="horizontal" >\r
 \r
     <LinearLayout\r
-        android:id="@+id/linearLayout1"\r
-        android:layout_width="fill_parent"\r
-        android:layout_height="fill_parent"\r
-        android:orientation="horizontal" >\r
-\r
-        <LinearLayout\r
-            android:id="@+id/file_list_container"\r
-            android:layout_width="0dp"\r
-            android:layout_height="wrap_content" \r
-            android:layout_weight="1">\r
-        </LinearLayout>\r
-\r
-        <fragment\r
-            android:id="@+id/fileDetail"\r
-            android:layout_width="0dp"\r
-            android:layout_height="fill_parent"\r
-            android:layout_weight="2"\r
-            class="eu.alefzero.owncloud.ui.fragment.FileDetail" >\r
-\r
-            <!-- Preview: layout=@layout/file_details -->\r
-        </fragment>\r
+        android:id="@+id/file_list_container"\r
+        android:layout_width="0dp"\r
+        android:layout_height="wrap_content"\r
+        android:layout_weight="1" >\r
     </LinearLayout>\r
 \r
+    <fragment\r
+        android:id="@+id/fileDetail"\r
+        android:layout_width="0dp"\r
+        android:layout_height="fill_parent"\r
+        android:layout_weight="2"\r
+        class="eu.alefzero.owncloud.ui.fragment.FileDetail" >\r
+        <!-- Preview: layout=@layout/file_details -->\r
+    </fragment>\r
+\r
 </LinearLayout>
\ No newline at end of file
index 90c02f8..1a9e281 100644 (file)
-<?xml version="1.0" encoding="utf-8"?>\r
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
-    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"\r
-    android:layout_width="fill_parent"\r
-    android:layout_height="fill_parent"\r
-    android:background="#F7F7F7"\r
-    android:focusable="true"\r
-    android:orientation="vertical" >\r
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ownCloud Android client application\r
 \r
-    <LinearLayout\r
-        android:id="@+id/linearLayout7"\r
-        android:layout_width="fill_parent"\r
-        android:layout_height="wrap_content"\r
-        android:layout_gravity="top"\r
-        android:background="#1D2D44"\r
-        android:gravity="center_vertical|top"\r
-        android:orientation="vertical"\r
-        android:paddingBottom="2pt"\r
-        android:paddingTop="2pt" >\r
+  Copyright (C) 2012  Bartek Przybylski\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
-        <ImageView\r
-            android:id="@+id/main_header_small"\r
-            android:layout_width="wrap_content"\r
-            android:layout_height="wrap_content"\r
-            android:layout_gravity="center|center_vertical|center_horizontal"\r
-            android:focusable="true"\r
-            android:src="@drawable/owncloud_logo_small_white" >\r
-        </ImageView>\r
-    </LinearLayout>\r
-\r
-    <LinearLayout\r
-        android:id="@+id/linearLayout2"\r
-        android:layout_width="fill_parent"\r
-        android:layout_height="fill_parent"\r
-        android:layout_gravity="center|center_vertical"\r
-        android:gravity="center_vertical"\r
-        android:orientation="vertical" >\r
-\r
-        <TableLayout\r
-            android:id="@+id/tableLayout1"\r
-            android:layout_width="fill_parent"\r
-            android:layout_height="wrap_content"\r
-            android:gravity="center_horizontal" >\r
-\r
-            <TableRow\r
-                android:id="@+id/tableRow1"\r
-                android:layout_width="wrap_content"\r
-                android:layout_height="wrap_content"\r
-                android:gravity="center_horizontal" >\r
-\r
-                <TextView\r
-                    android:id="@+id/textView1"\r
-                    android:layout_width="wrap_content"\r
-                    android:layout_height="wrap_content"\r
-                    android:layout_marginBottom="15dip"\r
-                    android:layout_marginTop="15dip"\r
-                    android:text="@string/setup_title"\r
-                    android:textColor="@android:color/black"\r
-                    android:textSize="7pt"\r
-                    android:textStyle="bold" >\r
-                </TextView>\r
-            </TableRow>\r
-\r
-            <TableRow\r
-                android:id="@+id/tableRow2"\r
-                android:layout_width="wrap_content"\r
-                android:layout_height="wrap_content"\r
-                android:gravity="center_horizontal"\r
-                android:weightSum="1.0" >\r
-\r\r\r
-                <eu.alefzero.owncloud.widgets.ActionEditText\r
-                    android:id="@+id/host_URL"\r
-                    android:layout_width="fill_parent"\r
-                    android:layout_height="wrap_content"\r
-                    android:layout_weight="0.75"\r
-                    android:hint="@string/setup_hint_address"\r
-                    android:inputType="textUri"\r
-                    android:textColor="@android:color/black"\r
-                    android:singleLine="true"\r
-                    oc:optionOneString="SSL"\r
-                    oc:optionTwoString="NO SSL"\r
-                    oc:optionOneColor="#00ff00"\r
-                    oc:optionTwoColor="#ff0000"\r
-                    oc:onBadgeClick="sslBadgeClick">\r
-\r
-                    <requestFocus>\r
-                    </requestFocus>\r
-                </eu.alefzero.owncloud.widgets.ActionEditText>\r
-            </TableRow>\r
-\r
-            <TableRow\r
-                android:id="@+id/tableRow3"\r
-                android:layout_width="wrap_content"\r
-                android:layout_height="wrap_content"\r
-                android:gravity="center_horizontal"\r
-                android:weightSum="1.0" >\r
-\r\r
-                <EditText\r
-                    android:id="@+id/account_username"\r
-                    android:layout_width="fill_parent"\r
-                    android:layout_height="wrap_content"\r
-                    android:layout_weight=".75"\r
-                    android:hint="@string/setup_hint_username"\r
-                    android:singleLine="true"\r
-                    android:textColor="@android:color/black" >\r
-\r
-                </EditText>\r
-            </TableRow>\r
-\r
-            <TableRow\r
-                android:id="@+id/tableRow4"\r
-                android:layout_width="fill_parent"\r
-                android:layout_height="wrap_content"\r
-                android:gravity="center_horizontal"\r
-                android:weightSum="1.0" >\r
-\r\r
-                <eu.alefzero.owncloud.widgets.ActionEditText\r
-                    android:id="@+id/account_password"\r
-                    android:layout_width="fill_parent"\r
-                    android:layout_height="wrap_content"\r
-                    android:layout_weight=".75"\r
-                    android:hint="@string/setup_hint_password"\r
-                    android:inputType="textPassword"\r
-                    android:singleLine="true"\r
-                    android:textColor="@android:color/black" \r
-                    oc:optionOneString="Show"\r
-                    oc:optionTwoString="Hide"\r
-                    oc:optionOneColor="#00ff00"\r
-                    oc:optionTwoColor="#ff0000"\r
-                    oc:onBadgeClick="passwordBadgeClick">\r
-\r
-                </eu.alefzero.owncloud.widgets.ActionEditText>\r
-            </TableRow>\r
-        </TableLayout>\r
-\r
-        <LinearLayout\r
-            android:id="@+id/linearLayout1"\r
-            android:layout_width="fill_parent"\r
-            android:layout_height="wrap_content"\r
-            android:gravity="center_horizontal"\r
-            android:orientation="vertical"\r
-            android:weightSum="1.0" >\r
-\r
-            <Button\r
-                android:id="@+id/buttonOK"\r
-                android:layout_width="fill_parent"\r
-                android:layout_height="wrap_content"\r
-                android:layout_weight=".75"\r
-                android:onClick="onOkClick"\r
-                android:textColor="@android:color/black"\r
-                android:text="@string/setup_btn_connect" >\r
-            </Button>\r
-<!-- \r
-            <Button\r
-                android:id="@+id/buttonNotUser"\r
-                android:layout_width="fill_parent"\r
-                android:layout_height="wrap_content"\r
-                android:layout_weight=".75"\r
-                android:onClick="onNotUserClick"\r
-                android:textColor="@android:color/black"\r
-                android:text="Get started!" >\r
-            </Button>\r
--->       \r
-        </LinearLayout>\r
-    </LinearLayout>\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
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:oc="http://schemas.android.com/apk/res/eu.alefzero.owncloud"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:focusable="true"
+    android:gravity="center|fill"
+    android:orientation="vertical" >
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="16dip"
+        android:layout_weight="1" >
+
+        <LinearLayout
+            android:id="@+id/LinearLayout1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_weight="1"
+            android:orientation="vertical" >
+
+            <ImageView
+                android:id="@+id/imageView1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="10dp"
+                android:layout_weight="1"
+                android:src="@drawable/logo_inverted" />
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" >
+
+                <EditText
+                    android:id="@+id/host_URL"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:ems="10"
+                    android:hint="@string/auth_host_url"
+                    android:singleLine="true" >
+
+                    <requestFocus />
+                </EditText>
+
+                <ImageView
+                    android:id="@+id/refreshButton"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/ic_action_refresh_black"
+                    android:layout_gravity="right|center_vertical"
+                    android:visibility="invisible" />
+
+            </FrameLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="50dp"
+                android:layout_weight="1" >
+
+                <ImageView
+                    android:id="@+id/action_indicator"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginLeft="5dp"
+                    android:layout_marginRight="5dp"
+                    android:src="@android:drawable/stat_notify_sync"
+                    android:visibility="invisible" />
+
+                <TextView
+                    android:id="@+id/status_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="TextView"
+                    android:visibility="invisible" />
+
+            </LinearLayout>
+
+            <TextView
+                android:id="@+id/textView2"
+                android:layout_width="wrap_content"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:text="@string/auth_login_details"
+                android:textAppearance="?android:attr/textAppearanceSmall" />
+
+            <EditText
+                android:id="@+id/account_username"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:ems="10"
+                android:singleLine="true"
+                android:hint="@string/auth_username" />
+
+            <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" >
+
+                <EditText
+                    android:id="@+id/account_password"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:ems="10"
+                    android:hint="@string/auth_password"
+                    android:inputType="textPassword"
+                    android:singleLine="true" />
+
+                <ImageView
+                    android:id="@+id/viewPassword"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="right|center_vertical"
+                    android:src="@android:drawable/ic_menu_view"
+                    android:visibility="invisible" />
+
+            </FrameLayout>
+
+        </LinearLayout>
+
+    </FrameLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:weightSum="1" >
+
+            <Button
+                android:id="@+id/buttonCancel"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:text="@string/common_cancel" />
+
+            <Button
+                android:id="@+id/buttonOK"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_weight=".5"
+                android:enabled="false"
+                android:onClick="onOkClick"
+                android:text="@string/setup_btn_connect"
+                android:textColor="@android:color/black" />
+
+        </LinearLayout>
+    </RelativeLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/authenticator_getting_started_fragment.xml b/res/layout/authenticator_getting_started_fragment.xml
new file mode 100644 (file)
index 0000000..52ee339
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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/>.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#F7F7F7"
+    android:focusable="true"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="Large Text"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/extensions_available_dialog.xml b/res/layout/extensions_available_dialog.xml
new file mode 100644 (file)
index 0000000..e487eb4
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/extensions_avail"
+    android:layout_width="wrap_content" android:layout_height="wrap_content"
+    android:layout_gravity="center" android:orientation="vertical"  >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_margin="7dp"
+        android:text="@string/extensions_avail_message" />
+
+    <LinearLayout
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_margin="5dp"
+        android:weightSum="1.0" >
+
+        <Button
+            android:id="@+id/buttonNo"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/common_no"
+            android:layout_weight="0.5"/>
+
+        <Button
+            android:id="@+id/buttonYes"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/common_yes"
+            android:layout_weight="0.5"/>
+
+    </LinearLayout>
+    
+</LinearLayout>
\ No newline at end of file
index 304b97f..664d756 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
     android:layout_width="fill_parent"\r
     android:layout_height="fill_parent"\r
index 1cd82fc..d08d728 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
index e02ed7c..f4cd33f 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
index 1d0b084..36ceb5f 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center_horizontal" android:gravity="center_horizontal">
        <ImageView android:layout_width="wrap_content"
index 9cbd3bb..e1be03b 100644 (file)
@@ -1,14 +1,33 @@
 <?xml version="1.0" encoding="utf-8"?>\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
     android:layout_width="fill_parent"\r
     android:layout_height="fill_parent"\r
-    android:background="#F7F7F7"\r
-        android:orientation="vertical" >\r
-       <fragment\r
-                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
-                <!-- Preview: layout=@layout/list_layout -->\r
-            </fragment>\r
+    android:orientation="vertical" >\r
+\r
+    <fragment\r
+        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
+\r
+        <!-- Preview: layout=@layout/list_layout -->\r
+    </fragment>\r
+\r
 </LinearLayout>
\ No newline at end of file
index 01eaeaa..95413c0 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
     android:id="@+id/linearLayout1"\r
     android:layout_width="fill_parent"\r
index a15412c..7ef8930 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
     android:layout_width="fill_parent"\r
     android:layout_height="fill_parent" >\r
index 60f6689..5f2a43f 100644 (file)
@@ -1,17 +1,72 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  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/>.
+ -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-       android:orientation="horizontal"
-       android:id="@+id/ListItemLayout" android:layout_width="fill_parent"
-       android:background="#F7F7F7" android:layout_height="wrap_content">
-       <ImageView android:layout_width="wrap_content" android:src="@drawable/ic_menu_archive"
-               android:id="@+id/imageView1" android:layout_height="wrap_content"
-               android:layout_marginLeft="15dip" android:focusable="false"
-               android:focusableInTouchMode="false"></ImageView>
-       <TextView android:layout_height="wrap_content"
-               android:textColor="#303030" android:layout_width="wrap_content"
-               android:text="TextView" android:layout_marginLeft="5dip"
-               android:layout_marginBottom="5dip" android:layout_marginRight="30dip"
-               android:id="@+id/Filename" android:focusable="false"
-    android:focusableInTouchMode="false" android:textSize="20dip">
-       </TextView>
+    android:id="@+id/ListItemLayout"
+    android:layout_width="fill_parent"
+    android:background="@drawable/list_selector"
+    android:orientation="horizontal"
+    android:layout_height="56dp">
+
+    <FrameLayout
+        android:layout_width="56dp"
+        android:layout_height="56dp"
+        android:focusable="false"
+        android:focusableInTouchMode="false">
+        
+        <ImageView
+            android:id="@+id/imageView2"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:src="@drawable/local_file_indicator"/>
+
+        <ImageView
+            android:id="@+id/imageView1"
+            android:layout_width="wrap_content"
+            android:layout_height="48dp"
+            android:layout_gravity="center_vertical"
+            android:layout_margin="4dp"
+            android:src="@drawable/ic_menu_archive" />
+        
+    </FrameLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent" >
+
+        <TextView
+            android:id="@+id/Filename"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginLeft="4dp"
+            android:text="TextView"
+            android:textColor="#303030"
+            android:textSize="20dip" />
+
+        <TextView
+            android:id="@+id/Extension"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:text="TextView"
+            android:textColor="#D0D0D0"
+            android:textSize="20dip" />
+    </LinearLayout>
+
 </LinearLayout>
index 33eb75a..0697bd1 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>\r
+<!-- \r
+  ownCloud Android client application\r
+\r
+  Copyright (C) 2012  Bartek Przybylski\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
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
     android:layout_width="fill_parent"\r
     android:layout_height="fill_parent"\r
diff --git a/res/layout/pick_account_layout.xml b/res/layout/pick_account_layout.xml
new file mode 100644 (file)
index 0000000..df3ece9
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="TextView" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/selected_account_element.xml b/res/layout/selected_account_element.xml
new file mode 100644 (file)
index 0000000..fe3146e
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="TextView" />
+
+</LinearLayout>
\ No newline at end of file
index b3e6565..1d22041 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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/>.
+ -->
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="wrap_content" android:orientation="vertical"
        android:layout_width="wrap_content" android:background="#fefefe"
index d546814..12ac1ed 100644 (file)
@@ -1,4 +1,21 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 
+  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/>.
+ -->
 <LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
diff --git a/res/menu/account_picker.xml b/res/menu/account_picker.xml
new file mode 100644 (file)
index 0000000..1001cd1
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+    <item android:id="@+id/createAccount" android:title="Create Account" android:showAsAction="ifRoom|withText"></item>
+    
+
+</menu>
\ No newline at end of file
index df201e7..f6a7db9 100644 (file)
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <menu
   xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem"></item>
-    <item android:id="@+id/createDirectoryItem" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add"></item>
-    <item android:id="@+id/startSync" android:title="Sync account"></item>
+    <item android:id="@+id/startSync" android:title="Sync account" android:showAsAction="ifRoom" android:icon="@drawable/ic_action_refresh"></item><item android:title="Settings" android:icon="@android:drawable/ic_menu_preferences" android:id="@+id/settingsItem" android:showAsAction="never"></item>
+    <item android:id="@+id/createDirectoryItem" android:title="Create Directory" android:icon="@android:drawable/ic_menu_add" android:showAsAction="ifRoom"></item>
+    
+    <item android:id="@+id/search" android:icon="@drawable/ic_action_search" android:showAsAction="ifRoom"></item>
+    <item android:id="@+id/action_upload" android:icon="@drawable/ic_action_upload" android:showAsAction="ifRoom"></item>
 </menu>
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644 (file)
index 0000000..521105b
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="filelist_icon_backgorund">#DDDDDD</color>
+    <color name="filelist_backgorund">#F7F7F7</color>
+    
+</resources>
\ No newline at end of file
index 8233e3b..a75f227 100644 (file)
@@ -17,7 +17,6 @@
     
     <string name="prefs_category_general">General</string>
     <string name="prefs_category_trackmydevice">Device tracking</string>
-    <string name="prefs_sessions">Stored sessions</string>
     <string name="prefs_add_session">Add new session</string>
     <string name="prefs_create_img_thumbnails">Create image thumbnails</string>
     <string name="prefs_select_oc_account">Select an account</string>
     <string name="prefs_trackmydevice_summary_on">Your ownCloud keeps track of this device</string>
     <string name="prefs_trackmydevice_interval">Update intervall</string>
     <string name="prefs_trackmydevice_interval_summary">Update every %1$s minutes</string>
+    <string name="prefs_accounts">Accounts</string>
     
-    <string name="new_session_id">Session Name</string>
-    <string name="new_session_url">URL</string>
-    <string name="new_session_username">Username</string>
-    <string name="new_session_password">Password</string>
-    <string name="new_session_save">OK</string>
-    <string name="new_session_cancel">Cancel</string>
+    <string name="auth_host_url">ownCloud location</string>
+    <string name="auth_username">Username</string>
+    <string name="auth_password">Password</string>
     <string name="new_session_uri_error">Wrong URL given</string>
     <string name="new_session_session_name_error">Wrong session name</string>
     <string name="sync_string_files">Files</string>
@@ -52,6 +49,8 @@
     <string name="uploader_info_uploading">Uploading</string>
     <string name="uploader_btn_create_dir_text">Create dir for upload</string>
     <string name="filedetails_select_file">Tap on a file to display additional information.</string>
+    <string name="common_yes">Yes</string>
+    <string name="common_no">No</string>
     <string name="common_ok">OK</string>
     <string name="common_cancel">Cancel</string>
     <string name="uploader_info_dirname">Directory name</string>
        <item>30</item>
        <item>60</item>
        </string-array>
-    <string name="auth_trying_to_login">Trying to login</string>
-    <string name="auth_no_ssl">No SSL</string>
+    <string name="auth_trying_to_login">Trying to login…</string>
+    <string name="auth_no_net_conn_title">No network connection</string>
+    <string name="auth_no_net_conn_message">No network connection have been detected, check your Internet connection and try again.</string>
+    <string name="auth_connect_anyway">Connect anyway</string>
+    <string name="auth_nossl_plain_ok_title">Secure connection unavailable.</string>
+    <string name="auth_nossl_plain_ok_message">Application couldn\'t etablish secure connection to server. Although non secure connection is available. You may continue or cancel.</string>
+    <string name="auth_connection_established">Connection established</string>
+    <string name="auth_testing_connection">Testing connection…</string>
+    <string name="auth_not_configured_title">Malformed ownCloud configuration</string>
+    <string name="auth_not_configured_message">It seems that your ownCloud intance is not correctly configured. Contact your administrator for more details.</string>
+    <string name="auth_unknown_error_title">Unknown error occurred</string>
+    <string name="auth_unknown_error_message">Unknown error occurred. Please contact authors and include logs from your device.</string>
+    <string name="auth_unknow_host_title">Can\'t establish connection</string>
+    <string name="auth_unknow_host_message">Coundn\'t establish connection to host. Please check hostname and server availability and try again.</string>
+    <string name="auth_incorrect_path_title">ownCloud intance not found</string>
+    <string name="auth_incorrect_path_message">Application couldn\'t find ownClound instance at given path. Please check your path and try again.</string>
+    <string name="auth_secure_connection">Secure connection established</string>
+    <string name="auth_unknow_error">Unknown error occured!</string>
+    <string name="auth_login_details">Login details</string>
+    
+    <string name="extensions_avail_title">Extensions available!</string>
+    <string name="extensions_avail_message">Looks like your ownCloud instance is supporting advanced extensions. Would you like to see extensions available for android ?</string>
 </resources>
index 83ec437..a09945e 100644 (file)
@@ -7,6 +7,12 @@
        <item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
        <item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
        </style>
+       
+       <style name="Theme.ownCloud.noActionBar" parent="style/Theme.Sherlock.Light.NoActionBar">
+      <item name="android:actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
+      <item name="actionBarStyle">@style/Theme.ownCloud.Widget.ActionBar</item>
+  </style>
+       
 
        <style name="Theme.ownCloud.Widget.ActionBar" parent="style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@drawable/main_header_bg</item>
index 4077775..9e1b124 100644 (file)
@@ -1,5 +1,5 @@
 /* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\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
@@ -19,6 +19,7 @@
 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
@@ -29,15 +30,18 @@ import android.preference.PreferenceManager;
 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/webdav.php";\r
   public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";\r
-  \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 preferences\r
    * \r
    * @param context The current appContext\r
-   * @return The current account or null, if there is none yet.\r
+   * @return The current account or first available, if none is available, then null.\r
    */\r
-  public static Account getCurrentOwnCloudAccount(Context context){\r
+  public static Account getCurrentOwnCloudAccount(Context context) {\r
          Account[] ocAccounts = AccountManager.get(context).getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
          Account defaultAccount = null;\r
          \r
@@ -58,4 +62,27 @@ public class AccountUtils {
          \r
        return defaultAccount;\r
   }\r
+  \r
+  public static void setCurrentOwnCloudAccount(Context context, String name) {\r
+    SharedPreferences.Editor appPrefs = PreferenceManager.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
index c0c950a..3fb5b45 100644 (file)
@@ -8,7 +8,6 @@ import android.app.Notification;
 import android.app.NotificationManager;\r
 import android.app.PendingIntent;\r
 import android.app.Service;\r
-import android.content.BroadcastReceiver;\r
 import android.content.ContentValues;\r
 import android.content.Intent;\r
 import android.net.Uri;\r
@@ -105,6 +104,7 @@ public class FileDownloader extends Service {
     dir.mkdirs();\r
     File file = new File(dir, mFilePath.replace('/', '.'));\r
     \r
+    Log.e(TAG, file.getAbsolutePath() + " " + oc_url.toString());\r
     wdc.downloadFile(mFilePath, file);\r
     ContentValues cv = new ContentValues();\r
     cv.put(ProviderTableMeta.FILE_STORAGE_PATH, file.getAbsolutePath());\r
index 94b43dd..f210a6e 100644 (file)
@@ -436,7 +436,6 @@ public class Uploader extends ListActivity implements OnItemClickListener, andro
         Uri uri = (Uri) mUploadStreams.get(i);\r
         if (uri.getScheme().equals("content")) {\r
           final Cursor c = getContentResolver().query((Uri) mUploadStreams.get(i), null, null, null, null);\r
-          c.moveToFirst();\r
           \r
           if (!wdc.putFile(c.getString(c.getColumnIndex(Media.DATA)),\r
                            mUploadPath+"/"+c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),\r
index a346e2c..7c62b65 100644 (file)
@@ -1,3 +1,21 @@
+/* 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
@@ -8,225 +26,252 @@ import android.os.Bundle;
 import android.util.Log;\r
 \r
 public class AccountAuthenticator extends AbstractAccountAuthenticator {\r
-    public static final String OPTIONS_USERNAME = "username";\r
-    public static final String OPTIONS_PASSWORD = "password";\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
-    public static final String KEY_OC_URL = "oc_url";\r
-    public static final String KEY_CONTACT_URL = "oc_contact_url";\r
-\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, String[] requiredFeatures,\r
-                             Bundle options) throws NetworkErrorException {\r
-        Log.i(getClass().getName(), "Adding account with type " + accountType +\r
-                " and auth token " + authTokenType);\r
-        try {\r
-            validateAccountType(accountType);\r
-            //validateAuthTokenType(authTokenType);\r
-            validateRequiredFeatures(requiredFeatures);\r
-        } catch (AuthenticatorException e) {\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, 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
-        Log.i(getClass().getName(), intent.toString());\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
-            return e.getFailureBundle();\r
-        }\r
-        Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 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
-        throw new UnsupportedOperationException();\r
-    }\r
-\r
-    @Override\r
-    public Bundle getAuthToken(AccountAuthenticatorResponse response,\r
-                               Account account, String authTokenType, Bundle options)\r
-            throws NetworkErrorException {\r
-        Log.i(getClass().getName(), "Getting authToken");\r
-        try {\r
-            validateAccountType(account.type);\r
-            validateAuthTokenType(authTokenType);\r
-        } catch (AuthenticatorException e) {\r
-            Log.w(getClass().getName(), "Validating failded in getAuthToken");\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, 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
+   * 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,\r
+                           String authTokenType,\r
+                           String[] requiredFeatures,\r
+                           Bundle options) throws NetworkErrorException {\r
+    Log.i(TAG, "Adding account with type " + accountType + " and auth token " + authTokenType);\r
+    try {\r
+      validateAccountType(accountType);\r
+    } catch (AuthenticatorException e) {\r
+      Log.e(TAG, "Failed to validate account type "+ accountType +": " + e.getMessage());\r
+      e.printStackTrace();\r
+      return e.getFailureBundle();\r
     }\r
-\r
-    @Override\r
-    public String getAuthTokenLabel(String authTokenType) {\r
-        return null;\r
+    final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 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 +": " + e.getMessage());\r
+      e.printStackTrace();\r
+      return e.getFailureBundle();\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
+    Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 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,\r
+                             String authTokenType,\r
+                             Bundle options) 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 +": " + e.getMessage());\r
+      e.printStackTrace();\r
+      return e.getFailureBundle();\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, 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
+    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
-    @Override\r
-    public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,\r
-                                           Account account) throws NetworkErrorException {\r
-        return super.getAccountRemovalAllowed(response, account);\r
+    final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 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,\r
+                            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,\r
+                                  String authTokenType,\r
+                                  Bundle options) throws NetworkErrorException {\r
+    final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+    intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 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(AccountAuthenticatorResponse response,\r
+      Account account) 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 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
+  private void validateAuthTokenType(String authTokenType)\r
+      throws UnsupportedAuthTokenTypeException {\r
+    if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {\r
+      throw new UnsupportedAuthTokenTypeException();\r
     }\r
+  }\r
 \r
-    private void validateAccountType(String type) throws UnsupportedAccountTypeException {\r
-        if (!type.equals(ACCOUNT_TYPE)) {\r
-            throw new UnsupportedAccountTypeException();\r
-        }\r
-    }\r
+  public static class AuthenticatorException extends Exception {\r
+    private static final long serialVersionUID = 1L;\r
+    private Bundle mFailureBundle;\r
 \r
-    private void validateAuthTokenType(String authTokenType) throws UnsupportedAuthTokenTypeException {\r
-        if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {\r
-            throw new UnsupportedAuthTokenTypeException();\r
-        }\r
+    public AuthenticatorException(int code, String errorMsg) {\r
+      mFailureBundle = new Bundle();\r
+      mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);\r
+      mFailureBundle.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);\r
     }\r
 \r
-    private void validateRequiredFeatures(String[] requiredFeatures) throws UnsupportedFeaturesException {\r
+    public Bundle getFailureBundle() {\r
+      return mFailureBundle;\r
     }\r
+  }\r
 \r
-    private void validateCreaditials(String username, String password, String path) throws AccessDeniedException {\r
+  public static class UnsupportedAccountTypeException\r
+      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 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.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);\r
-        }\r
+  public static class UnsupportedAuthTokenTypeException\r
+      extends\r
+        AuthenticatorException {\r
+    private static final long serialVersionUID = 1L;\r
 \r
-        public Bundle getFailureBundle() {\r
-            return mFailureBundle;\r
-        }\r
+    public UnsupportedAuthTokenTypeException() {\r
+      super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+          "Unsupported auth token type");\r
     }\r
+  }\r
 \r
-    public static class UnsupportedAccountTypeException extends AuthenticatorException {\r
-        private static final long serialVersionUID = 1L;\r
+  public static class UnsupportedFeaturesException\r
+      extends\r
+        AuthenticatorException {\r
+    public static final long serialVersionUID = 1L;\r
 \r
-        public UnsupportedAccountTypeException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported account type");\r
-        }\r
+    public UnsupportedFeaturesException() {\r
+      super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,\r
+          "Unsupported features");\r
     }\r
+  }\r
 \r
-    public static class UnsupportedAuthTokenTypeException extends AuthenticatorException {\r
-        private static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedAuthTokenTypeException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported auth token type");\r
-        }\r
-    }\r
-\r
-    public static class UnsupportedFeaturesException extends AuthenticatorException {\r
-        public static final long serialVersionUID = 1L;\r
-\r
-        public UnsupportedFeaturesException() {\r
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported features");\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
-    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
+    private static final long serialVersionUID = 1L;\r
 \r
-    }\r
+  }\r
 }\r
index 445524c..d156a76 100644 (file)
@@ -34,9 +34,7 @@ public class AuthenticationRunnable implements Runnable {
   private URL mUrl;
   private String mUsername;
   private String mPassword;
-  
-  private static final String WEBDAV_2_0_PATH = "/files/webdav.php";
-  
+
   public AuthenticationRunnable(URL url, String username, String password) {
     mListener = null;
     mUrl = url;
@@ -51,7 +49,8 @@ public class AuthenticationRunnable implements Runnable {
   
   @Override
   public void run() {
-    Uri uri = Uri.parse(mUrl.toString() + WEBDAV_2_0_PATH);
+    Uri uri;
+    uri = Uri.parse(mUrl.toString());
     WebdavClient client = new WebdavClient(uri);
     client.setCredentials(mUsername, mPassword);
     int login_result = client.tryToLogin(); 
@@ -71,11 +70,11 @@ public class AuthenticationRunnable implements Runnable {
   }
 
   private void postResult(final boolean success, final String message) {
-    if (mHandler != null) {
+    if (mHandler != null && mListener != null) {
       mHandler.post(new Runnable() {
         @Override
         public void run() {
-          AuthenticationRunnable.this.mListener.onAuthenticationResult(success, message);
+          mListener.onAuthenticationResult(success, message);
         }
       });
     }
diff --git a/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java b/src/eu/alefzero/owncloud/authenticator/ConnectionCheckerRunnable.java
new file mode 100644 (file)
index 0000000..a9866b4
--- /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 eu.alefzero.owncloud.authenticator;
+
+import java.net.ConnectException;
+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 {
+  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 = ResultType.OK;
+      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);
+        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(uri);
+    wc.allowUnsignedCertificates();
+    GetMethod get = new GetMethod(uri.toString());
+    boolean retval = false;
+    try {
+      int status = wc.executeMethod(get);
+      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) {
+        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);
+        }
+      });
+    }
+  }
+  
+}
index f057b8b..3cd5781 100644 (file)
-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
+ * $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
+ *      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/>.
  *
- * 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.
  */
 
+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.SSLSocket;
 import javax.net.ssl.TrustManager;
 
-import org.apache.http.conn.ConnectTimeoutException;
-import org.apache.http.conn.scheme.LayeredSocketFactory;
-import org.apache.http.conn.scheme.SocketFactory;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
+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;
 
 /**
- * This socket factory will create ssl socket that accepts self signed
- * certificate
+ * <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("https", new EasySSLProtocolSocketFactory(), 443);
+ *
+ *     URI uri = new URI("https://localhost/", 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("https", new EasySSLProtocolSocketFactory(), 443);
+ *     Protocol.registerProtocol("https", easyhttps);
+ *
+ *     HttpClient client = new HttpClient();
+ *     GetMethod httpget = new GetMethod("https://localhost/");
+ *     client.executeMethod(httpget);
+ *     </pre>
+ * </p>
+ * 
+ * @author <a href="mailto:oleg -at- ural.ru">Oleg Kalnichevski</a>
  * 
- * @author olamy
- * @version $Id: EasySSLSocketFactory.java 765355 2009-04-15 20:59:07Z evenisse
- *          $
- * @since 1.2.3
+ * <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 SocketFactory,
-    LayeredSocketFactory {
-
-  private SSLContext sslcontext = null;
-
-  private static SSLContext createEasySSLContext() throws IOException {
-    try {
-      SSLContext context = SSLContext.getInstance("TLS");
-      context.init(null, new TrustManager[] { new EasyX509TrustManager(
-          null) }, null);
-      return context;
-    } catch (Exception e) {
-      throw new IOException(e.getMessage());
+
+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) {
+            return socketfactory.createSocket(host, port, localAddress, localPort);
+        } else {
+            Socket socket = socketfactory.createSocket();
+            SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
+            SocketAddress remoteaddr = new InetSocketAddress(host, port);
+            socket.bind(localaddr);
+            socket.connect(remoteaddr, timeout);
+            return socket;
+        }
     }
-  }
 
-  private SSLContext getSSLContext() throws IOException {
-    if (this.sslcontext == null) {
-      this.sslcontext = createEasySSLContext();
+    /**
+     * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
+     */
+    public Socket createSocket(String host, int port)
+        throws IOException, UnknownHostException {
+        return getSSLContext().getSocketFactory().createSocket(
+            host,
+            port
+        );
     }
-    return this.sslcontext;
-  }
-
-  /**
-   * @see org.apache.http.conn.scheme.SocketFactory#connectSocket(java.net.Socket,
-   *      java.lang.String, int, java.net.InetAddress, int,
-   *      org.apache.http.params.HttpParams)
-   */
-  public Socket connectSocket(Socket sock, String host, int port,
-      InetAddress localAddress, int localPort, HttpParams params)
-      throws IOException, UnknownHostException, ConnectTimeoutException {
-    int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
-    int soTimeout = HttpConnectionParams.getSoTimeout(params);
-
-    InetSocketAddress remoteAddress = new InetSocketAddress(host, port);
-    SSLSocket sslsock = (SSLSocket) ((sock != null) ? sock : createSocket());
-
-    if ((localAddress != null) || (localPort > 0)) {
-      // we need to bind explicitly
-      if (localPort < 0) {
-        localPort = 0; // indicates "any"
-      }
-      InetSocketAddress isa = new InetSocketAddress(localAddress,
-          localPort);
-      sslsock.bind(isa);
+
+    /**
+     * @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
+        );
     }
 
-    sslsock.connect(remoteAddress, connTimeout);
-    sslsock.setSoTimeout(soTimeout);
-    return sslsock;
-
-  }
-
-  /**
-   * @see org.apache.http.conn.scheme.SocketFactory#createSocket()
-   */
-  public Socket createSocket() throws IOException {
-    return getSSLContext().getSocketFactory().createSocket();
-  }
-
-  /**
-   * @see org.apache.http.conn.scheme.SocketFactory#isSecure(java.net.Socket)
-   */
-  public boolean isSecure(Socket socket) throws IllegalArgumentException {
-    return true;
-  }
-
-  /**
-   * @see org.apache.http.conn.scheme.LayeredSocketFactory#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);
-  }
-
-  // -------------------------------------------------------------------
-  // javadoc in org.apache.http.conn.scheme.SocketFactory says :
-  // Both Object.equals() and Object.hashCode() must be overridden
-  // for the correct operation of some connection managers
-  // -------------------------------------------------------------------
-
-  public boolean equals(Object obj) {
-    return ((obj != null) && obj.getClass().equals(
-        EasySSLSocketFactory.class));
-  }
-
-  public int hashCode() {
-    return EasySSLSocketFactory.class.hashCode();
-  }
+    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/OnConnectCheckListener.java b/src/eu/alefzero/owncloud/authenticator/OnConnectCheckListener.java
new file mode 100644 (file)
index 0000000..c4b1815
--- /dev/null
@@ -0,0 +1,20 @@
+package eu.alefzero.owncloud.authenticator;
+
+public interface OnConnectCheckListener {
+  
+  enum ResultType {
+    OK,
+    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);
+  
+}
index 7ecb491..7757551 100644 (file)
@@ -173,13 +173,21 @@ public class FileDataStorageManager implements DataStorageManager {
       
       if (getContentProvider() != null) {
         try {
-          c = getContentProvider().query(req_uri, null, null, null, null);
+          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, null, null, null);
+        c = getContentResolver().query(req_uri,
+                                       null,
+                                       ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                                       new String[]{mAccount.name},
+                                       null);
       }
 
       if (c.moveToFirst()) {
@@ -201,22 +209,24 @@ public class FileDataStorageManager implements DataStorageManager {
     if (getContentResolver() != null) {
       c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
                                     null,
-                                    cmp_key + "=?",
-                                    new String[] {value},
+                                    cmp_key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                                    new String[] {value, mAccount.name},
                                     null);
     } else {
       try {
         c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
                                       null,
-                                      cmp_key + "=?",
-                                      new String[] {value},
+                                      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;
       }
     }
-    return c.moveToFirst();
+    boolean retval = c.moveToFirst();
+    c.close();
+    return retval;
   }
   
   private Cursor getCursorForValue(String key, String value) {
@@ -224,15 +234,15 @@ public class FileDataStorageManager implements DataStorageManager {
     if (getContentResolver() != null) {
       c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
                                      null,
-                                     key + "=?",
-                                     new String[] {value},
+                                     key + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
+                                     new String[] {value, mAccount.name},
                                      null);
     } else {
       try {
         c = getContentProvider().query(ProviderTableMeta.CONTENT_URI,
                                        null,
-                                       key + "=?",
-                                       new String[]{value},
+                                       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());
index 591edaf..b134ae6 100644 (file)
@@ -58,7 +58,7 @@ public class ProviderMeta {
     public static final String FILE_PATH = "path";\r
     public static final String FILE_ACCOUNT_OWNER = "file_owner";\r
     \r
-    public static final String DEFAULT_SORT_ORDER = FILE_NAME + " asc";\r
+    public static final String DEFAULT_SORT_ORDER = FILE_NAME + " 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
new file mode 100644 (file)
index 0000000..4bb849b
--- /dev/null
@@ -0,0 +1,17 @@
+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
new file mode 100644 (file)
index 0000000..93741b3
--- /dev/null
@@ -0,0 +1,48 @@
+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
new file mode 100644 (file)
index 0000000..2d4137c
--- /dev/null
@@ -0,0 +1,116 @@
+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; }
+  }
+}
index 1d23ec8..3d9a766 100644 (file)
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.net.UnknownHostException;\r
 import java.util.Date;\r
 \r
-import org.apache.http.HttpHost;\r
 import org.apache.http.HttpRequest;\r
 import org.apache.http.HttpResponse;\r
 import org.apache.http.client.ClientProtocolException;\r
@@ -39,7 +38,6 @@ import android.content.Context;
 import android.net.Uri;\r
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
 import eu.alefzero.owncloud.datamodel.DataStorageManager;\r
-import eu.alefzero.webdav.HttpPropFind;\r
 import eu.alefzero.webdav.WebdavClient;\r
 \r
 /**\r
@@ -49,8 +47,7 @@ import eu.alefzero.webdav.WebdavClient;
  * @author sassman\r
  * \r
  */\r
-public abstract class AbstractOwnCloudSyncAdapter extends\r
-               AbstractThreadedSyncAdapter {\r
+public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {\r
 \r
        private AccountManager accountManager;\r
        private Account account;\r
@@ -58,9 +55,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
        private Date lastUpdated;\r
        private DataStorageManager mStoreManager;\r
 \r
-       private HttpHost mHost;\r
        private WebdavClient mClient = null;\r
-       private static String TAG = "AbstractOwnCloudSyncAdapter";\r
 \r
        public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {\r
                super(context, autoInitialize);\r
@@ -131,15 +126,6 @@ public abstract class AbstractOwnCloudSyncAdapter extends
                };\r
        }\r
 \r
-       protected HttpPropFind getPropFindQuery()\r
-                       throws OperationCanceledException, AuthenticatorException,\r
-                       IOException {\r
-               HttpPropFind query = new HttpPropFind(getUri().toString());\r
-               query.setHeader("Content-type", "text/xml");\r
-               query.setHeader("User-Agent", "Android-ownCloud");\r
-               return query;\r
-       }\r
-\r
        protected HttpResponse fireRawRequest(HttpRequest query)\r
                        throws ClientProtocolException, OperationCanceledException,\r
                        AuthenticatorException, IOException {\r
@@ -171,7 +157,7 @@ public abstract class AbstractOwnCloudSyncAdapter extends
                        mClient = new WebdavClient(uri);\r
                        mClient.setCredentials(username, password);\r
                        mClient.allowUnsignedCertificates();\r
-                       mHost = mClient.getTargetHost();\r
+                       //mHost = mClient.getTargetHost();\r
                }\r
 \r
                return mClient;\r
index a97d59d..63e99d5 100644 (file)
@@ -31,7 +31,6 @@ import android.content.ContentProviderClient;
 import android.content.Context;\r
 import android.content.Intent;\r
 import android.content.SyncResult;\r
-import android.content.IntentSender.SendIntentException;\r
 import android.os.Bundle;\r
 import android.util.Log;\r
 import eu.alefzero.owncloud.datamodel.FileDataStorageManager;\r
@@ -62,6 +61,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
                        this.setContentProvider(provider);\r
                        this.setStorageManager(new FileDataStorageManager(account, getContentProvider()));\r
 \r
+                       Log.d("ASD", "syncing owncloud account " + account.name);\r
+                       \r
                        Intent i = new Intent(FileSyncService.SYNC_MESSAGE);\r
                        i.putExtra(FileSyncService.IN_PROGRESS, true);\r
                        i.putExtra(FileSyncService.ACCOUNT_NAME, account.name);\r
index a8d0dcd..c6fe962 100644 (file)
@@ -7,17 +7,21 @@ 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 {
+public class FragmentListView extends SherlockFragment
+                              implements OnItemClickListener,
+                                         OnItemLongClickListener {
   ListView mList;
   
   @Override
   public void onCreate(Bundle savedInstanceState) {
     mList = new ListView(getActivity());
     mList.setOnItemClickListener(this);
+    mList.setOnItemLongClickListener(this);
     super.onCreate(savedInstanceState);
   }
   
@@ -38,6 +42,12 @@ public class FragmentListView extends SherlockFragment implements OnItemClickLis
   }
   
   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/activity/AccountSelectActivity.java b/src/eu/alefzero/owncloud/ui/activity/AccountSelectActivity.java
new file mode 100644 (file)
index 0000000..f3dd4b3
--- /dev/null
@@ -0,0 +1,117 @@
+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.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+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 {
+
+  @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();
+
+    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}));
+  }
+  
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater inflater = getSherlock().getMenuInflater();
+    inflater.inflate(eu.alefzero.owncloud.R.menu.account_picker, menu);
+    return true;
+  }
+  
+  @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);
+    Intent i = new Intent(this, FileDisplayActivity.class);
+    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;
+  }
+  
+  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;
+  } 
+    
+    
+  }
+}
+
index 545adef..5952921 100644 (file)
@@ -1,5 +1,5 @@
 /* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\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
@@ -30,22 +30,27 @@ import android.content.ContentResolver;
 import android.content.DialogInterface;\r
 import android.content.Intent;\r
 import android.content.SharedPreferences;\r
-import android.graphics.Color;\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 android.widget.Toast;\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
@@ -53,37 +58,70 @@ import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
  * @author Bartek Przybylski\r
  * \r
  */\r
-public class AuthenticatorActivity extends AccountAuthenticatorActivity implements OnAuthenticationResultListener {\r
+public class AuthenticatorActivity extends AccountAuthenticatorActivity\r
+                                   implements OnAuthenticationResultListener,\r
+                                              OnConnectCheckListener,\r
+                                              OnFocusChangeListener,\r
+                                              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 boolean mUseSSLConnection;\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
-  public AuthenticatorActivity() {\r
-    mUseSSLConnection = true;\r
-  }\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
-    if (getIntent().hasExtra(PARAM_USERNAME)) {\r
-      String username = getIntent().getStringExtra(PARAM_HOSTNAME);\r
-      TextView host_text, user_text;\r
-      host_text = (TextView) findViewById(R.id.host_URL);\r
-      user_text = (TextView) findViewById(R.id.account_username);\r
-      host_text.setText(host_text.getText()\r
-          + username.substring(username.lastIndexOf('@')));\r
-      user_text.setText(user_text.getText()\r
-          + username.substring(0, username.lastIndexOf('@') - 1));\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
@@ -92,20 +130,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
     switch (id) {\r
       case DIALOG_LOGIN_PROGRESS : {\r
         ProgressDialog working_dialog = new ProgressDialog(this);\r
-        dialog = working_dialog;\r
         working_dialog.setMessage(getResources().getString(R.string.auth_trying_to_login));\r
         working_dialog.setIndeterminate(true);\r
         working_dialog.setCancelable(true);\r
         working_dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {\r
           @Override\r
           public void onCancel(DialogInterface dialog) {\r
-            Log.i(getClass().getName(), "Login canceled");\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
@@ -146,21 +184,20 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
       }\r
 \r
       final Intent intent = new Intent();\r
-      intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE,\r
-          AccountAuthenticator.ACCOUNT_TYPE);\r
+      intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);\r
       intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);\r
-      intent.putExtra(AccountManager.KEY_AUTHTOKEN,\r
-          AccountAuthenticator.ACCOUNT_TYPE);\r
-      accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL,\r
-          url.toString());\r
-\r
-      // TODO prepare this URL using a central service\r
+      intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE);\r
       intent.putExtra(AccountManager.KEY_USERDATA, username);\r
-      accManager.setUserData(\r
-          account,\r
-          AccountAuthenticator.KEY_CONTACT_URL,\r
-          url.toString().replace(AccountUtils.WEBDAV_PATH_2_0,\r
-              AccountUtils.CARDDAV_PATH_2_0));\r
+\r
+      accManager.setUserData(account,\r
+                             AccountAuthenticator.KEY_OC_URL,\r
+                             url.toString());\r
+      accManager.setUserData(account,\r
+                             AccountAuthenticator.KEY_OC_VERSION,\r
+                             mConnChkRunnable.getDiscoveredVersion().toString());\r
+      accManager.setUserData(account,\r
+                             AccountAuthenticator.KEY_OC_BASE_URL,\r
+                             mBaseUrl);\r
 \r
       setAccountAuthenticatorResult(intent.getExtras());\r
       setResult(RESULT_OK, intent);\r
@@ -168,96 +205,173 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity implemen
       bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
       getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle);\r
 \r
-      dismissDialog(0);\r
+      /*if (mConnChkRunnable.getDiscoveredVersion().compareTo(OwnCloudVersion.owncloud_v2) >= 0) {\r
+        Intent i = new Intent(this, ExtensionsAvailableActivity.class);\r
+        startActivity(i);\r
+      }*/\r
+\r
       finish();\r
     } else {\r
-      Toast.makeText(this, message, Toast.LENGTH_LONG).show();\r
-      dismissDialog(0);\r
+      dismissDialog(DIALOG_LOGIN_PROGRESS);\r
+      TextView tv = (TextView) findViewById(R.id.account_username);\r
+      tv.setError(message);\r
     }\r
   }\r
 \r
   public void onOkClick(View view) {\r
-    TextView url_text = (TextView) findViewById(R.id.host_URL);\r
-    TextView username_text = (TextView) findViewById(R.id.account_username);\r
-    TextView password_text = (TextView) findViewById(R.id.account_password);\r
-    Log.i(getClass().getName(), "OK clicked");\r
-    boolean hasErrors = false;\r
-\r
-    URL uri = null;\r
-    if (url_text.getText().toString().trim().length() == 0) {\r
-      url_text.setTextColor(Color.RED);\r
-      hasErrors = true;\r
+    String prefix = "";\r
+    String url = ((TextView) findViewById(R.id.host_URL)).getText().toString();\r
+    if (mIsSslConn) {\r
+      prefix = "https://";\r
     } else {\r
-      url_text.setTextColor(android.R.color.black);\r
+      prefix = "http://";\r
     }\r
-    try {\r
-      String url_str = url_text.getText().toString();\r
-      if (!url_str.startsWith("http://") && !url_str.startsWith("https://")) {\r
-        if (mUseSSLConnection)\r
-          url_str = "https://" + url_str;\r
-        else\r
-          url_str = "http://" + url_str;\r
-      }\r
-      uri = new URL(url_str);\r
-    } catch (MalformedURLException e) {\r
-      url_text.setTextColor(Color.RED);\r
-      e.printStackTrace();\r
-      hasErrors = true;\r
-    }\r
-\r
-    if (username_text.getText().toString().contains(" ")\r
-        || username_text.getText().toString().trim().length() == 0) {\r
-      username_text.setTextColor(Color.RED);\r
-      hasErrors = true;\r
-    } else {\r
-      username_text.setTextColor(android.R.color.black);\r
-    }\r
-\r
-    if (password_text.getText().toString().trim().length() == 0) {\r
-      password_text.setTextColor(Color.RED);\r
-      hasErrors = true;\r
-    } else {\r
-      password_text.setTextColor(android.R.color.black);\r
-    }\r
-    if (hasErrors) {\r
-      return;\r
+    if (url.toLowerCase().startsWith("http://") || 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().toString();\r
+    String username = ((TextView) findViewById(R.id.account_username)).getText().toString();\r
+    String password = ((TextView) findViewById(R.id.account_password)).getText().toString();\r
+    if (url.endsWith("/"))\r
+      url = url.substring(0, url.length()-1);\r
 \r
-    int new_port = uri.getPort();\r
-    if (new_port == -1) {\r
-      if (mUseSSLConnection)\r
-        new_port = 443;\r
-      else\r
-        new_port = 80;\r
-    }\r
+    URL uri = null;\r
+    String webdav_path = AccountUtils.getWebdavPath(mConnChkRunnable.getDiscoveredVersion());\r
 \r
     try {\r
-      uri = new URL(uri.getProtocol(), uri.getHost(), new_port, uri.getPath());\r
+      mBaseUrl = prefix + url;\r
+      String url_str = prefix + url + webdav_path;\r
+      uri = new URL(url_str);\r
     } catch (MalformedURLException e) {\r
-      e.printStackTrace(); // should not happend\r
+      // should not happend\r
+      e.printStackTrace();\r
     }\r
 \r
     showDialog(DIALOG_LOGIN_PROGRESS);\r
-    mAuthRunnable = new AuthenticationRunnable(\r
-        uri,\r
-        username_text.getText().toString(),\r
-        password_text.getText().toString());\r
+    mAuthRunnable = new AuthenticationRunnable(uri, username, password);\r
     mAuthRunnable.setOnAuthenticationResultListener(this, mHandler);\r
-    Log.e(TAG, uri.toString());\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().toString().toLowerCase();\r
 \r
-  public void sslBadgeClick(View view, String val) {\r
-    mUseSSLConnection = ((TextView) view).getText().equals("SSL");\r
+    switch (type) {\r
+      case OK:\r
+        // ugly as hell\r
+        if (t_url.startsWith("http://") || t_url.startsWith("https://")) {\r
+          mIsSslConn = t_url.startsWith("http://") ? false : true;\r
+          mStatusIcon = R.drawable.ic_ok;\r
+          mStatusText = R.string.auth_connection_established;\r
+          mStatusCorrect = true;\r
+        } else {\r
+          mIsSslConn = true;\r
+          mStatusIcon = android.R.drawable.ic_secure;\r
+          mStatusText =  R.string.auth_secure_connection;\r
+          mStatusCorrect = true;          \r
+        }\r
+        break;\r
+      case OK_NO_SSL:\r
+        mStatusIcon = android.R.drawable.ic_secure;\r
+        mStatusText = R.string.auth_nossl_plain_ok_title;\r
+        mStatusCorrect = true;\r
+        mIsSslConn = false;\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
-  public void passwordBadgeClick(View view, String val) {\r
-    int input_type = InputType.TYPE_CLASS_TEXT;\r
-    input_type |= val.equals("Hide")\r
-                  ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD\r
-                  : InputType.TYPE_TEXT_VARIATION_PASSWORD;\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.string.auth_testing_connection);\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(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 | 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
-    ((TextView) view).setInputType(input_type);\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 | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;\r
+      view.setInputType(input_type);\r
+    }\r
   }\r
 }\r
index 916b90e..cec268b 100644 (file)
@@ -25,14 +25,15 @@ import android.app.AlertDialog.Builder;
 import android.app.Dialog;\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.BroadcastReceiver;\r
 import android.content.ContentResolver;\r
 import android.content.Intent;\r
 import android.content.IntentFilter;\r
+import android.database.Cursor;\r
 import android.net.Uri;\r
 import android.os.Bundle;\r
+import android.provider.MediaStore;\r
 import android.util.Log;\r
 import android.view.View;\r
 import android.view.ViewGroup;\r
@@ -54,8 +55,6 @@ import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
 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.db.ProviderMeta.ProviderTableMeta;\r
-import eu.alefzero.owncloud.syncadapter.FileSyncAdapter;\r
 import eu.alefzero.owncloud.syncadapter.FileSyncService;\r
 import eu.alefzero.owncloud.ui.fragment.FileListFragment;\r
 import eu.alefzero.webdav.WebdavClient;\r
@@ -76,6 +75,9 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
        \r
        private static final int DIALOG_SETUP_ACCOUNT = 0;\r
        private static final int DIALOG_CREATE_DIR = 1;\r
+       \r
+       private static final int REQUEST_ACCOUNT_SETUP = 0;\r
+       private static final int ACTION_SELECT_FILE = 1;\r
 \r
        public void pushPath(String path) {\r
                mDirectories.insert(path, 0);\r
@@ -96,8 +98,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
       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
+      builder.setPositiveButton(android.R.string.ok, this);\r
+      builder.setNegativeButton(android.R.string.cancel, this);\r
       dialog = builder.create();\r
       break;\r
     case DIALOG_CREATE_DIR:\r
@@ -107,12 +109,13 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
       final Account a = AccountUtils.getCurrentOwnCloudAccount(this);\r
       builder.setView(dirName);\r
       builder.setTitle(R.string.uploader_info_dirname);\r
-      dirName.setTextColor(R.color.setup_text_typed);\r
+      int typed_color = getResources().getColor(R.color.setup_text_typed);\r
+      dirName.setTextColor(typed_color);\r
 \r
-      builder.setPositiveButton(R.string.common_ok, new OnClickListener() {\r
+      builder.setPositiveButton(android.R.string.ok, new OnClickListener() {\r
         public void onClick(DialogInterface dialog, int which) {\r
           String s = dirName.getText().toString();\r
-          if (s.trim().isEmpty()) {\r
+          if (s.trim().length() == 0) {\r
             dialog.cancel();\r
             return;\r
           }\r
@@ -140,6 +143,8 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
               dialog.cancel();\r
             }\r
           });\r
+      dialog = builder.create();\r
+      break;\r
     }\r
     default: \r
       dialog = null;\r
@@ -151,27 +156,19 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
        @Override\r
        public void onCreate(Bundle savedInstanceState) {\r
                super.onCreate(savedInstanceState);\r
+\r
                if(!accountsAreSetup()){\r
       showDialog(DIALOG_SETUP_ACCOUNT);\r
       return;\r
     }\r
-\r
-               requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  \r
-\r
-               mDirectories = new CustomArrayAdapter<String>(this,\r
-                               R.layout.sherlock_spinner_dropdown_item);\r
-               mDirectories.add("/");\r
-               setContentView(R.layout.files);\r
-               mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());\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
-               action_bar.setDisplayHomeAsUpEnabled(true);\r
+               \r
+               requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);\r
+    setProgressBarIndeterminateVisibility(false);\r
        }\r
 \r
        @Override\r
        public boolean onOptionsItemSelected(MenuItem item) {\r
+         boolean retval = true;\r
                switch (item.getItemId()) {\r
                case R.id.settingsItem: {\r
                        Intent i = new Intent(this, Preferences.class);\r
@@ -190,13 +187,23 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
                      bundle);\r
       break;\r
                }\r
+               case R.id.action_upload: {\r
+                 Intent action = new Intent(Intent.ACTION_GET_CONTENT);  \r
+                 action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);  \r
+                 startActivityForResult(Intent.createChooser(action, "Upload file from..."), ACTION_SELECT_FILE);\r
+                 break;\r
+               }\r
+                 \r
                case android.R.id.home: {\r
-                       onBackPressed();\r
+                 Intent i = new Intent(this, AccountSelectActivity.class);\r
+                 startActivity(i);\r
+                 finish();\r
                        break;\r
                }\r
-                       \r
+                       default:\r
+                         retval = false;\r
                }\r
-               return true;\r
+               return retval;\r
        }\r
        \r
        @Override\r
@@ -225,15 +232,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
              showDialog(DIALOG_SETUP_ACCOUNT);\r
            }\r
          }\r
-        \r
-        @Override\r
-         protected void onStart() {\r
-           super.onStart();\r
-           // Check, if there are ownCloud accounts\r
-           if(!accountsAreSetup()){\r
-             showDialog(DIALOG_SETUP_ACCOUNT);\r
-           }\r
-        }\r
+\r
            \r
         @Override\r
        protected void onResume() {\r
@@ -242,16 +241,74 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
       showDialog(DIALOG_SETUP_ACCOUNT);\r
       return;\r
     }\r
+         \r
           IntentFilter f = new IntentFilter(FileSyncService.SYNC_MESSAGE);\r
           b = new  BR();\r
           registerReceiver(b, f);\r
-          setProgressBarIndeterminateVisibility(false);\r
+          if (getSupportFragmentManager().findFragmentById(R.id.fileList) == null)\r
+            setContentView(R.layout.files);\r
+          \r
+          mDirectories = new CustomArrayAdapter<String>(this,\r
+               R.layout.sherlock_spinner_dropdown_item);\r
+           mDirectories.add("/");\r
+           \r
+           mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());\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
+           action_bar.setDisplayHomeAsUpEnabled(true);\r
        }\r
            \r
+        public void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+     if (resultCode == RESULT_OK) {\r
+         if (requestCode == ACTION_SELECT_FILE) {\r
+             Uri selectedImageUri = data.getData();\r
+\r
+             String filemanagerstring = selectedImageUri.getPath();\r
+\r
+             String selectedImagePath = getPath(selectedImageUri);\r
+\r
+             //DEBUG PURPOSE - you can delete this if you want\r
+             if(selectedImagePath!=null)\r
+                 System.out.println(selectedImagePath);\r
+             else System.out.println("selectedImagePath is null");\r
+             if(filemanagerstring!=null)\r
+                 System.out.println(filemanagerstring);\r
+             else System.out.println("filemanagerstring is null");\r
+\r
+             //NOW WE HAVE OUR WANTED STRING\r
+             if(selectedImagePath!=null)\r
+                 System.out.println("selectedImagePath is the right one for you!");\r
+             else\r
+                 System.out.println("filemanagerstring is the right one for you!");\r
+         }\r
+     }\r
+        }\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
+       {\r
+           //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL\r
+           //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA\r
+           int column_index = cursor\r
+           .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);\r
+           cursor.moveToFirst();\r
+           return cursor.getString(column_index);\r
+       }\r
+       else return null;\r
+   }\r
+     \r
         @Override\r
        protected void onPause() {\r
          super.onPause();\r
-         unregisterReceiver(b);\r
+         if (b != null) {\r
+           unregisterReceiver(b);\r
+           b = null;\r
+         }\r
+         \r
        }\r
         \r
        @Override\r
@@ -322,7 +379,7 @@ public class FileDisplayActivity extends SherlockFragmentActivity implements
 \r
                \r
        }\r
-\r
+       \r
         public void onClick(DialogInterface dialog, int which) {\r
            // In any case - we won't need it anymore\r
            dialog.dismiss();\r
index 5747a7b..b513337 100644 (file)
@@ -21,9 +21,6 @@ package eu.alefzero.owncloud.ui.adapter;
 import java.io.File;
 
 import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.R.drawable;
-import eu.alefzero.owncloud.R.id;
-import eu.alefzero.owncloud.R.layout;
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
 import android.accounts.Account;
@@ -45,10 +42,10 @@ public class FileListActionListAdapter implements ListAdapter {
 
   private Context mContext;
   private Account mAccount;
-  private String mFilename, mFileType, mFilePath, mFileStoragePath, mItemId;
+  private String mFilename, mFileType, mFilePath, mFileStoragePath;
   
   private final int ITEM_DOWNLOAD = 0;
-  private final int ITEM_SHARE = 1;
+  //private final int ITEM_SHARE = 1;
   
   public FileListActionListAdapter(Cursor c, Context co, Account account) {
     mContext = co;
@@ -56,7 +53,7 @@ public class FileListActionListAdapter implements ListAdapter {
     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));
+    //mItemId = c.getString(c.getColumnIndex(ProviderTableMeta._ID));
     mAccount = account;
   }
   
index d0d102a..93d7720 100644 (file)
@@ -96,11 +96,28 @@ public class FileListListAdapter implements ListAdapter {
     if (mFiles.size() > position) {\r
       OCFile file = mFiles.get(position);\r
       TextView fileName = (TextView) view.findViewById(R.id.Filename);\r
-      fileName.setText(DisplayUtils.HtmlDecode(file.getFileName()));\r
+      TextView ext_text = (TextView) view.findViewById(R.id.Extension);\r
+      String name = file.getFileName();\r
+      String ext = file.getFileName();\r
+      if (name.lastIndexOf('.') != -1) {\r
+        name = name.substring(0, name.lastIndexOf('.'));\r
+        ext = ext.substring(ext.lastIndexOf('.'));\r
+      } else {\r
+        ext = "";\r
+      }\r
+      \r
+      fileName.setText(DisplayUtils.HtmlDecode(name));\r
+      ext_text.setText(ext);\r
+      ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
       if (!file.getMimetype().equals("DIR")) {\r
-        ImageView fileIcon = (ImageView) view.findViewById(R.id.imageView1);\r
         fileIcon.setImageResource(R.drawable.file);\r
+      } else {\r
+        fileIcon.setImageResource(R.drawable.ic_menu_archive);\r
       }\r
+      ImageView down = (ImageView) view.findViewById(R.id.imageView2);\r
+      if (file.getStoragePath() != null) down.setVisibility(View.VISIBLE);\r
+      else down.setVisibility(View.INVISIBLE);\r
+      \r
     }\r
 \r
     return view;\r
diff --git a/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java b/src/eu/alefzero/owncloud/ui/fragment/AuthenticatorAccountDetailsFragment.java
new file mode 100644 (file)
index 0000000..e17cf79
--- /dev/null
@@ -0,0 +1,7 @@
+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
new file mode 100644 (file)
index 0000000..84ef887
--- /dev/null
@@ -0,0 +1,7 @@
+package eu.alefzero.owncloud.ui.fragment;
+
+import com.actionbarsherlock.app.SherlockFragment;
+
+public class AuthenticatorGetStartedFragment extends SherlockFragment {
+
+}
index 3639ac6..3ad899b 100644 (file)
@@ -21,6 +21,8 @@ import java.util.Stack;
 import java.util.Vector;\r
 \r
 import android.accounts.Account;\r
+import android.content.ClipData;\r
+import android.content.ClipDescription;\r
 import android.content.Intent;\r
 import android.os.Bundle;\r
 import android.util.Log;\r
@@ -57,6 +59,9 @@ public class FileListFragment extends FragmentListView {
     super.onCreate(savedInstanceState);\r
 \r
     mAccount = AccountUtils.getCurrentOwnCloudAccount(getActivity());\r
+    getListView().setDivider(getResources().getDrawable(R.drawable.uploader_list_separator));\r
+    getListView().setDividerHeight(1);\r
+    \r
     populateFileList();\r
   }\r
   \r
@@ -89,7 +94,16 @@ public class FileListFragment extends FragmentListView {
       startActivity(i);\r
     }\r
   }\r
-\r
+  \r
+  @Override\r
+  public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {\r
+    ClipData.Item item = new ClipData.Item("ASD");\r
+    ClipDescription cd = new ClipDescription("ASD", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN});\r
+    ClipData dragData = new ClipData(cd, item);\r
+    arg1.startDrag(dragData, new View.DragShadowBuilder(arg0.getChildAt(arg2)), null, 0);\r
+    return true;\r
+  }\r
+  \r
   /**\r
    * Call this, when the user presses the up button\r
    */\r
diff --git a/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java b/src/eu/alefzero/owncloud/utils/OwnCloudVersion.java
new file mode 100644 (file)
index 0000000..d5b607a
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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;
+    }
+  }
+}
index b0d550d..a17c59e 100644 (file)
@@ -5,20 +5,14 @@ import java.lang.reflect.Method;
 
 import eu.alefzero.owncloud.R;
 import android.content.Context;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.text.InputType;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
-import android.view.View;
-import android.widget.CheckBox;
 import android.widget.EditText;
-import android.widget.TextView;
 
 public class ActionEditText extends EditText {
   private String s;
@@ -26,6 +20,7 @@ public class ActionEditText extends EditText {
   private int optionOneColor; 
   private String optionTwoString;
   private int optionTwoColor;
+  private Rect mTextBounds, mButtonRect;
   
   private String badgeClickCallback;
   private Rect btn_rect;
@@ -34,39 +29,41 @@ public class ActionEditText extends EditText {
     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);
-    Rect r = new Rect();
     
     Paint p = getPaint();
-    Rect text_bounds = new Rect();
     
-    p.getTextBounds(s, 0, s.length(), text_bounds);
+    p.getTextBounds(s, 0, s.length(), mTextBounds);
     
-    getDrawingRect(r);
-    r.top += 10;
-    r.bottom -= 10;
-    r.left = (int)(getWidth() - text_bounds.width() - 18);
-    r.right = getWidth() - 10;
-    btn_rect = r;
+    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(r, p);
+    canvas.drawRect(mButtonRect, p);
     p.setColor(Color.GRAY);
     
-    canvas.drawText(s, r.left + 3, r.bottom - (text_bounds.height()/2), p);
+    canvas.drawText(s, mButtonRect.left + 3, mButtonRect.bottom - (mTextBounds.height()/2), p);
     
     invalidate();
   }
@@ -81,6 +78,7 @@ public class ActionEditText extends EditText {
         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;
diff --git a/src/eu/alefzero/webdav/FileRequestEntity.java b/src/eu/alefzero/webdav/FileRequestEntity.java
new file mode 100644 (file)
index 0000000..70154ec
--- /dev/null
@@ -0,0 +1,53 @@
+package eu.alefzero.webdav;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.commons.httpclient.methods.RequestEntity;
+
+/**
+ * A RequestEntity that represents a File.
+ *
+ */
+public class FileRequestEntity implements RequestEntity {
+
+  final File file;
+  final String contentType;
+
+  public FileRequestEntity(final File file, final String contentType) {
+    super();
+    if (file == null) {
+      throw new IllegalArgumentException("File may not be null");
+    }
+    this.file = file;
+    this.contentType = contentType;
+  }
+  public long getContentLength() {
+    return this.file.length();
+  }
+
+  public String getContentType() {
+    return this.contentType;
+  }
+
+  public boolean isRepeatable() {
+    return true;
+  }
+
+  public void writeRequest(final OutputStream out) throws IOException {
+    byte[] tmp = new byte[4096];
+    int i = 0;
+    InputStream instream = new FileInputStream(this.file);
+    try {
+      while ((i = instream.read(tmp)) >= 0) {
+        out.write(tmp, 0, i);
+      }
+    } finally {
+      instream.close();
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/src/eu/alefzero/webdav/HttpMkCol.java b/src/eu/alefzero/webdav/HttpMkCol.java
deleted file mode 100644 (file)
index 8fcac16..0000000
+++ /dev/null
@@ -1,36 +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.webdav;\r
-\r
-import java.net.URI;\r
-\r
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;\r
-\r
-public class HttpMkCol extends HttpEntityEnclosingRequestBase {\r
-\r
-  public final static String METHOD_NAME = "MKCOL";\r
-  \r
-  public HttpMkCol(final String uri) {\r
-    setURI(URI.create(uri));\r
-  }\r
-\r
-  @Override\r
-  public String getMethod() {\r
-    return METHOD_NAME;\r
-  }\r
-}\r
diff --git a/src/eu/alefzero/webdav/HttpPropFind.java b/src/eu/alefzero/webdav/HttpPropFind.java
deleted file mode 100644 (file)
index a3d0063..0000000
+++ /dev/null
@@ -1,49 +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.webdav;\r
-\r
-import java.net.URI;\r
-\r
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;\r
-import org.apache.http.protocol.HTTP;\r
-\r
-public class HttpPropFind extends HttpEntityEnclosingRequestBase {\r
-\r
-  public final static String METHOD_NAME = "PROPFIND";\r
-  \r
-  public HttpPropFind(final URI uri) {\r
-    super();\r
-    setURI(uri);\r
-  }\r
-\r
-  public HttpPropFind(final String uri) {\r
-    this.setDepth("1");\r
-    setURI(URI.create(uri));\r
-    this.setHeader(HTTP.CONTENT_TYPE, "text/xml" + HTTP.CHARSET_PARAM + HTTP.UTF_8.toLowerCase());\r
-  }\r
-  \r
-  @Override\r
-  public String getMethod() {\r
-    return METHOD_NAME;\r
-  }\r
-  \r
-  public void setDepth(String depth) {\r
-    this.setHeader("Depth", depth);\r
-  }\r
-  \r
-}\r
diff --git a/src/eu/alefzero/webdav/HttpPropPatch.java b/src/eu/alefzero/webdav/HttpPropPatch.java
deleted file mode 100644 (file)
index 82898d3..0000000
+++ /dev/null
@@ -1,43 +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.webdav;\r
-\r
-import java.net.URI;\r
-\r
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;\r
-\r
-public class HttpPropPatch extends HttpEntityEnclosingRequestBase {\r
-\r
-  public static final String METHOD_NAME = "PROPPATCH";\r
-  \r
-  public HttpPropPatch(URI uri) {\r
-    super();\r
-    setURI(uri);\r
-  }\r
-  \r
-  public HttpPropPatch(final String uri) {\r
-    super();\r
-    setURI(URI.create(uri));\r
-  }\r
-  \r
-  @Override\r
-  public String getMethod() {\r
-    return METHOD_NAME;\r
-  }\r
-  \r
-}\r
index 1f19629..880995d 100644 (file)
@@ -21,70 +21,37 @@ import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.net.URLDecoder;\r
 
 import org.apache.commons.httpclient.Credentials;\r
 import org.apache.commons.httpclient.HttpClient;\r
-import org.apache.commons.httpclient.HttpMethod;\r
 import org.apache.commons.httpclient.UsernamePasswordCredentials;\r
 import org.apache.commons.httpclient.auth.AuthScope;\r
+import org.apache.commons.httpclient.methods.GetMethod;\r
 import org.apache.commons.httpclient.methods.HeadMethod;\r
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;\r
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.params.ConnManagerPNames;
-import org.apache.http.conn.params.ConnPerRouteBean;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.entity.FileEntity;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.protocol.BasicHttpContext;
+import org.apache.commons.httpclient.methods.PutMethod;\r
+import org.apache.commons.httpclient.params.HttpMethodParams;\r
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.http.HttpStatus;\r
+import org.apache.jackrabbit.webdav.client.methods.MkColMethod;\r
 
 import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
-import eu.alefzero.webdav.HttpMkCol;
 
-import android.net.Uri;
+import android.net.Uri;\r
 import android.util.Log;
 
 public class WebdavClient extends HttpClient {
-  private DefaultHttpClient mHttpClient;
-  private BasicHttpContext mHttpContext;
-  private HttpHost mTargetHost;
-  private SchemeRegistry mSchemeRegistry;
   private Uri mUri;\r
   private Credentials mCredentials;
-  final private static String TAG = "WebdavClient";
-  
-  public DefaultHttpClient getHttpClient() {
-    return mHttpClient;
-  }
-  public HttpHost getTargetHost() {
-    return mTargetHost;
-  }
+  final private static String TAG = "WebdavClient";\r
+  private static final String USER_AGENT = "Android-ownCloud";
   
   public WebdavClient(Uri uri) {
-    mUri = uri;
-    mSchemeRegistry = new SchemeRegistry();
-    setupHttpClient();
+    mUri = uri;\r
+    getParams().setParameter(HttpMethodParams.USER_AGENT, USER_AGENT);
   }
   
-  public void setCredentials(String username, String password) {
-    // determine default port for http or https
-    int targetPort = mTargetHost.getPort() == -1 ? 
-                        ( mUri.getScheme().equals("https") ? 443 : 80)
-                        : mUri.getPort();\r
-\r
+  public void setCredentials(String username, String password) {\r
     getParams().setAuthenticationPreemptive(true);
     getState().setCredentials(AuthScope.ANY, getCredentials(username, password));
   }
@@ -94,22 +61,27 @@ public class WebdavClient extends HttpClient {
       mCredentials = new UsernamePasswordCredentials(username, password); \r
     return mCredentials;\r
   }\r
+\r
   public void allowUnsignedCertificates() {
-    // https
-    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
+    // https\r
+    Protocol.registerProtocol("https", new Protocol("https", new EasySSLSocketFactory(), 443));
   }
   
   public boolean downloadFile(String filepath, File targetPath) {
-    HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));
-    get.setHeader("Host", mUri.getHost());
-    get.setHeader("User-Agent", "Android-ownCloud");
+    //HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));\r
+   \r
+    Log.e("ASD", mUri.toString() + URLDecoder.decode(filepath) + "");\r
+    GetMethod get = new GetMethod(mUri.toString() + URLDecoder.decode(filepath));\r
+    
+//    get.setHeader("Host", mUri.getHost());
+//    get.setHeader("User-Agent", "Android-ownCloud");
     
     try {
-      HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext);
-      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
+      int status = executeMethod(get);
+      if (status != HttpStatus.SC_OK) {
         return false;
       }
-      BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
+      BufferedInputStream bis = new BufferedInputStream(get.getResponseBodyAsStream());
       FileOutputStream fos = new FileOutputStream(targetPath);
       
       byte[] bytes = new byte[512];
@@ -127,29 +99,14 @@ public class WebdavClient extends HttpClient {
                   String remoteTarget,
                   String contentType) {
     boolean result = true;
-    HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));
-    method.setHeader("Content-type", contentType);
-    method.setHeader("Host", mUri.getHost());
-    method.setHeader("User-Agent", "Android-ownCloud");
 
     try {
-      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);
-
-      method.setEntity(fileEntity);
-      Log.i(TAG, "executing:" + method.getRequestLine().toString());
+      FileRequestEntity entity = new FileRequestEntity(new File(localFile), contentType);\r
+      PutMethod put = new PutMethod(mUri.toString() + remoteTarget.substring(1));\r
+      put.setRequestEntity(entity);\r
+      int status = executeMethod(put);\r
+      Log.d(TAG, "PUT method return with status "+status);
 
-      mHttpClient.execute(mTargetHost, method, mHttpContext);
-      /*mHandler.post(new Runnable() {
-      public void run() {
-        Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),
-                                                  c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
-                                                  mUploadPath + (mUploadPath.equals("/")?"":"/"),
-                                                  fileEntity.getContentType().getValue(),
-                                                  fileEntity.getContentLength()+"");
-      }
-    });
-    Log.i(TAG, "Uploading, done");
-*/
       Log.i(TAG, "Uploading, done");
     } catch (final Exception e) {
       Log.i(TAG, ""+e.getMessage());
@@ -169,13 +126,13 @@ public class WebdavClient extends HttpClient {
     }\r
     return r;\r
   }\r
-  
+
   public boolean createDirectory(String path) {
-    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");
-    method.setHeader("User-Agent", "Android-ownCloud");
-    
-    try {
-      mHttpClient.execute(mTargetHost, method, mHttpContext);
+    try {\r
+      MkColMethod mkcol = new MkColMethod(mUri.toString() + "/" + path + "/");
+      int status = executeMethod(mkcol);\r
+      Log.d(TAG, "Status returned " + status);\r
+      Log.d(TAG, "uri: " + mkcol.getURI().toString());
       Log.i(TAG, "Creating dir completed");
     } catch (final Exception e) {
       e.printStackTrace();
@@ -183,27 +140,4 @@ public class WebdavClient extends HttpClient {
     }
     return true;
   }
-  
-  private void setupHttpClient() {
-    // http scheme
-    mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
-    mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
-    
-    HttpParams params = new BasicHttpParams();
-    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
-    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
-    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
-    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
-
-    mHttpContext = new BasicHttpContext();
-    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);
-
-    int port = mUri.getPort() == -1 ? 
-                 mUri.getScheme().equals("https") ? 443 : 80
-               : mUri.getPort();
-    
-    mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());
-    
-    mHttpClient = new DefaultHttpClient(cm, params);
-  }
 }
index 4fd9b74..eefcdf6 100644 (file)
@@ -1,5 +1,5 @@
 /* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
+ *   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
 
 package eu.alefzero.webdav;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Locale;
 
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import android.util.Log;
-
 public class WebdavUtils {
-  
-  public static final String RESPONSE = "response";
-  public static final String HREF = "href";
-  public static final String IS_HIDDEN = "ishidden";
-  public static final String RESOURCE_TYPE = "resourcetype";
-  public static final String CONTENT_TYPE = "getcontenttype";
-  public static final String CONTENT_LENGTH = "getcontentlength";
-  public static final String LAST_MODIFIED = "getlastmodified";
-  public static final String LAST_ACCESS = "lastaccessed";
-  public static final String CREATE_DATE = "creationdate";
-  
-  public static final String PROPSTAT = "propstat";
-  public static final String STATUS = "status";
-  public static final String PROP = "prop";
-
-  private static final String DAV_NAMESPACE_PREFIX = "DAV:";
-  
   public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat("dd.MM.yyyy hh:mm");
   private static final SimpleDateFormat DATETIME_FORMATS[] = {
       new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
@@ -86,14 +53,4 @@ public class WebdavUtils {
     }
     return null;
   }
-  
-  private static String determineDAVPrefix(Element e) {
-    for (int i = 0; i < e.getAttributes().getLength(); ++i) {
-      String attrName = e.getAttributes().item(i).getNodeName();
-      if (e.getAttribute(attrName).equals(DAV_NAMESPACE_PREFIX)) {
-        return attrName.substring(attrName.lastIndexOf(':')+1) + ":";
-      }
-    }
-    return null;
-  }
 }