Refactoring: Added comments to every class, as well as a copyright
authorLennart Rosam <lennart@familie-rosam.de>
Sat, 4 Feb 2012 16:41:28 +0000 (17:41 +0100)
committerLennart Rosam <lennart@familie-rosam.de>
Sat, 4 Feb 2012 16:41:28 +0000 (17:41 +0100)
notice. Also, some classes were moved to packages where they make sense

47 files changed:
AndroidManifest.xml
res/layout/action_bar.xml
src/eu/alefzero/owncloud/ActionItem.java [deleted file]
src/eu/alefzero/owncloud/CustomPopup.java [deleted file]
src/eu/alefzero/owncloud/DbHandler.java [deleted file]
src/eu/alefzero/owncloud/DisplayUtils.java
src/eu/alefzero/owncloud/FileDownloader.java
src/eu/alefzero/owncloud/OwnCloudSession.java
src/eu/alefzero/owncloud/PathLayout.java [deleted file]
src/eu/alefzero/owncloud/QuickAction.java [deleted file]
src/eu/alefzero/owncloud/Uploader.java
src/eu/alefzero/owncloud/WebdavClient.java [deleted file]
src/eu/alefzero/owncloud/authenticator/AccountAuthenticator.java
src/eu/alefzero/owncloud/authenticator/AuthUtils.java
src/eu/alefzero/owncloud/cp.java
src/eu/alefzero/owncloud/db/DbHandler.java [new file with mode: 0644]
src/eu/alefzero/owncloud/db/ProviderMeta.java
src/eu/alefzero/owncloud/syncadapter/AbstractOwnCloudSyncAdapter.java
src/eu/alefzero/owncloud/syncadapter/FileSyncAdapter.java
src/eu/alefzero/owncloud/syncadapter/FileSyncService.java
src/eu/alefzero/owncloud/ui/ActionItem.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/AuthenticatorActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/CustomPopup.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/FileDetailActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/FileDisplayActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/LandingActivity.java [deleted file]
src/eu/alefzero/owncloud/ui/Preferences.java [deleted file]
src/eu/alefzero/owncloud/ui/PreferencesNewSession.java [deleted file]
src/eu/alefzero/owncloud/ui/QuickAction.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/LandingActivity.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/Preferences.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java [new file with mode: 0644]
src/eu/alefzero/owncloud/ui/adapter/FileListListAdapter.java
src/eu/alefzero/owncloud/ui/adapter/LandingScreenAdapter.java
src/eu/alefzero/owncloud/ui/fragment/ActionBar.java
src/eu/alefzero/owncloud/ui/fragment/FileDetail.java
src/eu/alefzero/owncloud/ui/fragment/FileList.java
src/eu/alefzero/owncloud/ui/fragment/LandingPageFragment.java
src/eu/alefzero/owncloud/ui/fragment/PathLayout.java [new file with mode: 0644]
src/eu/alefzero/webdav/HttpMkCol.java
src/eu/alefzero/webdav/HttpPropFind.java
src/eu/alefzero/webdav/HttpPropPatch.java
src/eu/alefzero/webdav/TreeNodeContainer.java
src/eu/alefzero/webdav/WebdavClient.java [new file with mode: 0644]

index 2500eaa..d2bf586 100644 (file)
@@ -1,77 +1,76 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="eu.alefzero.owncloud"
-      android:versionCode="1"
-      android:versionName="1.0">
-<uses-permission
-        android:name="android.permission.GET_ACCOUNTS" />
-    <uses-permission
-        android:name="android.permission.USE_CREDENTIALS" />
-    <uses-permission
-        android:name="android.permission.MANAGE_ACCOUNTS" />
-    <uses-permission
-        android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
-    <uses-permission
-        android:name="android.permission.INTERNET" />
-    <uses-permission
-        android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.READ_SYNC_STATS" />
-    <uses-permission
-        android:name="android.permission.READ_SYNC_SETTINGS" />
-    <uses-permission
-        android:name="android.permission.WRITE_SYNC_SETTINGS" />
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="10" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
-
-    <application android:icon="@drawable/icon" android:label="@string/app_name">
-        <activity android:name=".ui.FileDisplayActivity"></activity>
-        <activity android:name=".Uploader">
-            <intent-filter>
-                <action android:name="android.intent.action.SEND"></action>
-                <category android:name="android.intent.category.DEFAULT"></category>
-                <data android:mimeType="*/*"></data>
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.SEND_MULTIPLE"></action>
-                <category android:name="android.intent.category.DEFAULT"></category>
-                <data android:mimeType="*/*"></data>
-            </intent-filter>
-        </activity>
-        <activity android:name=".ui.Preferences"></activity>
-        <activity android:name=".ui.PreferencesNewSession">
-        </activity>
-                <service
-            android:exported="true" android:name=".authenticator.AccountAuthenticatorService">
-            <intent-filter>
-                <action
-                    android:name="android.accounts.AccountAuthenticator" />
-            </intent-filter>
-            <meta-data
-                android:name="android.accounts.AccountAuthenticator"
-                android:resource="@xml/authenticator" />
-        </service>
-         <service
-            android:exported="true" android:name=".syncadapter.FileSyncService">
-            <intent-filter>
-                <action android:name="android.content.SyncAdapter"/>
-            </intent-filter>
-            <meta-data
-                android:name="android.content.SyncAdapter"
-                android:resource="@xml/syncadapter_files"/>
-        </service>
-         <provider android:name=".cp" android:enabled="true" android:syncable="true" android:exported="false" android:authorities="org.owncloud" android:label="@string/sync_string_files"></provider>
-         <activity android:name=".ui.AuthenticatorActivity"></activity>
-         <service android:name=".FileDownloader">
-         </service>
-         <activity android:name=".ui.FileDetailActivity"></activity>
-         <activity android:name=".ui.LandingActivity"
-             android:theme="@android:style/Theme.NoTitleBar"
-             android:label="@string/app_name">
-             <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-         </activity>
-    </application>
+<?xml version="1.0" encoding="utf-8"?>\r
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+      package="eu.alefzero.owncloud"\r
+      android:versionCode="1"\r
+      android:versionName="1.0">\r
+<uses-permission\r
+        android:name="android.permission.GET_ACCOUNTS" />\r
+    <uses-permission\r
+        android:name="android.permission.USE_CREDENTIALS" />\r
+    <uses-permission\r
+        android:name="android.permission.MANAGE_ACCOUNTS" />\r
+    <uses-permission\r
+        android:name="android.permission.AUTHENTICATE_ACCOUNTS" />\r
+    <uses-permission\r
+        android:name="android.permission.INTERNET" />\r
+    <uses-permission\r
+        android:name="android.permission.WRITE_SETTINGS" />\r
+    <uses-permission\r
+        android:name="android.permission.READ_SYNC_STATS" />\r
+    <uses-permission\r
+        android:name="android.permission.READ_SYNC_SETTINGS" />\r
+    <uses-permission\r
+        android:name="android.permission.WRITE_SYNC_SETTINGS" />\r
+    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="10" />\r
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>\r
+\r
+    <application android:icon="@drawable/icon" android:label="@string/app_name">\r
+        <activity android:name=".ui.activity.FileDisplayActivity"></activity>\r
+        <activity android:name=".Uploader">\r
+            <intent-filter>\r
+                <action android:name="android.intent.action.SEND"></action>\r
+                <category android:name="android.intent.category.DEFAULT"></category>\r
+                <data android:mimeType="*/*"></data>\r
+            </intent-filter>\r
+            <intent-filter>\r
+                <action android:name="android.intent.action.SEND_MULTIPLE"></action>\r
+                <category android:name="android.intent.category.DEFAULT"></category>\r
+                <data android:mimeType="*/*"></data>\r
+            </intent-filter>\r
+        </activity>\r
+        <activity android:name=".ui.activity.Preferences"></activity>\r
+        <activity android:name=".ui.activity.PreferencesNewSessionewSession"></activity>\r
+                <service\r
+            android:exported="true" android:name=".authenticator.AccountAuthenticatorService">\r
+            <intent-filter>\r
+                <action\r
+                    android:name="android.accounts.AccountAuthenticator" />\r
+            </intent-filter>\r
+            <meta-data\r
+                android:name="android.accounts.AccountAuthenticator"\r
+                android:resource="@xml/authenticator" />\r
+        </service>\r
+         <service\r
+            android:exported="true" android:name=".syncadapter.FileSyncService">\r
+            <intent-filter>\r
+                <action android:name="android.content.SyncAdapter"/>\r
+            </intent-filter>\r
+            <meta-data\r
+                android:name="android.content.SyncAdapter"\r
+                android:resource="@xml/syncadapter_files"/>\r
+        </service>\r
+         <provider android:name=".cp" android:enabled="true" android:syncable="true" android:exported="false" android:authorities="org.owncloud" android:label="@string/sync_string_files"></provider>\r
+         <activity android:name=".ui.activity.AuthenticatorActivity"></activity>\r
+         <service android:name=".FileDownloader">\r
+         </service>\r
+         <activity android:name=".ui.activity.FileDetailActivity"></activity>\r
+         <activity android:name=".ui.activity.LandingActivity"\r
+             android:theme="@android:style/Theme.NoTitleBar"\r
+             android:label="@string/app_name">\r
+             <intent-filter>\r
+                <action android:name="android.intent.action.MAIN" />\r
+                <category android:name="android.intent.category.LAUNCHER" />\r
+            </intent-filter>\r
+         </activity>\r
+    </application>\r
 </manifest>
\ No newline at end of file
 </manifest>
\ No newline at end of file
index 4d69c6a..4500adb 100644 (file)
@@ -1,39 +1,39 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:background="#F7F7F7"
-    android:orientation="vertical" >
-
-    <LinearLayout
-        android:id="@+id/linearLayout1"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:orientation="vertical" >
-
-        <LinearLayout
-            android:id="@+id/linearLayout7"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:background="@drawable/main_header_bg"
-            android:gravity="top"
-            android:orientation="horizontal" >
-
-            <ImageView
-                android:id="@+id/main_header_small"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical|left"
-                android:src="@drawable/icon" >
-            </ImageView>
-
-            <eu.alefzero.owncloud.PathLayout
-                android:id="@+id/pathLayout1"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_vertical" >
-            </eu.alefzero.owncloud.PathLayout>
-        </LinearLayout>
-    </LinearLayout>
+<?xml version="1.0" encoding="utf-8"?>\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    android:layout_width="fill_parent"\r
+    android:layout_height="wrap_content"\r
+    android:background="#F7F7F7"\r
+    android:orientation="vertical" >\r
+\r
+    <LinearLayout\r
+        android:id="@+id/linearLayout1"\r
+        android:layout_width="fill_parent"\r
+        android:layout_height="fill_parent"\r
+        android:orientation="vertical" >\r
+\r
+        <LinearLayout\r
+            android:id="@+id/linearLayout7"\r
+            android:layout_width="fill_parent"\r
+            android:layout_height="wrap_content"\r
+            android:layout_gravity="center_vertical"\r
+            android:background="@drawable/main_header_bg"\r
+            android:gravity="top"\r
+            android:orientation="horizontal" >\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_vertical|left"\r
+                android:src="@drawable/icon" >\r
+            </ImageView>\r
+\r
+            <eu.alefzero.owncloud.ui.fragment.PathLayout\r
+                android:id="@+id/pathLayout1"\r
+                android:layout_width="wrap_content"\r
+                android:layout_height="wrap_content"\r
+                android:layout_gravity="center_vertical" >\r
+            </eu.alefzero.owncloud.ui.fragment.PathLayout>\r
+        </LinearLayout>\r
+    </LinearLayout>\r
 </LinearLayout>
\ No newline at end of file
 </LinearLayout>
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/ActionItem.java b/src/eu/alefzero/owncloud/ActionItem.java
deleted file mode 100644 (file)
index 5f97c55..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-package eu.alefzero.owncloud;
-
-import android.graphics.drawable.Drawable;
-import android.view.View.OnClickListener;
-
-public class ActionItem {
-  private Drawable mIcon;
-  private String mTitle;
-  private OnClickListener mClickListener;
-  
-  public ActionItem() { }
-  
-  public void setTitle(String title) {
-    mTitle = title;
-  }
-  
-  public String getTitle() {
-    return mTitle;
-  }
-  
-  public void setIcon(Drawable icon) {
-    mIcon = icon;
-  }
-  
-  public Drawable getIcon() {
-    return mIcon;
-  }
-  
-  public void setOnClickListener(OnClickListener listener) {
-    mClickListener = listener;
-  }
-  
-  public OnClickListener getOnClickListerner() {
-    return mClickListener;
-  }
-  
-}
diff --git a/src/eu/alefzero/owncloud/CustomPopup.java b/src/eu/alefzero/owncloud/CustomPopup.java
deleted file mode 100644 (file)
index 7c91970..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-package eu.alefzero.owncloud;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowManager;
-import android.view.View.OnTouchListener;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.PopupWindow;
-
-public class CustomPopup {
-  protected final View mAnchor;
-  protected final PopupWindow mWindow;
-  private View root;
-  private Drawable background = null;
-  protected final WindowManager mWManager;
-  
-  public CustomPopup(View anchor) {
-    mAnchor = anchor;
-    mWindow = new PopupWindow(anchor.getContext());
-    
-    mWindow.setTouchInterceptor(new OnTouchListener() {
-      
-      public boolean onTouch(View v, MotionEvent event) {
-        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-          CustomPopup.this.dismiss();
-          return true;
-        }
-        return false;
-      }
-    });
-    
-    mWManager = (WindowManager) anchor.getContext().getSystemService(Context.WINDOW_SERVICE);
-    onCreate();
-  }
-  
-  
-  public void onCreate() {}
-  public void onShow() {}
-  
-  public void preShow() {
-    if (root == null) {
-      throw new IllegalStateException("setContentView called with a view to display");
-    }
-    
-    onShow();
-    
-    if (background == null) {
-      mWindow.setBackgroundDrawable(new BitmapDrawable());
-    } else {
-      mWindow.setBackgroundDrawable(background);
-    }
-    
-    mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
-    mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
-    mWindow.setTouchable(true);
-    mWindow.setFocusable(true);
-    mWindow.setOutsideTouchable(true);
-    
-    mWindow.setContentView(root);
-  }
-  
-  public void setBackgroundDrawable(Drawable background) {
-    this.background = background;
-  }
-  
-  public void setContentView(View root) {
-    this.root = root;
-    mWindow.setContentView(root);
-  }
-  
-  public void setContentView(int layoutResId) {
-    LayoutInflater inflater = 
-      (LayoutInflater) mAnchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-    setContentView(inflater.inflate(layoutResId, null));
-  }
-  
-  public void showDropDown() {
-    showDropDown(0, 0);
-  }
-  
-  public void showDropDown(int x, int y) {
-    preShow();
-    mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
-    mWindow.showAsDropDown(mAnchor, x, y);
-  }
-  
-  public void showLikeQuickAction() {
-    showLikeQuickAction(0, 0);
-  }
-  
-  public void showLikeQuickAction(int x, int y) {
-    preShow();
-    
-    mWindow.setAnimationStyle(android.R.style.Animation_Dialog);
-    int[] location = new int[2];
-    mAnchor.getLocationOnScreen(location);
-    
-    Rect anchorRect = 
-      new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] + mAnchor.getHeight());
-    
-    root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-    root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
-    
-    int rootW = root.getWidth(), rootH = root.getHeight();
-    int screenW = mWManager.getDefaultDisplay().getWidth();
-    
-    int xpos = ((screenW-rootW)/2) + x;
-    int ypos = anchorRect.top - rootH + y;
-    
-    if (rootH > anchorRect.top) {
-      ypos = anchorRect.bottom + y;
-    }
-    mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);
-  }
-  
-  public void dismiss() {
-    mWindow.dismiss();
-  }
-  
-}
diff --git a/src/eu/alefzero/owncloud/DbHandler.java b/src/eu/alefzero/owncloud/DbHandler.java
deleted file mode 100644 (file)
index c47bd43..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-package eu.alefzero.owncloud;
-
-import java.util.Vector;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-public class DbHandler {
-  private SQLiteDatabase mDB;
-  private OpenerHepler mHelper;
-  private final String mDatabaseName = "ownCloud";
-  private final String TABLE_SESSIONS = "sessions";
-  private final int mDatabaseVersion = 1;
-  
-  public DbHandler(Context context) {
-    mHelper = new OpenerHepler(context);
-    mDB = mHelper.getWritableDatabase();
-  }
-  
-  public Vector<OwnCloudSession> getSessionList() {
-    Cursor c = mDB.query(TABLE_SESSIONS, null, null, null, null, null, null);
-    Vector<OwnCloudSession> v = new Vector<OwnCloudSession>();
-    if (!c.moveToFirst()) {
-      return v;
-    }
-    while (!c.isAfterLast()) {
-      v.add(new OwnCloudSession(c.getString(c.getColumnIndex("sessionName")),
-                                c.getString(c.getColumnIndex("sessionUrl")),
-                                c.getInt(c.getColumnIndex("_id"))));
-      c.moveToNext();
-    }
-    c.close();
-    return v;
-  }
-  
-  public void addSession(String sessionName, String uri) {
-    ContentValues cv = new ContentValues();
-    cv.put("sessionName", sessionName);
-    cv.put("sessionUrl", uri);
-    mDB.insert(TABLE_SESSIONS, null, cv);
-  }
-  
-  public void removeSessionWithId(int sessionId) {
-    mDB.delete(TABLE_SESSIONS, "_id = ?", new String[] {String.valueOf(sessionId)});
-  }
-
-  public void changeSessionFields(int id, String hostname, String uri) {
-    ContentValues cv = new ContentValues();
-    cv.put("sessionName", hostname);
-    cv.put("sessionUrl", uri);
-    mDB.update(TABLE_SESSIONS, cv, "_id = ?", new String[] {String.valueOf(id)});
-  }
-  
-  public void close() {
-    mDB.close();
-  }
-  
-  private class OpenerHepler extends SQLiteOpenHelper {
-    public OpenerHepler(Context context) {
-      super(context, mDatabaseName, null, mDatabaseVersion);
-    }
-
-    @Override
-    public void onCreate(SQLiteDatabase db) {
-      db.execSQL("CREATE TABLE " + TABLE_SESSIONS + " (" +
-                 " _id INTEGER PRIMARY KEY, " +
-                 " sessionName TEXT, " +
-                 " sessionUrl  TEXT);");
-    }
-
-    @Override
-    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-    }
-  }
-}
index 3f278b3..bea19ac 100644 (file)
@@ -1,75 +1,80 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package eu.alefzero.owncloud;
-
-import java.util.HashMap;
-
-import android.util.Log;
-
-public class DisplayUtils {
-  public static String bitsToHumanReadable(long bitsLen) {
-    double result = bitsLen;
-    int attachedsuff = 0;
-    while (result > 1024 && attachedsuff < suffixes.length) {
-      result /= 1024.;
-      attachedsuff++;
-    }
-    result = ((int)(result * 100))/100.;
-    return result+suffixes[attachedsuff];
-  }
-  
-  public static String HtmlDecode(String s) {
-    String ret = "";
-    for (int i = 0; i < s.length(); ++i) {
-      if (s.charAt(i) == '%') {
-        ret += (char)Integer.parseInt(s.substring(i+1, i+3), 16);
-        i+=2;
-      } else {
-        ret += s.charAt(i);
-      }
-    }
-    return ret;
-  }
-
-  public static String convertMIMEtoPrettyPrint(String mimetype) {
-    if (mimeType2HUmanReadable.containsKey(mimetype)) {
-      return mimeType2HUmanReadable.get(mimetype);
-    }
-    return mimetype.split("/")[1].toUpperCase() + " file";
-  }
-  
-  private static final String[] suffixes = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
-  
-  private static HashMap<String, String> mimeType2HUmanReadable;
-  static {
-    mimeType2HUmanReadable = new HashMap<String, String>();
-    // images
-    mimeType2HUmanReadable.put("image/jpeg", "JPEG image");
-    mimeType2HUmanReadable.put("image/jpg", "JPEG image");
-    mimeType2HUmanReadable.put("image/png", "PNG image");
-    mimeType2HUmanReadable.put("image/bmp", "Bitmap image");
-    mimeType2HUmanReadable.put("image/gif", "GIF image");
-    mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");
-    mimeType2HUmanReadable.put("image/tiff", "TIFF image");
-    // music
-    mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");
-    mimeType2HUmanReadable.put("application/ogg", "OGG music file");
-    
-  }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package eu.alefzero.owncloud;\r
+\r
+import java.util.HashMap;\r
+\r
+import android.util.Log;\r
+\r
+/**\r
+ * A helper class for some string operations.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class DisplayUtils {\r
+  public static String bitsToHumanReadable(long bitsLen) {\r
+    double result = bitsLen;\r
+    int attachedsuff = 0;\r
+    while (result > 1024 && attachedsuff < suffixes.length) {\r
+      result /= 1024.;\r
+      attachedsuff++;\r
+    }\r
+    result = ((int)(result * 100))/100.;\r
+    return result+suffixes[attachedsuff];\r
+  }\r
+  \r
+  public static String HtmlDecode(String s) {\r
+    String ret = "";\r
+    for (int i = 0; i < s.length(); ++i) {\r
+      if (s.charAt(i) == '%') {\r
+        ret += (char)Integer.parseInt(s.substring(i+1, i+3), 16);\r
+        i+=2;\r
+      } else {\r
+        ret += s.charAt(i);\r
+      }\r
+    }\r
+    return ret;\r
+  }\r
+\r
+  public static String convertMIMEtoPrettyPrint(String mimetype) {\r
+    if (mimeType2HUmanReadable.containsKey(mimetype)) {\r
+      return mimeType2HUmanReadable.get(mimetype);\r
+    }\r
+    return mimetype.split("/")[1].toUpperCase() + " file";\r
+  }\r
+  \r
+  private static final String[] suffixes = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};\r
+  \r
+  private static HashMap<String, String> mimeType2HUmanReadable;\r
+  static {\r
+    mimeType2HUmanReadable = new HashMap<String, String>();\r
+    // images\r
+    mimeType2HUmanReadable.put("image/jpeg", "JPEG image");\r
+    mimeType2HUmanReadable.put("image/jpg", "JPEG image");\r
+    mimeType2HUmanReadable.put("image/png", "PNG image");\r
+    mimeType2HUmanReadable.put("image/bmp", "Bitmap image");\r
+    mimeType2HUmanReadable.put("image/gif", "GIF image");\r
+    mimeType2HUmanReadable.put("image/svg+xml", "JPEG image");\r
+    mimeType2HUmanReadable.put("image/tiff", "TIFF image");\r
+    // music\r
+    mimeType2HUmanReadable.put("audio/mpeg", "MP3 music file");\r
+    mimeType2HUmanReadable.put("application/ogg", "OGG music file");\r
+    \r
+  }\r
+}\r
index 7d3605e..121e147 100644 (file)
@@ -1,76 +1,77 @@
-package eu.alefzero.owncloud;
-
-import java.io.File;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.IBinder;
-import android.util.Log;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.ui.FileDisplayActivity;
-
-public class FileDownloader extends Service {
-  static final String EXTRA_ACCOUNT = "ACCOUNT";
-  static final String EXTRA_FILE_PATH = "FILE_PATH";
-  static final String TAG = "OC_FileDownloader";
-  
-  NotificationManager nm;
-  
-  @Override
-  public IBinder onBind(Intent arg0) {
-    return null;
-  }
-  
-  @Override
-  public int onStartCommand(Intent intent, int flags, int startId) {
-    if (!intent.hasExtra(EXTRA_ACCOUNT) && !intent.hasExtra(EXTRA_FILE_PATH)) {
-      Log.e(TAG, "Not enough information provided in intent");
-      return START_NOT_STICKY;
-    }
-    
-    nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
-    
-    Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
-    String file_path = intent.getStringExtra(EXTRA_FILE_PATH);
-    AccountManager am = (AccountManager)getSystemService(ACCOUNT_SERVICE);
-    Uri oc_url = Uri.parse(am.getUserData(account, AccountAuthenticator.KEY_OC_URL));
-
-    WebdavClient wdc = new WebdavClient(oc_url);
-    
-    String username = account.name.split("@")[0];
-    String password = "";
-    try {
-      password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE, true);
-    } catch (Exception e) {
-      // TODO Auto-generated catch block
-      e.printStackTrace();
-      return START_NOT_STICKY;
-    }
-    
-    wdc.setCredentials(username, password);
-    wdc.allowUnsignedCertificates();
-
-    Notification n = new Notification(R.drawable.icon, "Downloading file", System.currentTimeMillis());
-    PendingIntent pi = PendingIntent.getActivity(this, 1, new Intent(this, FileDisplayActivity.class), 0);
-    n.setLatestEventInfo(this, "A", "B", pi);
-    nm.notify(1, n);
-
-    File sdCard = Environment.getExternalStorageDirectory();
-    File dir = new File (sdCard.getAbsolutePath() + "/owncloud");
-    dir.mkdirs();
-    File file = new File(dir, file_path.replace('/', '.'));
-    
-    wdc.downloadFile(file_path, file);
-    
-    return START_NOT_STICKY;
-  }
-  
-  
-}
+package eu.alefzero.owncloud;\r
+\r
+import java.io.File;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.Notification;\r
+import android.app.NotificationManager;\r
+import android.app.PendingIntent;\r
+import android.app.Service;\r
+import android.content.Intent;\r
+import android.net.Uri;\r
+import android.os.Environment;\r
+import android.os.IBinder;\r
+import android.util.Log;\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
+import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;\r
+import eu.alefzero.webdav.WebdavClient;\r
+\r
+public class FileDownloader extends Service {\r
+  static final String EXTRA_ACCOUNT = "ACCOUNT";\r
+  static final String EXTRA_FILE_PATH = "FILE_PATH";\r
+  static final String TAG = "OC_FileDownloader";\r
+  \r
+  NotificationManager nm;\r
+  \r
+  @Override\r
+  public IBinder onBind(Intent arg0) {\r
+    return null;\r
+  }\r
+  \r
+  @Override\r
+  public int onStartCommand(Intent intent, int flags, int startId) {\r
+    if (!intent.hasExtra(EXTRA_ACCOUNT) && !intent.hasExtra(EXTRA_FILE_PATH)) {\r
+      Log.e(TAG, "Not enough information provided in intent");\r
+      return START_NOT_STICKY;\r
+    }\r
+    \r
+    nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);\r
+    \r
+    Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);\r
+    String file_path = intent.getStringExtra(EXTRA_FILE_PATH);\r
+    AccountManager am = (AccountManager)getSystemService(ACCOUNT_SERVICE);\r
+    Uri oc_url = Uri.parse(am.getUserData(account, AccountAuthenticator.KEY_OC_URL));\r
+\r
+    WebdavClient wdc = new WebdavClient(oc_url);\r
+    \r
+    String username = account.name.split("@")[0];\r
+    String password = "";\r
+    try {\r
+      password = am.blockingGetAuthToken(account, AccountAuthenticator.AUTH_TOKEN_TYPE, true);\r
+    } catch (Exception e) {\r
+      // TODO Auto-generated catch block\r
+      e.printStackTrace();\r
+      return START_NOT_STICKY;\r
+    }\r
+    \r
+    wdc.setCredentials(username, password);\r
+    wdc.allowUnsignedCertificates();\r
+\r
+    Notification n = new Notification(R.drawable.icon, "Downloading file", System.currentTimeMillis());\r
+    PendingIntent pi = PendingIntent.getActivity(this, 1, new Intent(this, FileDisplayActivity.class), 0);\r
+    n.setLatestEventInfo(this, "A", "B", pi);\r
+    nm.notify(1, n);\r
+\r
+    File sdCard = Environment.getExternalStorageDirectory();\r
+    File dir = new File (sdCard.getAbsolutePath() + "/owncloud");\r
+    dir.mkdirs();\r
+    File file = new File(dir, file_path.replace('/', '.'));\r
+    \r
+    wdc.downloadFile(file_path, file);\r
+    \r
+    return START_NOT_STICKY;\r
+  }\r
+  \r
+  \r
+}\r
index c7caae5..0b9fc39 100644 (file)
@@ -1,33 +1,55 @@
-package eu.alefzero.owncloud;
-
-public class OwnCloudSession {
-  private String mSessionName;
-  private String mSessionUrl;
-  private int mEntryId;
-  
-  public OwnCloudSession(String name, String url, int entryId) {
-    mSessionName = name;
-    mSessionUrl = url;
-    mEntryId = entryId;
-  }
-  
-  public void setName(String name) {
-    mSessionName = name;
-  }
-  
-  public String getName() {
-    return mSessionName;
-  }
-  
-  public void setUrl(String url) {
-    mSessionUrl = url;
-  }
-  
-  public String getUrl() {
-    return mSessionUrl;
-  }
-  
-  public int getEntryId() {
-    return mEntryId;
-  }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud;\r
+\r
+/**\r
+ * Represents a session to an ownCloud instance\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class OwnCloudSession {\r
+  private String mSessionName;\r
+  private String mSessionUrl;\r
+  private int mEntryId;\r
+  \r
+  public OwnCloudSession(String name, String url, int entryId) {\r
+    mSessionName = name;\r
+    mSessionUrl = url;\r
+    mEntryId = entryId;\r
+  }\r
+  \r
+  public void setName(String name) {\r
+    mSessionName = name;\r
+  }\r
+  \r
+  public String getName() {\r
+    return mSessionName;\r
+  }\r
+  \r
+  public void setUrl(String url) {\r
+    mSessionUrl = url;\r
+  }\r
+  \r
+  public String getUrl() {\r
+    return mSessionUrl;\r
+  }\r
+  \r
+  public int getEntryId() {\r
+    return mEntryId;\r
+  }\r
+}\r
diff --git a/src/eu/alefzero/owncloud/PathLayout.java b/src/eu/alefzero/owncloud/PathLayout.java
deleted file mode 100644 (file)
index 3f5a493..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-package eu.alefzero.owncloud;
-
-import java.util.LinkedList;
-import java.util.Stack;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.widget.HorizontalScrollView;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-public class PathLayout extends LinearLayout {
-
-  private LinkedList<String> paths;
-  ScrollView internalScroll;
-  LinearLayout view;
-
-  public PathLayout(Context context) {
-    super(context);
-    initialize();
-  }
-  
-  public PathLayout(Context context, AttributeSet attrs) {
-    super(context, attrs);
-    initialize();
-  }
-
-  public String pop() {
-    if (paths.size() == 0) {
-      return null;
-    }
-    int start = paths.size()*2-2;
-    int count = 2;
-    if (paths.size() == 1) {
-      start++;
-      count--;
-    }
-    view.removeViews(start, count);
-    return paths.removeLast();
-  }
-
-  public void addPath(String path) {
-    for (String s : path.split("/")) if (s.length() != 0) push(s);
-  }
-  
-  public void push(String path) {
-    // its weird that we cannot declare static imgView as path separator
-    if (paths.size() != 0) {
-      ImageView iv = new ImageView(getContext());
-      iv.setImageDrawable(getResources().getDrawable(R.drawable.breadcrumb));
-      iv.setPadding(2, 0, 2, 0);
-      view.addView(iv);
-    }
-    TextView tv = new TextView(getContext());
-    tv.setLayoutParams(getLayoutParams());
-    tv.setText(path);
-    view.addView(tv);
-    HorizontalScrollView hsv = (HorizontalScrollView) internalScroll.getChildAt(0);
-    hsv.smoothScrollTo(hsv.getMaxScrollAmount()*2, 0);
-    paths.addLast(path);
-  }
-  
-  public String peek() {
-    return paths.peek();
-  }
-
-  public String getFullPath() {
-    String ret = new String();
-    for (int i = 0; i < paths.size(); i++) {
-      ret += "/" + paths.get(i);
-    }
-    return ret;
-  }
-  
-  private void initialize() {
-    paths = new LinkedList<String>();
-    internalScroll = new ScrollView(getContext());
-    internalScroll.setFillViewport(true);
-    HorizontalScrollView hsv = new HorizontalScrollView(getContext());
-    hsv.setSmoothScrollingEnabled(true);
-    internalScroll.addView(hsv);
-    view = new LinearLayout(getContext());
-    addView(internalScroll);
-    hsv.addView(view);
-    ImageView iv = new ImageView(getContext());
-    iv.setImageDrawable(getResources().getDrawable(R.drawable.breadcrumb));
-    view.addView(iv);
-  }
-
-}
diff --git a/src/eu/alefzero/owncloud/QuickAction.java b/src/eu/alefzero/owncloud/QuickAction.java
deleted file mode 100644 (file)
index d197423..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-package eu.alefzero.owncloud;\r
-\r
-import android.content.Context;\r
-\r
-import android.graphics.Rect;\r
-import android.graphics.drawable.Drawable;\r
-\r
-import android.widget.ImageView;\r
-import android.widget.TextView;\r
-import android.widget.LinearLayout;\r
-import android.widget.ScrollView;\r
-\r
-import android.view.Gravity;\r
-import android.view.LayoutInflater;\r
-import android.view.View;\r
-import android.view.View.OnClickListener;\r
-import android.view.ViewGroup.LayoutParams;\r
-import android.view.ViewGroup;\r
-\r
-import java.util.ArrayList;\r
-\r
-/**\r
- * Popup window, shows action list as icon and text like the one in Gallery3D app. \r
- * \r
- * @author Lorensius. W. T\r
- */\r
-public class QuickAction extends CustomPopup {\r
-       private final View root;\r
-       private final ImageView mArrowUp;\r
-       private final ImageView mArrowDown;\r
-       private final LayoutInflater inflater;\r
-       private final Context context;\r
-       \r
-       protected static final int ANIM_GROW_FROM_LEFT = 1;\r
-       protected static final int ANIM_GROW_FROM_RIGHT = 2;\r
-       protected static final int ANIM_GROW_FROM_CENTER = 3;\r
-       protected static final int ANIM_REFLECT = 4;\r
-       protected static final int ANIM_AUTO = 5;\r
-\r
-       private int animStyle;\r
-       private ViewGroup mTrack;\r
-       private ScrollView scroller;\r
-       private ArrayList<ActionItem> actionList;\r
-       \r
-       /**\r
-        * Constructor\r
-        * \r
-        * @param anchor {@link View} on where the popup window should be displayed\r
-        */\r
-       public QuickAction(View anchor) {\r
-               super(anchor);\r
-               \r
-               actionList      = new ArrayList<ActionItem>();\r
-               context         = anchor.getContext();\r
-               inflater        = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
-               \r
-               root            = (ViewGroup) inflater.inflate(R.layout.popup, null);\r
-               \r
-               mArrowDown      = (ImageView) root.findViewById(R.id.arrow_down);\r
-               mArrowUp        = (ImageView) root.findViewById(R.id.arrow_up);\r
-               \r
-               setContentView(root);\r
-           \r
-               mTrack                  = (ViewGroup) root.findViewById(R.id.tracks);\r
-               scroller                = (ScrollView) root.findViewById(R.id.scroller);\r
-               animStyle               = ANIM_AUTO;\r
-       }\r
-\r
-       /**\r
-        * Set animation style\r
-        * \r
-        * @param animStyle animation style, default is set to ANIM_AUTO\r
-        */\r
-       public void setAnimStyle(int animStyle) {\r
-               this.animStyle = animStyle;\r
-       }\r
-\r
-       /**\r
-        * Add action item\r
-        * \r
-        * @param action  {@link ActionItem} object\r
-        */\r
-       public void addActionItem(ActionItem action) {\r
-               actionList.add(action); \r
-       }\r
-       \r
-       /**\r
-        * Show popup window. Popup is automatically positioned, on top or bottom of anchor view.\r
-        * \r
-        */\r
-       public void show () {\r
-               preShow();\r
-               \r
-               int xPos, yPos;\r
-               \r
-               int[] location          = new int[2];\r
-       \r
-               mAnchor.getLocationOnScreen(location);\r
-\r
-               Rect anchorRect         = new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] \r
-                                       + mAnchor.getHeight());\r
-\r
-               createActionList();\r
-               \r
-               root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));\r
-               root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
-       \r
-               int rootHeight          = root.getMeasuredHeight();\r
-               int rootWidth           = root.getMeasuredWidth();\r
-               \r
-               int screenWidth         = mWManager.getDefaultDisplay().getWidth();\r
-               int screenHeight        = mWManager.getDefaultDisplay().getHeight();\r
-               \r
-               //automatically get X coord of popup (top left)\r
-               if ((anchorRect.left + rootWidth) > screenWidth) {\r
-                       xPos = anchorRect.left - (rootWidth-mAnchor.getWidth());\r
-               } else {\r
-                       if (mAnchor.getWidth() > rootWidth) {\r
-                               xPos = anchorRect.centerX() - (rootWidth/2);\r
-                       } else {\r
-                               xPos = anchorRect.left;\r
-                       }\r
-               }\r
-               \r
-               int dyTop                       = anchorRect.top;\r
-               int dyBottom            = screenHeight - anchorRect.bottom;\r
-\r
-               boolean onTop           = (dyTop > dyBottom) ? true : false;\r
-\r
-               if (onTop) {\r
-                       if (rootHeight > dyTop) {\r
-                               yPos                    = 15;\r
-                               LayoutParams l  = scroller.getLayoutParams();\r
-                               l.height                = dyTop - mAnchor.getHeight();\r
-                       } else {\r
-                               yPos = anchorRect.top - rootHeight;\r
-                       }\r
-               } else {\r
-                       yPos = anchorRect.bottom;\r
-                       \r
-                       if (rootHeight > dyBottom) { \r
-                               LayoutParams l  = scroller.getLayoutParams();\r
-                               l.height                = dyBottom;\r
-                       }\r
-               }\r
-               \r
-               showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), anchorRect.centerX()-xPos);\r
-               \r
-               setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);\r
-               \r
-               mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);\r
-       }\r
-       \r
-       /**\r
-        * Set animation style\r
-        * \r
-        * @param screenWidth screen width\r
-        * @param requestedX distance from left edge\r
-        * @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view\r
-        *                and vice versa\r
-        */\r
-       private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {\r
-               int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;\r
-\r
-               switch (animStyle) {\r
-               case ANIM_GROW_FROM_LEFT:\r
-                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);\r
-                       break;\r
-                                       \r
-               case ANIM_GROW_FROM_RIGHT:\r
-                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);\r
-                       break;\r
-                                       \r
-               case ANIM_GROW_FROM_CENTER:\r
-                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);\r
-               break;\r
-                       \r
-               case ANIM_REFLECT:\r
-                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);\r
-               break;\r
-               \r
-               case ANIM_AUTO:\r
-                       if (arrowPos <= screenWidth/4) {\r
-                               mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);\r
-                       } else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {\r
-                               mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);\r
-                       } else {\r
-                               mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);\r
-                       }\r
-                                       \r
-                       break;\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Create action list\r
-        */\r
-       private void createActionList() {\r
-               View view;\r
-               String title;\r
-               Drawable icon;\r
-               OnClickListener listener;\r
-       \r
-               for (int i = 0; i < actionList.size(); i++) {\r
-                       title           = actionList.get(i).getTitle();\r
-                       icon            = actionList.get(i).getIcon();\r
-                       listener        = actionList.get(i).getOnClickListerner();\r
-       \r
-                       view            = getActionItem(title, icon, listener);\r
-               \r
-                       view.setFocusable(true);\r
-                       view.setClickable(true);\r
-                        \r
-                       mTrack.addView(view);\r
-               }\r
-       }\r
-       \r
-       /**\r
-        * Get action item {@link View}\r
-        * \r
-        * @param title action item title\r
-        * @param icon {@link Drawable} action item icon\r
-        * @param listener {@link View.OnClickListener} action item listener\r
-        * @return action item {@link View}\r
-        */\r
-       private View getActionItem(String title, Drawable icon, OnClickListener listener) {\r
-               LinearLayout container  = (LinearLayout) inflater.inflate(R.layout.action_item, null);\r
-               \r
-               ImageView img                   = (ImageView) container.findViewById(R.id.icon);\r
-               TextView text                   = (TextView) container.findViewById(R.id.title);\r
-               \r
-               if (icon != null) {\r
-                       img.setImageDrawable(icon);\r
-               }\r
-               \r
-               if (title != null) {                    \r
-                       text.setText(title);\r
-               }\r
-               \r
-               if (listener != null) {\r
-                       container.setOnClickListener(listener);\r
-               }\r
-\r
-               return container;\r
-       }\r
-       \r
-       /**\r
-        * Show arrow\r
-        * \r
-        * @param whichArrow arrow type resource id\r
-        * @param requestedX distance from left screen\r
-        */\r
-       private void showArrow(int whichArrow, int requestedX) {\r
-        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;\r
-        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;\r
-\r
-        final int arrowWidth = mArrowUp.getMeasuredWidth();\r
-\r
-        showArrow.setVisibility(View.VISIBLE);\r
-        \r
-        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();\r
-       \r
-        param.leftMargin = requestedX - arrowWidth / 2;\r
-        \r
-        hideArrow.setVisibility(View.INVISIBLE);\r
-    }\r
-}
\ No newline at end of file
index 5a6a4a2..b15cab9 100644 (file)
-package eu.alefzero.owncloud;
-
-import java.io.File;
-import java.net.FileNameMap;
-import java.net.URI;
-import java.net.URLConnection;
-import java.util.ArrayList;
-import java.util.Stack;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ListActivity;
-import android.app.ProgressDialog;
-import android.app.AlertDialog.Builder;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Parcelable;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.AdapterView;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.SimpleCursorAdapter;
-import android.widget.Toast;
-import android.widget.AdapterView.OnItemClickListener;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.webdav.WebdavUtils;
-
-public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {
-  private static final String TAG = "ownCloudUploader";
-
-  private Account mAccount;
-  private AccountManager mAccountManager;
-  private String mUsername, mPassword;
-  private Cursor mCursor;
-  private Stack<String> mParents;
-  private Thread mUploadThread;
-  private Handler mHandler;
-  private ArrayList<Parcelable> mStreamsToUpload;
-
-  private final static int DIALOG_NO_ACCOUNT = 0;
-  private final static int DIALOG_WAITING = 1;
-  private final static int DIALOG_NO_STREAM = 2;
-  private final static int DIALOG_MULTIPLE_ACCOUNT = 3;
-  private final static int DIALOG_GET_DIRNAME = 4;
-
-  private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;
-
-  @Override
-  protected void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
-    mParents = new Stack<String>();
-    mHandler = new Handler();
-    if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {
-      prepareStreamsToUpload();
-      mAccountManager = (AccountManager)getSystemService(Context.ACCOUNT_SERVICE);
-      Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
-      if (accounts.length == 0) {
-        Log.i(TAG, "No ownCloud account is available");
-        showDialog(DIALOG_NO_ACCOUNT);
-      } else if (accounts.length > 1) {
-        Log.i(TAG, "More then one ownCloud is available");
-        showDialog(DIALOG_MULTIPLE_ACCOUNT);
-      } else {
-        mAccount = accounts[0];
-        setContentView(R.layout.uploader_layout);
-        populateDirectoryList();
-      }
-    } else {
-      showDialog(DIALOG_NO_STREAM);
-    }
-  }
-
-  @Override
-  protected Dialog onCreateDialog(final int id) {
-    final AlertDialog.Builder builder = new Builder(this);
-    switch (id) {
-      case DIALOG_WAITING:
-        ProgressDialog pDialog = new ProgressDialog(this);
-        pDialog.setIndeterminate(false);
-        pDialog.setCancelable(false);
-        pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));
-        return pDialog;
-      case DIALOG_NO_ACCOUNT:
-        builder.setIcon(android.R.drawable.ic_dialog_alert);
-        builder.setTitle(R.string.uploader_wrn_no_account_title);
-        builder.setMessage(R.string.uploader_wrn_no_account_text);
-        builder.setCancelable(false);
-        builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {
-          public void onClick(DialogInterface dialog, int which) {
-            if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
-              // using string value since in API7 this constatn is not defined
-              // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS
-              // and Settings.EXTRA_AUTHORITIES
-              Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
-              intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});
-              startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
-            } else {
-              // since in API7 there is no direct call for account setup, so we need to
-              // show our own AccountSetupAcricity, get desired results and setup
-              // everything for ourself
-              Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);
-              startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);
-            }
-          }
-        });
-        builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {
-          public void onClick(DialogInterface dialog, int which) {
-            finish();
-          }
-        });
-        return builder.create();
-      case DIALOG_GET_DIRNAME:
-        final EditText dirName = new EditText(getBaseContext());
-        builder.setView(dirName);
-        builder.setTitle(R.string.uploader_info_dirname);
-        String pathToUpload;
-        if (mParents.empty()) {
-          pathToUpload = "/";
-        } else {
-          mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), 
-                                 null,
-                                 null,
-                                 null,
-                                 null);
-          mCursor.moveToFirst();
-          pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)) +
-                         mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");
-        }
-        a a = new a(pathToUpload, dirName);
-        builder.setPositiveButton(R.string.common_ok, a);
-        builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {
-          public void onClick(DialogInterface dialog, int which) {
-            dialog.cancel();
-          }
-        });
-        return builder.create();
-      case DIALOG_MULTIPLE_ACCOUNT:
-        CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
-        for (int i = 0;  i < ac.length; ++i) {
-          ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;
-        }
-        builder.setTitle(R.string.common_choose_account);
-        builder.setItems(ac, new OnClickListener() {
-          public void onClick(DialogInterface dialog, int which) {
-            mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];
-            populateDirectoryList();
-          }
-        });
-        builder.setCancelable(true);
-        builder.setOnCancelListener(new OnCancelListener() {
-          public void onCancel(DialogInterface dialog) {
-            dialog.cancel();
-            finish();
-          }
-        });
-        return builder.create();
-      default:
-        throw new IllegalArgumentException("Unknown dialog id: " + id);
-    }
-  }
-  
-  class a implements OnClickListener {
-    String mPath;
-    EditText mDirname;
-    public a(String path, EditText dirname) {
-      mPath = path; mDirname = dirname;
-    }
-    public void onClick(DialogInterface dialog, int which) {
-      showDialog(DIALOG_WAITING);
-      mUploadThread = new Thread(new BackgroundUploader(mPath+mDirname.getText().toString(), mStreamsToUpload, mHandler, true));
-      mUploadThread.start();
-    }
-  }
-  
-  @Override
-  public void onBackPressed() {
-    
-    if (mParents.size()==0) {
-      super.onBackPressed();
-      return;
-    } else if (mParents.size() == 1) {
-      mParents.pop();
-      mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,
-          null,
-          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
-          new String[]{"DIR"},
-          null);
-    } else {
-      mParents.pop();
-      mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
-          null,
-          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
-          new String[]{"DIR"},
-          null);
-    }
-    
-    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
-                                   mCursor,
-                                   new String[]{ProviderTableMeta.FILE_NAME},
-                                   new int[]{R.id.textView1});
-    setListAdapter(sca);
-  }
-  
-  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-    if (!mCursor.moveToPosition(position)) {
-      throw new IndexOutOfBoundsException("Incorrect item selected");
-    }
-    String _id = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
-    mParents.push(_id);
-    
-    mCursor.close();
-    mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, _id),
-                           null,
-                           ProviderTableMeta.FILE_CONTENT_TYPE+"=?",
-                           new String[]{"DIR"},
-                           null);
-    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,
-                                                      mCursor,
-                                                      new String[]{ProviderTableMeta.FILE_NAME},
-                                                      new int[]{R.id.textView1});
-    setListAdapter(sca);
-    getListView().invalidate();
-  }
-
-  public void onClick(View v) {
-    switch (v.getId()) {
-      case R.id.uploader_choose_folder:
-        String pathToUpload = null;
-        if (mParents.empty()) {
-          pathToUpload = "/";
-        } else {
-          mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), 
-                                 null,
-                                 null,
-                                 null,
-                                 null);
-          mCursor.moveToFirst();
-          pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)) +
-                         mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");
-        }
-        
-        showDialog(DIALOG_WAITING);
-        mUploadThread = new Thread(new BackgroundUploader(pathToUpload, mStreamsToUpload, mHandler));
-        mUploadThread.start();
-        
-        break;
-      case android.R.id.button1: // dynamic action for create aditional dir
-        showDialog(DIALOG_GET_DIRNAME);
-        break;
-      default:
-        throw new IllegalArgumentException("Wrong element clicked");
-    }
-  }
-
-  public void onUploadComplete(boolean uploadSucc, String message) {
-    dismissDialog(DIALOG_WAITING);
-    Log.i(TAG, "UploadSucc: " + uploadSucc + " message: " + message);
-    if (uploadSucc) {
-      Toast.makeText(this, getResources().getString(R.string.uploader_upload_succeed), Toast.LENGTH_SHORT).show();
-    } else {
-      Toast.makeText(this, getResources().getString(R.string.uploader_upload_failed) + message, Toast.LENGTH_LONG).show();
-    }
-    finish();
-  }
-  
-  @Override
-  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-    super.onActivityResult(requestCode, resultCode, data);
-    Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);
-    if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {
-      dismissDialog(DIALOG_NO_ACCOUNT);
-      if (resultCode == RESULT_CANCELED) {
-        finish();
-      }
-      Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);
-      if (accounts.length == 0) {
-        showDialog(DIALOG_NO_ACCOUNT);
-      } else {
-        // there is no need for checking for is there more then one account at this point
-        // since account setup can set only one account at time
-        mAccount = accounts[0];
-        populateDirectoryList();
-      }
-    }
-  }
-  
-  private void populateDirectoryList() {
-    mUsername = mAccount.name.substring(0, mAccount.name.indexOf('@'));
-    mPassword = mAccountManager.getPassword(mAccount);
-    setContentView(R.layout.uploader_layout);
-    mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI,
-                           null,
-                           ProviderTableMeta.FILE_CONTENT_TYPE+"=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                           new String[]{"DIR", mAccount.name},
-                           null);
-
-    ListView lv = getListView();
-    lv.setOnItemClickListener(this);
-    SimpleCursorAdapter sca = new SimpleCursorAdapter(this,
-                                                      R.layout.uploader_list_item_layout,
-                                                      mCursor,
-                                                      new String[]{ProviderTableMeta.FILE_NAME},
-                                                      new int[]{R.id.textView1});
-    setListAdapter(sca);
-    Button btn = (Button) findViewById(R.id.uploader_choose_folder);
-    btn.setOnClickListener(this);
-    // insert create new directory for multiple items uploading
-    if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
-      Button createDirBtn = new Button(this);
-      createDirBtn.setId(android.R.id.button1);
-      createDirBtn.setText(R.string.uploader_btn_create_dir_text);
-      createDirBtn.setOnClickListener(this);
-      ((LinearLayout)findViewById(R.id.linearLayout1)).addView(createDirBtn, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
-    }
-  }
-  
-  private void prepareStreamsToUpload() {
-    if (getIntent().getAction().equals(Intent.ACTION_SEND)) {
-      mStreamsToUpload = new ArrayList<Parcelable>();
-      mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
-    } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {
-      mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);
-    } else {
-      // unknow action inserted
-      throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());
-    }
-  }
-  
-  public void PartialupdateUpload(String fileLocalPath, String filename, String filepath, String contentType, String contentLength) {
-    ContentValues cv = new ContentValues();
-    cv.put(ProviderTableMeta.FILE_NAME, filename);
-    cv.put(ProviderTableMeta.FILE_PATH, filepath);
-    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, fileLocalPath);
-    cv.put(ProviderTableMeta.FILE_MODIFIED, WebdavUtils.DISPLAY_DATE_FORMAT.format(new java.util.Date()));
-    cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, contentType);
-    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, contentLength);
-    cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
-    Log.d(TAG, filename+" ++ "+filepath+" ++ " + contentLength + " ++ " + contentType + " ++ " + fileLocalPath);
-    if (!mParents.empty()) {
-      Cursor c = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),
-                              null,
-                              null,
-                              null,
-                              null);
-      c.moveToFirst();
-      cv.put(ProviderTableMeta.FILE_PARENT, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
-      c.close();
-    }
-    getContentResolver().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
-  }
-  
-  class BackgroundUploader implements Runnable {
-    private ArrayList<Parcelable> mUploadStreams;
-    private Handler mHandler;
-    private String mUploadPath;
-    private boolean mCreateDir;
-    
-    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
-        Handler handler) {
-      mUploadStreams = streamsToUpload;
-      mHandler = handler;
-      mUploadPath = pathToUpload.replace(" ", "%20");
-      mCreateDir = false;
-    }
-
-    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,
-                              Handler handler, boolean createDir) {
-      mUploadStreams = streamsToUpload;
-      mHandler = handler;
-      mUploadPath = pathToUpload.replace(" ", "%20");
-      mCreateDir = createDir;
-    }
-
-    public void run() {
-      WebdavClient wdc = new WebdavClient(Uri.parse(mAccountManager.getUserData(mAccount,
-          AccountAuthenticator.KEY_OC_URL)));
-      wdc.setCredentials(mUsername, mPassword);
-      wdc.allowUnsignedCertificates();
-
-      // create last directory in path if nessesary
-      if (mCreateDir) {
-        wdc.createDirectory(mUploadPath);
-      }
-      
-      for (int i = 0; i < mUploadStreams.size(); ++i) {
-        Uri uri = (Uri) mUploadStreams.get(i);
-        if (uri.getScheme().equals("content")) {
-          final Cursor c = getContentResolver().query((Uri) mUploadStreams.get(i), null, null, null, null);
-          c.moveToFirst();
-          
-          if (!wdc.putFile(c.getString(c.getColumnIndex(Media.DATA)),
-                           mUploadPath+"/"+c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),
-                           c.getString(c.getColumnIndex(Media.MIME_TYPE)))) {
-            mHandler.post(new Runnable() {
-              public void run() {
-                Uploader.this.onUploadComplete(false, "Error while uploading file: " + c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
-              }
-            });
-          }
-        } else if (uri.getScheme().equals("file")) {
-         final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme()+"://", ""));
-         FileNameMap fileNameMap = URLConnection.getFileNameMap();
-         String contentType = fileNameMap.getContentTypeFor(uri.toString());
-         if (contentType == null) {
-           contentType = "text/plain";
-         }
-         if (!wdc.putFile(file.getAbsolutePath(), mUploadPath+"/"+file.getName(), contentType)) {
-           mHandler.post(new Runnable() {
-             public void run() {
-               Uploader.this.onUploadComplete(false, "Error while uploading file: " + file.getName());
-             }
-           });
-         }
-        }
-        
-      }
-      mHandler.post(new Runnable() {
-        public void run() {
-          Uploader.this.onUploadComplete(true, null);
-        }
-      });
-    }
-
-  }
-  
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud;\r
+\r
+import java.io.File;\r
+import java.net.FileNameMap;\r
+import java.net.URI;\r
+import java.net.URLConnection;\r
+import java.util.ArrayList;\r
+import java.util.Stack;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.app.ListActivity;\r
+import android.app.ProgressDialog;\r
+import android.app.AlertDialog.Builder;\r
+import android.content.ContentValues;\r
+import android.content.Context;\r
+import android.content.DialogInterface;\r
+import android.content.Intent;\r
+import android.content.DialogInterface.OnCancelListener;\r
+import android.content.DialogInterface.OnClickListener;\r
+import android.database.Cursor;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.os.Parcelable;\r
+import android.provider.MediaStore.Images.Media;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.Window;\r
+import android.view.ViewGroup.LayoutParams;\r
+import android.widget.AdapterView;\r
+import android.widget.Button;\r
+import android.widget.EditText;\r
+import android.widget.LinearLayout;\r
+import android.widget.ListView;\r
+import android.widget.SimpleCursorAdapter;\r
+import android.widget.Toast;\r
+import android.widget.AdapterView.OnItemClickListener;\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
+import eu.alefzero.owncloud.db.ProviderMeta;\r
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
+import eu.alefzero.webdav.WebdavClient;\r
+import eu.alefzero.webdav.WebdavUtils;\r
+\r
+/**\r
+ * This can be used to upload things to an ownCloud instance.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class Uploader extends ListActivity implements OnItemClickListener, android.view.View.OnClickListener {\r
+  private static final String TAG = "ownCloudUploader";\r
+\r
+  private Account mAccount;\r
+  private AccountManager mAccountManager;\r
+  private String mUsername, mPassword;\r
+  private Cursor mCursor;\r
+  private Stack<String> mParents;\r
+  private Thread mUploadThread;\r
+  private Handler mHandler;\r
+  private ArrayList<Parcelable> mStreamsToUpload;\r
+\r
+  private final static int DIALOG_NO_ACCOUNT = 0;\r
+  private final static int DIALOG_WAITING = 1;\r
+  private final static int DIALOG_NO_STREAM = 2;\r
+  private final static int DIALOG_MULTIPLE_ACCOUNT = 3;\r
+  private final static int DIALOG_GET_DIRNAME = 4;\r
+\r
+  private final static int REQUEST_CODE_SETUP_ACCOUNT = 0;\r
+\r
+  @Override\r
+  protected void onCreate(Bundle savedInstanceState) {\r
+    super.onCreate(savedInstanceState);\r
+    getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+    mParents = new Stack<String>();\r
+    mHandler = new Handler();\r
+    if (getIntent().hasExtra(Intent.EXTRA_STREAM)) {\r
+      prepareStreamsToUpload();\r
+      mAccountManager = (AccountManager)getSystemService(Context.ACCOUNT_SERVICE);\r
+      Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
+      if (accounts.length == 0) {\r
+        Log.i(TAG, "No ownCloud account is available");\r
+        showDialog(DIALOG_NO_ACCOUNT);\r
+      } else if (accounts.length > 1) {\r
+        Log.i(TAG, "More then one ownCloud is available");\r
+        showDialog(DIALOG_MULTIPLE_ACCOUNT);\r
+      } else {\r
+        mAccount = accounts[0];\r
+        setContentView(R.layout.uploader_layout);\r
+        populateDirectoryList();\r
+      }\r
+    } else {\r
+      showDialog(DIALOG_NO_STREAM);\r
+    }\r
+  }\r
+\r
+  @Override\r
+  protected Dialog onCreateDialog(final int id) {\r
+    final AlertDialog.Builder builder = new Builder(this);\r
+    switch (id) {\r
+      case DIALOG_WAITING:\r
+        ProgressDialog pDialog = new ProgressDialog(this);\r
+        pDialog.setIndeterminate(false);\r
+        pDialog.setCancelable(false);\r
+        pDialog.setMessage(getResources().getString(R.string.uploader_info_uploading));\r
+        return pDialog;\r
+      case DIALOG_NO_ACCOUNT:\r
+        builder.setIcon(android.R.drawable.ic_dialog_alert);\r
+        builder.setTitle(R.string.uploader_wrn_no_account_title);\r
+        builder.setMessage(R.string.uploader_wrn_no_account_text);\r
+        builder.setCancelable(false);\r
+        builder.setPositiveButton(R.string.uploader_wrn_no_account_setup_btn_text, new OnClickListener() {\r
+          public void onClick(DialogInterface dialog, int which) {\r
+            if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ECLAIR_MR1) {\r
+              // using string value since in API7 this constatn is not defined\r
+              // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS\r
+              // and Settings.EXTRA_AUTHORITIES\r
+              Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+              intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});\r
+              startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);\r
+            } else {\r
+              // since in API7 there is no direct call for account setup, so we need to\r
+              // show our own AccountSetupAcricity, get desired results and setup\r
+              // everything for ourself\r
+              Intent intent = new Intent(getBaseContext(), AccountAuthenticator.class);\r
+              startActivityForResult(intent, REQUEST_CODE_SETUP_ACCOUNT);\r
+            }\r
+          }\r
+        });\r
+        builder.setNegativeButton(R.string.uploader_wrn_no_account_quit_btn_text, new OnClickListener() {\r
+          public void onClick(DialogInterface dialog, int which) {\r
+            finish();\r
+          }\r
+        });\r
+        return builder.create();\r
+      case DIALOG_GET_DIRNAME:\r
+        final EditText dirName = new EditText(getBaseContext());\r
+        builder.setView(dirName);\r
+        builder.setTitle(R.string.uploader_info_dirname);\r
+        String pathToUpload;\r
+        if (mParents.empty()) {\r
+          pathToUpload = "/";\r
+        } else {\r
+          mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), \r
+                                 null,\r
+                                 null,\r
+                                 null,\r
+                                 null);\r
+          mCursor.moveToFirst();\r
+          pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)) +\r
+                         mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");\r
+        }\r
+        a a = new a(pathToUpload, dirName);\r
+        builder.setPositiveButton(R.string.common_ok, a);\r
+        builder.setNegativeButton(R.string.common_cancel, new OnClickListener() {\r
+          public void onClick(DialogInterface dialog, int which) {\r
+            dialog.cancel();\r
+          }\r
+        });\r
+        return builder.create();\r
+      case DIALOG_MULTIPLE_ACCOUNT:\r
+        CharSequence ac[] = new CharSequence[mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];\r
+        for (int i = 0;  i < ac.length; ++i) {\r
+          ac[i] = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[i].name;\r
+        }\r
+        builder.setTitle(R.string.common_choose_account);\r
+        builder.setItems(ac, new OnClickListener() {\r
+          public void onClick(DialogInterface dialog, int which) {\r
+            mAccount = mAccountManager.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[which];\r
+            populateDirectoryList();\r
+          }\r
+        });\r
+        builder.setCancelable(true);\r
+        builder.setOnCancelListener(new OnCancelListener() {\r
+          public void onCancel(DialogInterface dialog) {\r
+            dialog.cancel();\r
+            finish();\r
+          }\r
+        });\r
+        return builder.create();\r
+      default:\r
+        throw new IllegalArgumentException("Unknown dialog id: " + id);\r
+    }\r
+  }\r
+  \r
+  class a implements OnClickListener {\r
+    String mPath;\r
+    EditText mDirname;\r
+    public a(String path, EditText dirname) {\r
+      mPath = path; mDirname = dirname;\r
+    }\r
+    public void onClick(DialogInterface dialog, int which) {\r
+      showDialog(DIALOG_WAITING);\r
+      mUploadThread = new Thread(new BackgroundUploader(mPath+mDirname.getText().toString(), mStreamsToUpload, mHandler, true));\r
+      mUploadThread.start();\r
+    }\r
+  }\r
+  \r
+  @Override\r
+  public void onBackPressed() {\r
+    \r
+    if (mParents.size()==0) {\r
+      super.onBackPressed();\r
+      return;\r
+    } else if (mParents.size() == 1) {\r
+      mParents.pop();\r
+      mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,\r
+          null,\r
+          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",\r
+          new String[]{"DIR"},\r
+          null);\r
+    } else {\r
+      mParents.pop();\r
+      mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),\r
+          null,\r
+          ProviderTableMeta.FILE_CONTENT_TYPE+"=?",\r
+          new String[]{"DIR"},\r
+          null);\r
+    }\r
+    \r
+    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,\r
+                                   mCursor,\r
+                                   new String[]{ProviderTableMeta.FILE_NAME},\r
+                                   new int[]{R.id.textView1});\r
+    setListAdapter(sca);\r
+  }\r
+  \r
+  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\r
+    if (!mCursor.moveToPosition(position)) {\r
+      throw new IndexOutOfBoundsException("Incorrect item selected");\r
+    }\r
+    String _id = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));\r
+    mParents.push(_id);\r
+    \r
+    mCursor.close();\r
+    mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, _id),\r
+                           null,\r
+                           ProviderTableMeta.FILE_CONTENT_TYPE+"=?",\r
+                           new String[]{"DIR"},\r
+                           null);\r
+    SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.uploader_list_item_layout,\r
+                                                      mCursor,\r
+                                                      new String[]{ProviderTableMeta.FILE_NAME},\r
+                                                      new int[]{R.id.textView1});\r
+    setListAdapter(sca);\r
+    getListView().invalidate();\r
+  }\r
+\r
+  public void onClick(View v) {\r
+    switch (v.getId()) {\r
+      case R.id.uploader_choose_folder:\r
+        String pathToUpload = null;\r
+        if (mParents.empty()) {\r
+          pathToUpload = "/";\r
+        } else {\r
+          mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()), \r
+                                 null,\r
+                                 null,\r
+                                 null,\r
+                                 null);\r
+          mCursor.moveToFirst();\r
+          pathToUpload = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH)) +\r
+                         mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)).replace(" ", "%20");\r
+        }\r
+        \r
+        showDialog(DIALOG_WAITING);\r
+        mUploadThread = new Thread(new BackgroundUploader(pathToUpload, mStreamsToUpload, mHandler));\r
+        mUploadThread.start();\r
+        \r
+        break;\r
+      case android.R.id.button1: // dynamic action for create aditional dir\r
+        showDialog(DIALOG_GET_DIRNAME);\r
+        break;\r
+      default:\r
+        throw new IllegalArgumentException("Wrong element clicked");\r
+    }\r
+  }\r
+\r
+  public void onUploadComplete(boolean uploadSucc, String message) {\r
+    dismissDialog(DIALOG_WAITING);\r
+    Log.i(TAG, "UploadSucc: " + uploadSucc + " message: " + message);\r
+    if (uploadSucc) {\r
+      Toast.makeText(this, getResources().getString(R.string.uploader_upload_succeed), Toast.LENGTH_SHORT).show();\r
+    } else {\r
+      Toast.makeText(this, getResources().getString(R.string.uploader_upload_failed) + message, Toast.LENGTH_LONG).show();\r
+    }\r
+    finish();\r
+  }\r
+  \r
+  @Override\r
+  protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+    super.onActivityResult(requestCode, resultCode, data);\r
+    Log.i(TAG, "result received. req: " + requestCode + " res: " + resultCode);\r
+    if (requestCode == REQUEST_CODE_SETUP_ACCOUNT) {\r
+      dismissDialog(DIALOG_NO_ACCOUNT);\r
+      if (resultCode == RESULT_CANCELED) {\r
+        finish();\r
+      }\r
+      Account[] accounts = mAccountManager.getAccountsByType(AccountAuthenticator.AUTH_TOKEN_TYPE);\r
+      if (accounts.length == 0) {\r
+        showDialog(DIALOG_NO_ACCOUNT);\r
+      } else {\r
+        // there is no need for checking for is there more then one account at this point\r
+        // since account setup can set only one account at time\r
+        mAccount = accounts[0];\r
+        populateDirectoryList();\r
+      }\r
+    }\r
+  }\r
+  \r
+  private void populateDirectoryList() {\r
+    mUsername = mAccount.name.substring(0, mAccount.name.indexOf('@'));\r
+    mPassword = mAccountManager.getPassword(mAccount);\r
+    setContentView(R.layout.uploader_layout);\r
+    mCursor = managedQuery(ProviderMeta.ProviderTableMeta.CONTENT_URI,\r
+                           null,\r
+                           ProviderTableMeta.FILE_CONTENT_TYPE+"=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
+                           new String[]{"DIR", mAccount.name},\r
+                           null);\r
+\r
+    ListView lv = getListView();\r
+    lv.setOnItemClickListener(this);\r
+    SimpleCursorAdapter sca = new SimpleCursorAdapter(this,\r
+                                                      R.layout.uploader_list_item_layout,\r
+                                                      mCursor,\r
+                                                      new String[]{ProviderTableMeta.FILE_NAME},\r
+                                                      new int[]{R.id.textView1});\r
+    setListAdapter(sca);\r
+    Button btn = (Button) findViewById(R.id.uploader_choose_folder);\r
+    btn.setOnClickListener(this);\r
+    // insert create new directory for multiple items uploading\r
+    if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {\r
+      Button createDirBtn = new Button(this);\r
+      createDirBtn.setId(android.R.id.button1);\r
+      createDirBtn.setText(R.string.uploader_btn_create_dir_text);\r
+      createDirBtn.setOnClickListener(this);\r
+      ((LinearLayout)findViewById(R.id.linearLayout1)).addView(createDirBtn, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);\r
+    }\r
+  }\r
+  \r
+  private void prepareStreamsToUpload() {\r
+    if (getIntent().getAction().equals(Intent.ACTION_SEND)) {\r
+      mStreamsToUpload = new ArrayList<Parcelable>();\r
+      mStreamsToUpload.add(getIntent().getParcelableExtra(Intent.EXTRA_STREAM));\r
+    } else if (getIntent().getAction().equals(Intent.ACTION_SEND_MULTIPLE)) {\r
+      mStreamsToUpload = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM);\r
+    } else {\r
+      // unknow action inserted\r
+      throw new IllegalArgumentException("Unknown action given: " + getIntent().getAction());\r
+    }\r
+  }\r
+  \r
+  public void PartialupdateUpload(String fileLocalPath, String filename, String filepath, String contentType, String contentLength) {\r
+    ContentValues cv = new ContentValues();\r
+    cv.put(ProviderTableMeta.FILE_NAME, filename);\r
+    cv.put(ProviderTableMeta.FILE_PATH, filepath);\r
+    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, fileLocalPath);\r
+    cv.put(ProviderTableMeta.FILE_MODIFIED, WebdavUtils.DISPLAY_DATE_FORMAT.format(new java.util.Date()));\r
+    cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, contentType);\r
+    cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, contentLength);\r
+    cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);\r
+    Log.d(TAG, filename+" ++ "+filepath+" ++ " + contentLength + " ++ " + contentType + " ++ " + fileLocalPath);\r
+    if (!mParents.empty()) {\r
+      Cursor c = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, mParents.peek()),\r
+                              null,\r
+                              null,\r
+                              null,\r
+                              null);\r
+      c.moveToFirst();\r
+      cv.put(ProviderTableMeta.FILE_PARENT, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));\r
+      c.close();\r
+    }\r
+    getContentResolver().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);\r
+  }\r
+  \r
+  class BackgroundUploader implements Runnable {\r
+    private ArrayList<Parcelable> mUploadStreams;\r
+    private Handler mHandler;\r
+    private String mUploadPath;\r
+    private boolean mCreateDir;\r
+    \r
+    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,\r
+        Handler handler) {\r
+      mUploadStreams = streamsToUpload;\r
+      mHandler = handler;\r
+      mUploadPath = pathToUpload.replace(" ", "%20");\r
+      mCreateDir = false;\r
+    }\r
+\r
+    public BackgroundUploader(String pathToUpload, ArrayList<Parcelable> streamsToUpload,\r
+                              Handler handler, boolean createDir) {\r
+      mUploadStreams = streamsToUpload;\r
+      mHandler = handler;\r
+      mUploadPath = pathToUpload.replace(" ", "%20");\r
+      mCreateDir = createDir;\r
+    }\r
+\r
+    public void run() {\r
+      WebdavClient wdc = new WebdavClient(Uri.parse(mAccountManager.getUserData(mAccount,\r
+          AccountAuthenticator.KEY_OC_URL)));\r
+      wdc.setCredentials(mUsername, mPassword);\r
+      wdc.allowUnsignedCertificates();\r
+\r
+      // create last directory in path if nessesary\r
+      if (mCreateDir) {\r
+        wdc.createDirectory(mUploadPath);\r
+      }\r
+      \r
+      for (int i = 0; i < mUploadStreams.size(); ++i) {\r
+        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
+                           c.getString(c.getColumnIndex(Media.MIME_TYPE)))) {\r
+            mHandler.post(new Runnable() {\r
+              public void run() {\r
+                Uploader.this.onUploadComplete(false, "Error while uploading file: " + c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));\r
+              }\r
+            });\r
+          }\r
+        } else if (uri.getScheme().equals("file")) {\r
+         final File file = new File(Uri.decode(uri.toString()).replace(uri.getScheme()+"://", ""));\r
+         FileNameMap fileNameMap = URLConnection.getFileNameMap();\r
+         String contentType = fileNameMap.getContentTypeFor(uri.toString());\r
+         if (contentType == null) {\r
+           contentType = "text/plain";\r
+         }\r
+         if (!wdc.putFile(file.getAbsolutePath(), mUploadPath+"/"+file.getName(), contentType)) {\r
+           mHandler.post(new Runnable() {\r
+             public void run() {\r
+               Uploader.this.onUploadComplete(false, "Error while uploading file: " + file.getName());\r
+             }\r
+           });\r
+         }\r
+        }\r
+        \r
+      }\r
+      mHandler.post(new Runnable() {\r
+        public void run() {\r
+          Uploader.this.onUploadComplete(true, null);\r
+        }\r
+      });\r
+    }\r
+\r
+  }\r
+  \r
+}\r
diff --git a/src/eu/alefzero/owncloud/WebdavClient.java b/src/eu/alefzero/owncloud/WebdavClient.java
deleted file mode 100644 (file)
index 8459803..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package eu.alefzero.owncloud;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.methods.HttpGet;
-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.entity.mime.content.FileBody;
-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 eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;
-import eu.alefzero.webdav.HttpMkCol;
-
-import android.net.Uri;
-import android.util.Log;
-
-public class WebdavClient {
-  private DefaultHttpClient mHttpClient;
-  private BasicHttpContext mHttpContext;
-  private HttpHost mTargetHost;
-  private SchemeRegistry mSchemeRegistry;
-  private Uri mUri;
-  final private static String TAG = "WebdavClient";
-  
-  WebdavClient(Uri uri) {
-    mUri = uri;
-    mSchemeRegistry = new SchemeRegistry();
-    setupHttpClient();
-  }
-  
-  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();
-
-    mHttpClient.getCredentialsProvider().setCredentials(
-        new AuthScope(mUri.getHost(), targetPort), 
-        new UsernamePasswordCredentials(username, password));
-    BasicScheme basicAuth = new BasicScheme();
-    mHttpContext.setAttribute("preemptive-auth", basicAuth);
-  }
-  
-  void allowUnsignedCertificates() {
-    // https
-    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
-  }
-  
-  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");
-    
-    try {
-      HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext);
-      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
-        return false;
-      }
-      BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
-      FileOutputStream fos = new FileOutputStream(targetPath);
-      
-      byte[] bytes = new byte[512];
-      int readResult;
-      while ((readResult = bis.read(bytes)) != -1) fos.write(bytes, 0, readResult);
-      
-    } catch (IOException e) {
-      e.printStackTrace();
-      return false;
-    }
-    return true;
-  }
-  
-  void getFileList(String dirPath) {
-    
-  }
-  
-  boolean putFile(String localFile,
-                  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 {
-      FileBody fb = new FileBody(new File(localFile, contentType));
-      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);
-
-      method.setEntity(fileEntity);
-      Log.i(TAG, "executing:" + method.getRequestLine().toString());
-
-      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());
-      result = false;
-    }
-    
-    return result;
-  }
-  
-  public boolean createDirectory(String path) {
-    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");
-    method.setHeader("User-Agent", "Android-ownCloud");
-    
-    try {
-      mHttpClient.execute(mTargetHost, method, mHttpContext);
-      Log.i(TAG, "Creating dir completed");
-    } catch (final Exception e) {
-      e.printStackTrace();
-      return false;
-    }
-    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 e4b118c..b688a2d 100644 (file)
-package eu.alefzero.owncloud.authenticator;
-
-import eu.alefzero.owncloud.ui.AuthenticatorActivity;
-import android.accounts.*;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-
-public class AccountAuthenticator extends AbstractAccountAuthenticator {
-    public static final String OPTIONS_USERNAME = "username";
-    public static final String OPTIONS_PASSWORD = "password";
-    public static final String OPTIONS_FILE_LIST_SYNC_ENABLED = "filelist";
-    public static final String OPTIONS_PINNED_FILE_SYNC_ENABLED = "pinned";
-
-    public static final String ACCOUNT_TYPE = "owncloud";
-    public static final String AUTH_TOKEN_TYPE = "org.owncloud";
-
-    public static final String KEY_AUTH_TOKEN_TYPE = "authTokenType";
-    public static final String KEY_REQUIRED_FEATURES = "requiredFeatures";
-    public static final String KEY_LOGIN_OPTIONS = "loginOptions";
-    public static final String KEY_ACCOUNT = "account";
-    public static final String KEY_OC_URL = "oc_url";
-    public static final String KEY_CONTACT_URL = "oc_contact_url";
-
-    private Context mContext;
-
-    public AccountAuthenticator(Context context) {
-        super(context);
-        mContext = context;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Bundle addAccount(AccountAuthenticatorResponse response,
-                             String accountType, String authTokenType, String[] requiredFeatures,
-                             Bundle options) throws NetworkErrorException {
-        Log.i(getClass().getName(), "Adding account with type " + accountType +
-                " and auth token " + authTokenType);
-        try {
-            validateAccountType(accountType);
-            //validateAuthTokenType(authTokenType);
-            validateRequiredFeatures(requiredFeatures);
-        } catch (AuthenticatorException e) {
-            e.printStackTrace();
-            return e.getFailureBundle();
-        }
-        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
-        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
-        intent.putExtra(KEY_REQUIRED_FEATURES, requiredFeatures);
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);
-
-        setIntentFlags(intent);
-        Log.i(getClass().getName(), intent.toString());
-        final Bundle bundle = new Bundle();
-        bundle.putParcelable(AccountManager.KEY_INTENT, intent);
-        return bundle;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Bundle confirmCredentials(AccountAuthenticatorResponse response,
-                                     Account account, Bundle options) throws NetworkErrorException {
-        try {
-            validateAccountType(account.type);
-        } catch (AuthenticatorException e) {
-            return e.getFailureBundle();
-        }
-        Intent intent = new Intent(mContext, AuthenticatorActivity.class);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
-        intent.putExtra(KEY_ACCOUNT, account);
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);
-
-        setIntentFlags(intent);
-
-        Bundle resultBundle = new Bundle();
-        resultBundle.putParcelable(AccountManager.KEY_INTENT, intent);
-        return resultBundle;
-    }
-
-    @Override
-    public Bundle editProperties(AccountAuthenticatorResponse response,
-                                 String accountType) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Bundle getAuthToken(AccountAuthenticatorResponse response,
-                               Account account, String authTokenType, Bundle options)
-            throws NetworkErrorException {
-        Log.i(getClass().getName(), "Getting authToken");
-        try {
-            validateAccountType(account.type);
-            validateAuthTokenType(authTokenType);
-        } catch (AuthenticatorException e) {
-            Log.w(getClass().getName(), "Validating failded in getAuthToken");
-            return e.getFailureBundle();
-        }
-        final AccountManager am = AccountManager.get(mContext);
-        final String password = am.getPassword(account);
-        if (password != null) {
-            final Bundle result = new Bundle();
-            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
-            result.putString(AccountManager.KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
-            result.putString(AccountManager.KEY_AUTHTOKEN, password);
-            return result;
-        }
-
-        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
-        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);
-        intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
-
-        final Bundle bundle = new Bundle();
-        bundle.putParcelable(AccountManager.KEY_INTENT, intent);
-        return bundle;
-    }
-
-    @Override
-    public String getAuthTokenLabel(String authTokenType) {
-        return null;
-    }
-
-    @Override
-    public Bundle hasFeatures(AccountAuthenticatorResponse response,
-                              Account account, String[] features) throws NetworkErrorException {
-        final Bundle result = new Bundle();
-        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
-        return result;
-    }
-
-    @Override
-    public Bundle updateCredentials(AccountAuthenticatorResponse response,
-                                    Account account, String authTokenType, Bundle options)
-            throws NetworkErrorException {
-        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
-        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
-        intent.putExtra(KEY_ACCOUNT, account);
-        intent.putExtra(KEY_AUTH_TOKEN_TYPE, authTokenType);
-        intent.putExtra(KEY_LOGIN_OPTIONS, options);
-        setIntentFlags(intent);
-
-        final Bundle bundle = new Bundle();
-        bundle.putParcelable(AccountManager.KEY_INTENT, intent);
-        return bundle;
-    }
-
-    @Override
-    public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response,
-                                           Account account) throws NetworkErrorException {
-        return super.getAccountRemovalAllowed(response, account);
-    }
-
-    private void setIntentFlags(Intent intent) {
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
-        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
-    }
-
-    private void validateAccountType(String type) throws UnsupportedAccountTypeException {
-        if (!type.equals(ACCOUNT_TYPE)) {
-            throw new UnsupportedAccountTypeException();
-        }
-    }
-
-    private void validateAuthTokenType(String authTokenType) throws UnsupportedAuthTokenTypeException {
-        if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {
-            throw new UnsupportedAuthTokenTypeException();
-        }
-    }
-
-    private void validateRequiredFeatures(String[] requiredFeatures) throws UnsupportedFeaturesException {
-        // TODO
-    }
-
-    private void validateCreaditials(String username, String password, String path) throws AccessDeniedException {
-
-    }
-
-    public static class AuthenticatorException extends Exception {
-        private static final long serialVersionUID = 1L;
-        private Bundle mFailureBundle;
-
-        public AuthenticatorException(int code, String errorMsg) {
-            mFailureBundle = new Bundle();
-            mFailureBundle.putInt(AccountManager.KEY_ERROR_CODE, code);
-            mFailureBundle.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
-        }
-
-        public Bundle getFailureBundle() {
-            return mFailureBundle;
-        }
-    }
-
-    public static class UnsupportedAccountTypeException extends AuthenticatorException {
-        private static final long serialVersionUID = 1L;
-
-        public UnsupportedAccountTypeException() {
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported account type");
-        }
-    }
-
-    public static class UnsupportedAuthTokenTypeException extends AuthenticatorException {
-        private static final long serialVersionUID = 1L;
-
-        public UnsupportedAuthTokenTypeException() {
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported auth token type");
-        }
-    }
-
-    public static class UnsupportedFeaturesException extends AuthenticatorException {
-        public static final long serialVersionUID = 1L;
-
-        public UnsupportedFeaturesException() {
-            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported features");
-        }
-    }
-
-    public static class AccessDeniedException extends AuthenticatorException {
-        public AccessDeniedException(int code, String errorMsg) {
-            super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");
-        }
-
-        private static final long serialVersionUID = 1L;
-
-    }
-}
+package eu.alefzero.owncloud.authenticator;\r
+\r
+import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;\r
+import android.accounts.*;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+\r
+public class AccountAuthenticator extends AbstractAccountAuthenticator {\r
+    public static final String OPTIONS_USERNAME = "username";\r
+    public static final String OPTIONS_PASSWORD = "password";\r
+    public static final String OPTIONS_FILE_LIST_SYNC_ENABLED = "filelist";\r
+    public static final String OPTIONS_PINNED_FILE_SYNC_ENABLED = "pinned";\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
+\r
+    @Override\r
+    public String getAuthTokenLabel(String authTokenType) {\r
+        return null;\r
+    }\r
+\r
+    @Override\r
+    public Bundle hasFeatures(AccountAuthenticatorResponse response,\r
+                              Account account, String[] features) throws NetworkErrorException {\r
+        final Bundle result = new Bundle();\r
+        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public Bundle updateCredentials(AccountAuthenticatorResponse response,\r
+                                    Account account, String authTokenType, Bundle options)\r
+            throws NetworkErrorException {\r
+        final Intent intent = new Intent(mContext, AuthenticatorActivity.class);\r
+        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, 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) throws UnsupportedAccountTypeException {\r
+        if (!type.equals(ACCOUNT_TYPE)) {\r
+            throw new UnsupportedAccountTypeException();\r
+        }\r
+    }\r
+\r
+    private void validateAuthTokenType(String authTokenType) throws UnsupportedAuthTokenTypeException {\r
+        if (!authTokenType.equals(AUTH_TOKEN_TYPE)) {\r
+            throw new UnsupportedAuthTokenTypeException();\r
+        }\r
+    }\r
+\r
+    private void validateRequiredFeatures(String[] requiredFeatures) throws UnsupportedFeaturesException {\r
+        // TODO\r
+    }\r
+\r
+    private void validateCreaditials(String username, String password, String path) throws AccessDeniedException {\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
+\r
+        public Bundle getFailureBundle() {\r
+            return mFailureBundle;\r
+        }\r
+    }\r
+\r
+    public static class UnsupportedAccountTypeException extends AuthenticatorException {\r
+        private static final long serialVersionUID = 1L;\r
+\r
+        public UnsupportedAccountTypeException() {\r
+            super(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION, "Unsupported account type");\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
+    }\r
+\r
+    public static class AccessDeniedException extends AuthenticatorException {\r
+        public AccessDeniedException(int code, String errorMsg) {\r
+            super(AccountManager.ERROR_CODE_INVALID_RESPONSE, "Access Denied");\r
+        }\r
+\r
+        private static final long serialVersionUID = 1L;\r
+\r
+    }\r
+}\r
index e444824..7e6c813 100644 (file)
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package eu.alefzero.owncloud.authenticator;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.UnrecoverableKeyException;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import javax.security.cert.CertificateException;
-import javax.security.cert.X509Certificate;
-
-import org.apache.http.client.HttpClient;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-
-import org.apache.http.impl.client.DefaultHttpClient;
-
-import org.apache.commons.httpclient.auth.BasicScheme;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpVersion;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.methods.HttpHead;
-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.ssl.SSLSocketFactory;
-import org.apache.http.impl.conn.SingleClientConnManager;
-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 eu.alefzero.owncloud.ui.AuthenticatorActivity;
-
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.Log;
-
-public class AuthUtils {
-  public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
-  public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
-  public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";
-  
-  private static String mResultMsg = "";
-  
-  public static boolean authenticate(URL url, String username, String password,
-                                     Handler handler, Context context) {
-    String strippedPath = url.toString().endsWith("/") ?
-                          url.toString().substring(0, url.toString().length()-1) :
-                          url.toString();
-    String webdatPath = strippedPath + WEBDAV_PATH_2_0;
-    URL complete_url = null;
-    try {
-      complete_url = new URL(webdatPath);
-    } catch (MalformedURLException e) {
-      // should never happend
-      sendResult(false, handler, context, "URL error");
-      return false;
-    }
-    
-    // version 2.0 success
-    if (tryGetWebdav(complete_url, username, password, handler, context)) {
-      sendResult(true, handler, context, complete_url.toString());
-      return true;
-    }
-    
-    if (mResultMsg.equals("401")) {
-       sendResult(false, handler, context, "Invalid login or/and password");
-       return false;
-    }
-    
-    if (!mResultMsg.equals("404")) {
-      sendResult(false, handler, context, "Server error: " + mResultMsg);
-      return false;
-    }
-    
-    webdatPath = strippedPath + WEBDAV_PATH_1_2;
-    try {
-      complete_url = new URL(webdatPath);
-    } catch (MalformedURLException e) {
-      // should never happend
-      sendResult(false, handler, context, "URL error");
-      return false;
-    }
-    
-    // version 1.2 success
-    if (tryGetWebdav(complete_url, username, password, handler, context)) {
-      sendResult(true, handler, context, complete_url.toString());
-      return true;
-    }
-    
-    if (mResultMsg.equals("401")) {
-      sendResult(false, handler, context, "Invalid login or/and password");
-      return false;
-    }
-    
-    if (mResultMsg.equals("404")) {
-      sendResult(false, handler, context, "Wrong path given");
-      return false;
-    }
-    
-    sendResult(false, handler, context, "Server error: " + mResultMsg);
-    return false;
-  }
-  
-  public static boolean tryGetWebdav(URL url, String username, String pwd,
-                                     Handler handler, Context context) {
-    SchemeRegistry schemeRegistry = new SchemeRegistry();
- // http scheme
- schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
- // https scheme
- schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 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);
-
- ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
-    
-    DefaultHttpClient c = new DefaultHttpClient(cm, params);
-    
-    c.getCredentialsProvider().setCredentials(
-        new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()), 
-        new UsernamePasswordCredentials(username, pwd));
-    
-    BasicHttpContext localcontext  = new BasicHttpContext();
-    BasicScheme basicAuth = new BasicScheme();
-
-    localcontext.setAttribute("preemptive-auth", basicAuth);
-    HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)
-        ? 80
-        : url.getPort(), (url.getProtocol().equals("https")) ? "https" : "http");
-    HttpHead httpget = new HttpHead(url.toString());
-    httpget.setHeader("Host", url.getHost());
-    HttpResponse response = null;
-    try {
-      response = c.execute(targetHost, httpget, localcontext);
-    } catch (ClientProtocolException e1) {
-      sendResult(false, handler, context, "Protocol error: "
-          + e1.getLocalizedMessage());
-      return false;
-    } catch (UnknownHostException e1) {
-      mResultMsg = "Unknowh host: " + e1.getLocalizedMessage();
-      return false;
-    } catch (IOException e1) {
-      mResultMsg = "Error: " + e1.getLocalizedMessage();
-      return false;
-    }
-    String status = response.getStatusLine().toString();
-
-    status = status.split(" ")[1];
-    Log.i("AuthUtils", "Status returned: " + status);
-    if (status.equals("200")) {
-      return true;
-    } else if (status.equals("404")) {
-      mResultMsg = "404";
-      return false;
-    } else if (status.equals("401")) {
-      mResultMsg = "401";
-      return false;
-    }
-    mResultMsg = status;
-    return false;
-  }
-  
-  public static Thread performOnBackgroundThread(final Runnable r) {
-    final Thread t = new Thread() {
-      @Override
-      public void run() {
-        try {
-          r.run();
-        } finally {}
-      }
-    };
-    t.start();
-    return t;
-  }
-  
-  public static void sendResult(final Boolean result,
-                                final Handler handler,
-                                final Context context,
-                                final String message) {
-    if (handler == null || context == null) {
-      return;
-    }
-    handler.post(new Runnable() {
-      public void run() {
-        ((AuthenticatorActivity) context).onAuthenticationResult(result, message); 
-      }
-    });
-  }
-  
-  public static Thread attemptAuth(final URL url, final String username,
-                                   final String password, final Handler handler,
-                                   final Context context) {
-    final Runnable r = new Runnable() {
-      
-      public void run() {
-        authenticate(url, username, password, handler, context);
-      }
-    };
-    return performOnBackgroundThread(r);
-  }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package eu.alefzero.owncloud.authenticator;\r
+\r
+import java.io.IOException;\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+import java.net.UnknownHostException;\r
+import java.security.KeyManagementException;\r
+import java.security.KeyStore;\r
+import java.security.KeyStoreException;\r
+import java.security.NoSuchAlgorithmException;\r
+import java.security.SecureRandom;\r
+import java.security.UnrecoverableKeyException;\r
+\r
+import javax.net.SocketFactory;\r
+import javax.net.ssl.HostnameVerifier;\r
+import javax.net.ssl.HttpsURLConnection;\r
+import javax.net.ssl.SSLContext;\r
+import javax.net.ssl.SSLSession;\r
+import javax.net.ssl.TrustManager;\r
+import javax.net.ssl.X509TrustManager;\r
+\r
+import javax.security.cert.CertificateException;\r
+import javax.security.cert.X509Certificate;\r
+\r
+import org.apache.http.client.HttpClient;\r
+import org.apache.http.conn.ClientConnectionManager;\r
+import org.apache.http.conn.scheme.Scheme;\r
+import org.apache.http.conn.scheme.SchemeRegistry;\r
+\r
+import org.apache.http.impl.client.DefaultHttpClient;\r
+\r
+import org.apache.commons.httpclient.auth.BasicScheme;\r
+import org.apache.http.HttpHost;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.HttpVersion;\r
+import org.apache.http.auth.AuthScope;\r
+import org.apache.http.auth.UsernamePasswordCredentials;\r
+import org.apache.http.client.ClientProtocolException;\r
+import org.apache.http.client.methods.HttpHead;\r
+import org.apache.http.conn.params.ConnManagerPNames;\r
+import org.apache.http.conn.params.ConnPerRouteBean;\r
+import org.apache.http.conn.scheme.PlainSocketFactory;\r
+import org.apache.http.conn.ssl.SSLSocketFactory;\r
+import org.apache.http.impl.conn.SingleClientConnManager;\r
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;\r
+import org.apache.http.params.BasicHttpParams;\r
+import org.apache.http.params.HttpParams;\r
+import org.apache.http.params.HttpProtocolParams;\r
+import org.apache.http.protocol.BasicHttpContext;\r
+\r
+import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;\r
+\r
+\r
+import android.content.Context;\r
+import android.os.Handler;\r
+import android.util.Log;\r
+\r
+public class AuthUtils {\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 CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";\r
+  \r
+  private static String mResultMsg = "";\r
+  \r
+  public static boolean authenticate(URL url, String username, String password,\r
+                                     Handler handler, Context context) {\r
+    String strippedPath = url.toString().endsWith("/") ?\r
+                          url.toString().substring(0, url.toString().length()-1) :\r
+                          url.toString();\r
+    String webdatPath = strippedPath + WEBDAV_PATH_2_0;\r
+    URL complete_url = null;\r
+    try {\r
+      complete_url = new URL(webdatPath);\r
+    } catch (MalformedURLException e) {\r
+      // should never happend\r
+      sendResult(false, handler, context, "URL error");\r
+      return false;\r
+    }\r
+    \r
+    // version 2.0 success\r
+    if (tryGetWebdav(complete_url, username, password, handler, context)) {\r
+      sendResult(true, handler, context, complete_url.toString());\r
+      return true;\r
+    }\r
+    \r
+    if (mResultMsg.equals("401")) {\r
+       sendResult(false, handler, context, "Invalid login or/and password");\r
+       return false;\r
+    }\r
+    \r
+    if (!mResultMsg.equals("404")) {\r
+      sendResult(false, handler, context, "Server error: " + mResultMsg);\r
+      return false;\r
+    }\r
+    \r
+    webdatPath = strippedPath + WEBDAV_PATH_1_2;\r
+    try {\r
+      complete_url = new URL(webdatPath);\r
+    } catch (MalformedURLException e) {\r
+      // should never happend\r
+      sendResult(false, handler, context, "URL error");\r
+      return false;\r
+    }\r
+    \r
+    // version 1.2 success\r
+    if (tryGetWebdav(complete_url, username, password, handler, context)) {\r
+      sendResult(true, handler, context, complete_url.toString());\r
+      return true;\r
+    }\r
+    \r
+    if (mResultMsg.equals("401")) {\r
+      sendResult(false, handler, context, "Invalid login or/and password");\r
+      return false;\r
+    }\r
+    \r
+    if (mResultMsg.equals("404")) {\r
+      sendResult(false, handler, context, "Wrong path given");\r
+      return false;\r
+    }\r
+    \r
+    sendResult(false, handler, context, "Server error: " + mResultMsg);\r
+    return false;\r
+  }\r
+  \r
+  public static boolean tryGetWebdav(URL url, String username, String pwd,\r
+                                     Handler handler, Context context) {\r
+    SchemeRegistry schemeRegistry = new SchemeRegistry();\r
+ // http scheme\r
+ schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));\r
+ // https scheme\r
+ schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));\r
+\r
+ HttpParams params = new BasicHttpParams();\r
+ params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);\r
+ params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));\r
+ params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);\r
+ HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);\r
+\r
+ ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);\r
+    \r
+    DefaultHttpClient c = new DefaultHttpClient(cm, params);\r
+    \r
+    c.getCredentialsProvider().setCredentials(\r
+        new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()), \r
+        new UsernamePasswordCredentials(username, pwd));\r
+    \r
+    BasicHttpContext localcontext  = new BasicHttpContext();\r
+    BasicScheme basicAuth = new BasicScheme();\r
+\r
+    localcontext.setAttribute("preemptive-auth", basicAuth);\r
+    HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)\r
+        ? 80\r
+        : url.getPort(), (url.getProtocol().equals("https")) ? "https" : "http");\r
+    HttpHead httpget = new HttpHead(url.toString());\r
+    httpget.setHeader("Host", url.getHost());\r
+    HttpResponse response = null;\r
+    try {\r
+      response = c.execute(targetHost, httpget, localcontext);\r
+    } catch (ClientProtocolException e1) {\r
+      sendResult(false, handler, context, "Protocol error: "\r
+          + e1.getLocalizedMessage());\r
+      return false;\r
+    } catch (UnknownHostException e1) {\r
+      mResultMsg = "Unknowh host: " + e1.getLocalizedMessage();\r
+      return false;\r
+    } catch (IOException e1) {\r
+      mResultMsg = "Error: " + e1.getLocalizedMessage();\r
+      return false;\r
+    }\r
+    String status = response.getStatusLine().toString();\r
+\r
+    status = status.split(" ")[1];\r
+    Log.i("AuthUtils", "Status returned: " + status);\r
+    if (status.equals("200")) {\r
+      return true;\r
+    } else if (status.equals("404")) {\r
+      mResultMsg = "404";\r
+      return false;\r
+    } else if (status.equals("401")) {\r
+      mResultMsg = "401";\r
+      return false;\r
+    }\r
+    mResultMsg = status;\r
+    return false;\r
+  }\r
+  \r
+  public static Thread performOnBackgroundThread(final Runnable r) {\r
+    final Thread t = new Thread() {\r
+      @Override\r
+      public void run() {\r
+        try {\r
+          r.run();\r
+        } finally {}\r
+      }\r
+    };\r
+    t.start();\r
+    return t;\r
+  }\r
+  \r
+  public static void sendResult(final Boolean result,\r
+                                final Handler handler,\r
+                                final Context context,\r
+                                final String message) {\r
+    if (handler == null || context == null) {\r
+      return;\r
+    }\r
+    handler.post(new Runnable() {\r
+      public void run() {\r
+        ((AuthenticatorActivity) context).onAuthenticationResult(result, message); \r
+      }\r
+    });\r
+  }\r
+  \r
+  public static Thread attemptAuth(final URL url, final String username,\r
+                                   final String password, final Handler handler,\r
+                                   final Context context) {\r
+    final Runnable r = new Runnable() {\r
+      \r
+      public void run() {\r
+        authenticate(url, username, password, handler, context);\r
+      }\r
+    };\r
+    return performOnBackgroundThread(r);\r
+  }\r
+}\r
index bb66bfc..e443601 100644 (file)
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package eu.alefzero.owncloud;
-
-import java.util.HashMap;
-
-import eu.alefzero.owncloud.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-
-import android.content.ContentProvider;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.UriMatcher;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.text.TextUtils;
-
-public class cp extends ContentProvider {
-
-  private DataBaseHelper mDbHelper;
-  
-  private static HashMap<String, String> mProjectionMap;
-  static {
-    mProjectionMap = new HashMap<String, String>();
-    mProjectionMap.put(ProviderTableMeta._ID,
-                       ProviderTableMeta._ID);
-    mProjectionMap.put(ProviderTableMeta.FILE_PARENT,
-                       ProviderTableMeta.FILE_PARENT);
-    mProjectionMap.put(ProviderTableMeta.FILE_PATH,
-                       ProviderTableMeta.FILE_PATH);
-    mProjectionMap.put(ProviderTableMeta.FILE_NAME,
-                       ProviderTableMeta.FILE_NAME);
-    mProjectionMap.put(ProviderTableMeta.FILE_CREATION,
-                       ProviderTableMeta.FILE_CREATION);
-    mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,
-                       ProviderTableMeta.FILE_MODIFIED);
-    mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,
-                       ProviderTableMeta.FILE_CONTENT_LENGTH);
-    mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,
-                       ProviderTableMeta.FILE_CONTENT_TYPE);
-    mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,
-                       ProviderTableMeta.FILE_STORAGE_PATH);
-  }
-  
-  private static final int SINGLE_FILE = 1;
-  private static final int DIRECTORY = 2;
-  private static final int ROOT_DIRECTORY = 3;
-  private static final UriMatcher mUriMatcher;
-  static {
-    mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);
-    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);
-    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);
-    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);
-  }
-  
-  private static final String TAG = "OC_ContentProvider";
-  
-  @Override
-  public int delete(Uri uri, String where, String[] whereArgs) {
-    SQLiteDatabase db = mDbHelper.getWritableDatabase();
-    int count = 0;
-    switch (mUriMatcher.match(uri)) {
-      case SINGLE_FILE:
-        count = db.delete(ProviderTableMeta.DB_NAME,
-                          ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1)
-                          + (!TextUtils.isEmpty(where)?" AND (" + where +")" : ""),
-                          whereArgs);
-        break;
-      case ROOT_DIRECTORY:
-        count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);
-        break;
-      default:
-        throw new IllegalArgumentException("Unknown uri: " + uri.toString());
-    }
-    getContext().getContentResolver().notifyChange(uri, null);
-    return count;
-  }
-
-  @Override
-  public String getType(Uri uri) {
-    switch (mUriMatcher.match(uri)) {
-      case ROOT_DIRECTORY:
-        return ProviderTableMeta.CONTENT_TYPE;
-      case SINGLE_FILE:
-        return ProviderTableMeta.CONTENT_TYPE_ITEM;
-      default:
-        throw new IllegalArgumentException("Unknown Uri id." + uri.toString());
-    }
-  }
-
-  @Override
-  public Uri insert(Uri uri, ContentValues values) {
-    if (mUriMatcher.match(uri) != SINGLE_FILE) {
-      throw new IllegalArgumentException("Unknown uri id: " + uri);
-    }
-    
-    SQLiteDatabase db = mDbHelper.getWritableDatabase();
-    long rowId = db.insert(ProviderTableMeta.DB_NAME, ProviderTableMeta.FILE_NAME, values);
-    if (rowId > 0) {
-      Uri insertedFileUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId);
-      getContext().getContentResolver().notifyChange(insertedFileUri, null);
-      return insertedFileUri;
-    }
-    throw new SQLException("ERROR " + uri);
-  }
-
-  @Override
-  public boolean onCreate() {
-    mDbHelper = new DataBaseHelper(getContext());
-    return true;
-  }
-
-  @Override
-  public Cursor query(Uri uri, String[] projection, String selection,
-      String[] selectionArgs, String sortOrder) {
-    SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();
-        
-    sqlQuery.setTables(ProviderTableMeta.DB_NAME);
-    sqlQuery.setProjectionMap(mProjectionMap);
-    
-    switch (mUriMatcher.match(uri)) {
-      case ROOT_DIRECTORY:
-        sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + " is null");
-        break;
-      case DIRECTORY:
-        sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="+uri.getPathSegments().get(1));
-        break;
-      case SINGLE_FILE:
-        if (uri.getPathSegments().size() > 1) {
-          sqlQuery.appendWhere(ProviderTableMeta._ID + "=" +
-                               uri.getPathSegments().get(1));
-        }
-        break;
-      default:
-        throw new IllegalArgumentException("Unknown uri id: " + uri);
-    }
-    
-    String order;
-    if (TextUtils.isEmpty(sortOrder)) {
-      order = ProviderTableMeta.DEFAULT_SORT_ORDER;
-    } else {
-      order = sortOrder;
-    }
-    
-    SQLiteDatabase db = mDbHelper.getReadableDatabase();
-    Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);
-    
-    c.setNotificationUri(getContext().getContentResolver(), uri);
-
-    return c;
-  }
-
-  @Override
-  public int update(Uri uri, ContentValues values, String selection,
-      String[] selectionArgs) {
-    return mDbHelper.getWritableDatabase().update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);
-  }
-
-  class DataBaseHelper extends SQLiteOpenHelper {
-
-    public DataBaseHelper(Context context) {
-      super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);
-      
-    }
-    
-    @Override
-    public void onCreate(SQLiteDatabase db) {
-      db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "(" +
-                 ProviderTableMeta._ID + " INTEGER PRIMARY KEY, " +
-                 ProviderTableMeta.FILE_NAME + " TEXT, " +
-                 ProviderTableMeta.FILE_PATH + " TEXT, " +
-                 ProviderTableMeta.FILE_PARENT + " INTEGER, " +
-                 ProviderTableMeta.FILE_CREATION + " INTEGER, " +
-                 ProviderTableMeta.FILE_MODIFIED + " INTEGER, " +
-                 ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, " +
-                 ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, " +
-                 ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, " +
-                 ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT);");
-    }
-
-    @Override
-    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-      
-    }
-    
-  }
-  
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package eu.alefzero.owncloud;\r
+\r
+import java.util.HashMap;\r
+\r
+import eu.alefzero.owncloud.db.ProviderMeta;\r
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
+\r
+import android.content.ContentProvider;\r
+import android.content.ContentUris;\r
+import android.content.ContentValues;\r
+import android.content.Context;\r
+import android.content.UriMatcher;\r
+import android.database.Cursor;\r
+import android.database.SQLException;\r
+import android.database.sqlite.SQLiteDatabase;\r
+import android.database.sqlite.SQLiteOpenHelper;\r
+import android.database.sqlite.SQLiteQueryBuilder;\r
+import android.net.Uri;\r
+import android.text.TextUtils;\r
+\r
+/**\r
+* The ContentProvider for the ownCloud App.\r
+* @author Bartek Przybylski\r
+* \r
+*/\r
+public class cp extends ContentProvider {\r
+\r
+  private DataBaseHelper mDbHelper;\r
+  \r
+  private static HashMap<String, String> mProjectionMap;\r
+  static {\r
+    mProjectionMap = new HashMap<String, String>();\r
+    mProjectionMap.put(ProviderTableMeta._ID,\r
+                       ProviderTableMeta._ID);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_PARENT,\r
+                       ProviderTableMeta.FILE_PARENT);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_PATH,\r
+                       ProviderTableMeta.FILE_PATH);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_NAME,\r
+                       ProviderTableMeta.FILE_NAME);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_CREATION,\r
+                       ProviderTableMeta.FILE_CREATION);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_MODIFIED,\r
+                       ProviderTableMeta.FILE_MODIFIED);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_LENGTH,\r
+                       ProviderTableMeta.FILE_CONTENT_LENGTH);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_CONTENT_TYPE,\r
+                       ProviderTableMeta.FILE_CONTENT_TYPE);\r
+    mProjectionMap.put(ProviderTableMeta.FILE_STORAGE_PATH,\r
+                       ProviderTableMeta.FILE_STORAGE_PATH);\r
+  }\r
+  \r
+  private static final int SINGLE_FILE = 1;\r
+  private static final int DIRECTORY = 2;\r
+  private static final int ROOT_DIRECTORY = 3;\r
+  private static final UriMatcher mUriMatcher;\r
+  static {\r
+    mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);\r
+    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "/", ROOT_DIRECTORY);\r
+    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/", SINGLE_FILE);\r
+    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "file/#", SINGLE_FILE);\r
+    mUriMatcher.addURI(ProviderMeta.AUTHORITY_FILES, "dir/#", DIRECTORY);\r
+  }\r
+  \r
+  private static final String TAG = "OC_ContentProvider";\r
+  \r
+  @Override\r
+  public int delete(Uri uri, String where, String[] whereArgs) {\r
+    SQLiteDatabase db = mDbHelper.getWritableDatabase();\r
+    int count = 0;\r
+    switch (mUriMatcher.match(uri)) {\r
+      case SINGLE_FILE:\r
+        count = db.delete(ProviderTableMeta.DB_NAME,\r
+                          ProviderTableMeta._ID + "=" + uri.getPathSegments().get(1)\r
+                          + (!TextUtils.isEmpty(where)?" AND (" + where +")" : ""),\r
+                          whereArgs);\r
+        break;\r
+      case ROOT_DIRECTORY:\r
+        count = db.delete(ProviderTableMeta.DB_NAME, where, whereArgs);\r
+        break;\r
+      default:\r
+        throw new IllegalArgumentException("Unknown uri: " + uri.toString());\r
+    }\r
+    getContext().getContentResolver().notifyChange(uri, null);\r
+    return count;\r
+  }\r
+\r
+  @Override\r
+  public String getType(Uri uri) {\r
+    switch (mUriMatcher.match(uri)) {\r
+      case ROOT_DIRECTORY:\r
+        return ProviderTableMeta.CONTENT_TYPE;\r
+      case SINGLE_FILE:\r
+        return ProviderTableMeta.CONTENT_TYPE_ITEM;\r
+      default:\r
+        throw new IllegalArgumentException("Unknown Uri id." + uri.toString());\r
+    }\r
+  }\r
+\r
+  @Override\r
+  public Uri insert(Uri uri, ContentValues values) {\r
+    if (mUriMatcher.match(uri) != SINGLE_FILE) {\r
+      throw new IllegalArgumentException("Unknown uri id: " + uri);\r
+    }\r
+    \r
+    SQLiteDatabase db = mDbHelper.getWritableDatabase();\r
+    long rowId = db.insert(ProviderTableMeta.DB_NAME, ProviderTableMeta.FILE_NAME, values);\r
+    if (rowId > 0) {\r
+      Uri insertedFileUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, rowId);\r
+      getContext().getContentResolver().notifyChange(insertedFileUri, null);\r
+      return insertedFileUri;\r
+    }\r
+    throw new SQLException("ERROR " + uri);\r
+  }\r
+\r
+  @Override\r
+  public boolean onCreate() {\r
+    mDbHelper = new DataBaseHelper(getContext());\r
+    return true;\r
+  }\r
+\r
+  @Override\r
+  public Cursor query(Uri uri, String[] projection, String selection,\r
+      String[] selectionArgs, String sortOrder) {\r
+    SQLiteQueryBuilder sqlQuery = new SQLiteQueryBuilder();\r
+        \r
+    sqlQuery.setTables(ProviderTableMeta.DB_NAME);\r
+    sqlQuery.setProjectionMap(mProjectionMap);\r
+    \r
+    switch (mUriMatcher.match(uri)) {\r
+      case ROOT_DIRECTORY:\r
+        sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + " is null");\r
+        break;\r
+      case DIRECTORY:\r
+        sqlQuery.appendWhere(ProviderTableMeta.FILE_PARENT + "="+uri.getPathSegments().get(1));\r
+        break;\r
+      case SINGLE_FILE:\r
+        if (uri.getPathSegments().size() > 1) {\r
+          sqlQuery.appendWhere(ProviderTableMeta._ID + "=" +\r
+                               uri.getPathSegments().get(1));\r
+        }\r
+        break;\r
+      default:\r
+        throw new IllegalArgumentException("Unknown uri id: " + uri);\r
+    }\r
+    \r
+    String order;\r
+    if (TextUtils.isEmpty(sortOrder)) {\r
+      order = ProviderTableMeta.DEFAULT_SORT_ORDER;\r
+    } else {\r
+      order = sortOrder;\r
+    }\r
+    \r
+    SQLiteDatabase db = mDbHelper.getReadableDatabase();\r
+    Cursor c = sqlQuery.query(db, projection, selection, selectionArgs, null, null, order);\r
+    \r
+    c.setNotificationUri(getContext().getContentResolver(), uri);\r
+\r
+    return c;\r
+  }\r
+\r
+  @Override\r
+  public int update(Uri uri, ContentValues values, String selection,\r
+      String[] selectionArgs) {\r
+    return mDbHelper.getWritableDatabase().update(ProviderTableMeta.DB_NAME, values, selection, selectionArgs);\r
+  }\r
+\r
+  class DataBaseHelper extends SQLiteOpenHelper {\r
+\r
+    public DataBaseHelper(Context context) {\r
+      super(context, ProviderMeta.DB_NAME, null, ProviderMeta.DB_VERSION);\r
+      \r
+    }\r
+    \r
+    @Override\r
+    public void onCreate(SQLiteDatabase db) {\r
+      db.execSQL("CREATE TABLE " + ProviderTableMeta.DB_NAME + "(" +\r
+                 ProviderTableMeta._ID + " INTEGER PRIMARY KEY, " +\r
+                 ProviderTableMeta.FILE_NAME + " TEXT, " +\r
+                 ProviderTableMeta.FILE_PATH + " TEXT, " +\r
+                 ProviderTableMeta.FILE_PARENT + " INTEGER, " +\r
+                 ProviderTableMeta.FILE_CREATION + " INTEGER, " +\r
+                 ProviderTableMeta.FILE_MODIFIED + " INTEGER, " +\r
+                 ProviderTableMeta.FILE_CONTENT_TYPE + " TEXT, " +\r
+                 ProviderTableMeta.FILE_CONTENT_LENGTH + " INTEGER, " +\r
+                 ProviderTableMeta.FILE_STORAGE_PATH + " TEXT, " +\r
+                 ProviderTableMeta.FILE_ACCOUNT_OWNER + " TEXT);");\r
+    }\r
+\r
+    @Override\r
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
+      \r
+    }\r
+    \r
+  }\r
+  \r
+}\r
diff --git a/src/eu/alefzero/owncloud/db/DbHandler.java b/src/eu/alefzero/owncloud/db/DbHandler.java
new file mode 100644 (file)
index 0000000..d2e0b11
--- /dev/null
@@ -0,0 +1,103 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.db;\r
+\r
+import java.util.Vector;\r
+\r
+import eu.alefzero.owncloud.OwnCloudSession;\r
+\r
+import android.content.ContentValues;\r
+import android.content.Context;\r
+import android.database.Cursor;\r
+import android.database.sqlite.SQLiteDatabase;\r
+import android.database.sqlite.SQLiteOpenHelper;\r
+import android.util.Log;\r
+\r
+/**\r
+ * Custom database helper for ownCloud\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class DbHandler {\r
+  private SQLiteDatabase mDB;\r
+  private OpenerHepler mHelper;\r
+  private final String mDatabaseName = "ownCloud";\r
+  private final String TABLE_SESSIONS = "sessions";\r
+  private final int mDatabaseVersion = 1;\r
+  \r
+  public DbHandler(Context context) {\r
+    mHelper = new OpenerHepler(context);\r
+    mDB = mHelper.getWritableDatabase();\r
+  }\r
+  \r
+  public Vector<OwnCloudSession> getSessionList() {\r
+    Cursor c = mDB.query(TABLE_SESSIONS, null, null, null, null, null, null);\r
+    Vector<OwnCloudSession> v = new Vector<OwnCloudSession>();\r
+    if (!c.moveToFirst()) {\r
+      return v;\r
+    }\r
+    while (!c.isAfterLast()) {\r
+      v.add(new OwnCloudSession(c.getString(c.getColumnIndex("sessionName")),\r
+                                c.getString(c.getColumnIndex("sessionUrl")),\r
+                                c.getInt(c.getColumnIndex("_id"))));\r
+      c.moveToNext();\r
+    }\r
+    c.close();\r
+    return v;\r
+  }\r
+  \r
+  public void addSession(String sessionName, String uri) {\r
+    ContentValues cv = new ContentValues();\r
+    cv.put("sessionName", sessionName);\r
+    cv.put("sessionUrl", uri);\r
+    mDB.insert(TABLE_SESSIONS, null, cv);\r
+  }\r
+  \r
+  public void removeSessionWithId(int sessionId) {\r
+    mDB.delete(TABLE_SESSIONS, "_id = ?", new String[] {String.valueOf(sessionId)});\r
+  }\r
+\r
+  public void changeSessionFields(int id, String hostname, String uri) {\r
+    ContentValues cv = new ContentValues();\r
+    cv.put("sessionName", hostname);\r
+    cv.put("sessionUrl", uri);\r
+    mDB.update(TABLE_SESSIONS, cv, "_id = ?", new String[] {String.valueOf(id)});\r
+  }\r
+  \r
+  public void close() {\r
+    mDB.close();\r
+  }\r
+  \r
+  private class OpenerHepler extends SQLiteOpenHelper {\r
+    public OpenerHepler(Context context) {\r
+      super(context, mDatabaseName, null, mDatabaseVersion);\r
+    }\r
+\r
+    @Override\r
+    public void onCreate(SQLiteDatabase db) {\r
+      db.execSQL("CREATE TABLE " + TABLE_SESSIONS + " (" +\r
+                 " _id INTEGER PRIMARY KEY, " +\r
+                 " sessionName TEXT, " +\r
+                 " sessionUrl  TEXT);");\r
+    }\r
+\r
+    @Override\r
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\r
+    }\r
+  }\r
+}\r
index d5d86ca..591edaf 100644 (file)
@@ -1,59 +1,64 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-package eu.alefzero.owncloud.db;
-
-import android.net.Uri;
-import android.provider.BaseColumns;
-
-public class ProviderMeta {
-
-  public static final String AUTHORITY_FILES = "org.owncloud";
-  public static final String DB_FILE = "owncloud.db";
-  public static final String DB_NAME = "filelist";
-  public static final int DB_VERSION = 1;
-  
-  private ProviderMeta() { }
-  
-  static public class ProviderTableMeta implements BaseColumns {
-    public static final String DB_NAME = "filelist";
-    public static final Uri CONTENT_URI =  
-      Uri.parse("content://" + AUTHORITY_FILES + "/");
-    public static final Uri CONTENT_URI_FILE =
-      Uri.parse("content://" + AUTHORITY_FILES + "/file");
-    public static final Uri CONTENT_URI_DIR =
-      Uri.parse("content://" + AUTHORITY_FILES + "/dir");
-
-    public static final String CONTENT_TYPE =
-      "vnd.android.cursor.dir/vnd.owncloud.file";
-    public static final String CONTENT_TYPE_ITEM =
-      "vnd.android.cursor.item/vnd.owncloud.file";
-    
-    public static final String FILE_PARENT = "parent";
-    public static final String FILE_NAME = "filename";
-    public static final String FILE_CREATION = "created";
-    public static final String FILE_MODIFIED = "modified";
-    public static final String FILE_CONTENT_LENGTH = "content_length";
-    public static final String FILE_CONTENT_TYPE = "content_type";
-    public static final String FILE_STORAGE_PATH = "media_path";
-    public static final String FILE_PATH = "path";
-    public static final String FILE_ACCOUNT_OWNER = "file_owner";
-    
-    public static final String DEFAULT_SORT_ORDER = FILE_NAME + " asc";
-
-  }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.db;\r
+\r
+import android.net.Uri;\r
+import android.provider.BaseColumns;\r
+\r
+/**\r
+ * Meta-Class that holds various static field information\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class ProviderMeta {\r
+\r
+  public static final String AUTHORITY_FILES = "org.owncloud";\r
+  public static final String DB_FILE = "owncloud.db";\r
+  public static final String DB_NAME = "filelist";\r
+  public static final int DB_VERSION = 1;\r
+  \r
+  private ProviderMeta() { }\r
+  \r
+  static public class ProviderTableMeta implements BaseColumns {\r
+    public static final String DB_NAME = "filelist";\r
+    public static final Uri CONTENT_URI =  \r
+      Uri.parse("content://" + AUTHORITY_FILES + "/");\r
+    public static final Uri CONTENT_URI_FILE =\r
+      Uri.parse("content://" + AUTHORITY_FILES + "/file");\r
+    public static final Uri CONTENT_URI_DIR =\r
+      Uri.parse("content://" + AUTHORITY_FILES + "/dir");\r
+\r
+    public static final String CONTENT_TYPE =\r
+      "vnd.android.cursor.dir/vnd.owncloud.file";\r
+    public static final String CONTENT_TYPE_ITEM =\r
+      "vnd.android.cursor.item/vnd.owncloud.file";\r
+    \r
+    public static final String FILE_PARENT = "parent";\r
+    public static final String FILE_NAME = "filename";\r
+    public static final String FILE_CREATION = "created";\r
+    public static final String FILE_MODIFIED = "modified";\r
+    public static final String FILE_CONTENT_LENGTH = "content_length";\r
+    public static final String FILE_CONTENT_TYPE = "content_type";\r
+    public static final String FILE_STORAGE_PATH = "media_path";\r
+    public static final String FILE_PATH = "path";\r
+    public static final String FILE_ACCOUNT_OWNER = "file_owner";\r
+    \r
+    public static final String DEFAULT_SORT_ORDER = FILE_NAME + " asc";\r
+\r
+  }\r
+}\r
index 524904f..3c1caf9 100644 (file)
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-import java.util.Date;
-import java.util.LinkedList;
-
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.conn.ConnectionKeepAliveStrategy;
-import org.apache.http.impl.auth.BasicScheme;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.protocol.BasicHttpContext;
-import org.apache.http.protocol.HttpContext;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.AbstractThreadedSyncAdapter;
-import android.content.ContentProviderClient;
-import android.content.Context;
-import android.net.Uri;
-import android.text.TextUtils;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.webdav.HttpPropFind;
-import eu.alefzero.webdav.TreeNode;
-import eu.alefzero.webdav.TreeNode.NodeProperty;
-import eu.alefzero.webdav.WebdavUtils;
-
-/**
- * Base SyncAdapter for OwnCloud
- * Designed to be subclassed for the concreete SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..
- * 
- * @author sassman
- *
- */
-public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {
-
-       private AccountManager accountManager;
-       private Account account;
-       private ContentProviderClient contentProvider;
-       private Date lastUpdated;
-       
-       private DefaultHttpClient client = null;
-       private HttpHost host;
-
-       public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {
-               super(context, autoInitialize);
-               this.setAccountManager(AccountManager.get(context));
-       }
-
-       public AccountManager getAccountManager() {
-               return accountManager;
-       }
-
-       public void setAccountManager(AccountManager accountManager) {
-               this.accountManager = accountManager;
-       }
-
-       public Account getAccount() {
-               return account;
-       }
-
-       public void setAccount(Account account) {
-               this.account = account;
-       }
-
-       public ContentProviderClient getContentProvider() {
-               return contentProvider;
-       }
-
-       public void setContentProvider(ContentProviderClient contentProvider) {
-               this.contentProvider = contentProvider;
-       }
-
-       public Date getLastUpdated() {
-               return lastUpdated;
-       }
-
-       public void setLastUpdated(Date lastUpdated) {
-               this.lastUpdated = lastUpdated;
-       }
-       
-       protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {
-               return new ConnectionKeepAliveStrategy() {
-                       public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
-                               // TODO: change keep alive straategy basing on response: ie forbidden/not found/etc
-                               // should have keep alive 0
-                               // default return: 5s
-                               return 5 * 1000;
-                       }
-               };
-       }
-       
-       protected HttpPropFind getPropFindQuery() throws OperationCanceledException, AuthenticatorException, IOException {
-               HttpPropFind query = new HttpPropFind(getUri().toString());
-               query.setHeader("Content-type", "text/xml");
-               query.setHeader("User-Agent", "Android-ownCloud");
-               return query;
-       }
-       
-       protected HttpResponse fireRawRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {
-           BasicHttpContext httpContext = new BasicHttpContext();
-        BasicScheme basicAuth = new BasicScheme();
-        httpContext.setAttribute("preemptive-auth", basicAuth);
-        
-        HttpResponse response = getClient().execute(this.host, query, httpContext);
-        return response;
-       }
-       
-       protected TreeNode fireRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {
-               HttpResponse response = fireRawRequest(query);
-               
-               TreeNode root = new TreeNode();
-               root.setProperty(TreeNode.NodeProperty.NAME, "/");
-               this.parseResponse(response, getUri(), getClient(), this.host, root.getChildList());
-               return root;
-       }
-       
-       protected Uri getUri() {
-               return Uri.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL));
-       }
-       
-       private DefaultHttpClient getClient() throws OperationCanceledException, AuthenticatorException, IOException {
-               if(this.client == null) {
-                       String username = getAccount().name.split("@")[0];
-                       String password = this.getAccountManager().blockingGetAuthToken(getAccount(), AccountAuthenticator.AUTH_TOKEN_TYPE, true);
-                       if (this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL) == null) {
-                               throw new UnknownHostException();
-                       }
-                       Uri uri = getUri();
-       
-                       int port = (uri.getPort() == -1) ? 80 : uri.getPort();
-                       this.client = new DefaultHttpClient();
-                       this.client.getCredentialsProvider().setCredentials(
-                               new AuthScope(uri.getHost(), port),
-                               new UsernamePasswordCredentials(username, password)
-                       );
-                       this.client.setKeepAliveStrategy(this.getKeepAliveStrategy());
-                       this.host = new HttpHost(uri.getHost(), port, (uri.getScheme() == "https") ? "https" : "http");
-               }
-               
-               return this.client;
-       }
-       
-       private void parseResponse(HttpResponse resp, Uri uri, DefaultHttpClient client, HttpHost targetHost, LinkedList<TreeNode> insertList) throws IOException, OperationCanceledException, AuthenticatorException {
-               boolean skipFirst = true;
-               for (TreeNode n :WebdavUtils.parseResponseToNodes(resp.getEntity().getContent())) {
-                       String path = n.stripPathFromFilename(uri.getPath());
-                       if (skipFirst) {
-                               skipFirst = false;
-                               continue;
-                       }
-                       insertList.add(n);
-
-                       if (!TextUtils.isEmpty(n.getProperty(NodeProperty.NAME)) &&
-                                       n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {
-                           
-                           HttpPropFind method = new HttpPropFind(uri.getPath() + path + n.getProperty(NodeProperty.NAME).replace(" ", "%20") + "/");
-                               HttpResponse response = fireRawRequest(method);
-                               parseResponse(response, uri, client, targetHost, n.getChildList());
-                       }
-               }
-       }
-       
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.syncadapter;\r
+\r
+import java.io.IOException;\r
+import java.net.UnknownHostException;\r
+import java.util.Date;\r
+import java.util.LinkedList;\r
+\r
+import org.apache.http.HttpHost;\r
+import org.apache.http.HttpRequest;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.auth.AuthScope;\r
+import org.apache.http.auth.UsernamePasswordCredentials;\r
+import org.apache.http.client.ClientProtocolException;\r
+import org.apache.http.conn.ConnectionKeepAliveStrategy;\r
+import org.apache.http.impl.auth.BasicScheme;\r
+import org.apache.http.impl.client.DefaultHttpClient;\r
+import org.apache.http.protocol.BasicHttpContext;\r
+import org.apache.http.protocol.HttpContext;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.accounts.AuthenticatorException;\r
+import android.accounts.OperationCanceledException;\r
+import android.content.AbstractThreadedSyncAdapter;\r
+import android.content.ContentProviderClient;\r
+import android.content.Context;\r
+import android.net.Uri;\r
+import android.text.TextUtils;\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
+import eu.alefzero.webdav.HttpPropFind;\r
+import eu.alefzero.webdav.TreeNode;\r
+import eu.alefzero.webdav.TreeNode.NodeProperty;\r
+import eu.alefzero.webdav.WebdavUtils;\r
+\r
+/**\r
+ * Base SyncAdapter for OwnCloud\r
+ * Designed to be subclassed for the concreete SyncAdapter, like ConcatsSync, CalendarSync, FileSync etc..\r
+ * \r
+ * @author sassman\r
+ *\r
+ */\r
+public abstract class AbstractOwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {\r
+\r
+       private AccountManager accountManager;\r
+       private Account account;\r
+       private ContentProviderClient contentProvider;\r
+       private Date lastUpdated;\r
+       \r
+       private DefaultHttpClient client = null;\r
+       private HttpHost host;\r
+\r
+       public AbstractOwnCloudSyncAdapter(Context context, boolean autoInitialize) {\r
+               super(context, autoInitialize);\r
+               this.setAccountManager(AccountManager.get(context));\r
+       }\r
+\r
+       public AccountManager getAccountManager() {\r
+               return accountManager;\r
+       }\r
+\r
+       public void setAccountManager(AccountManager accountManager) {\r
+               this.accountManager = accountManager;\r
+       }\r
+\r
+       public Account getAccount() {\r
+               return account;\r
+       }\r
+\r
+       public void setAccount(Account account) {\r
+               this.account = account;\r
+       }\r
+\r
+       public ContentProviderClient getContentProvider() {\r
+               return contentProvider;\r
+       }\r
+\r
+       public void setContentProvider(ContentProviderClient contentProvider) {\r
+               this.contentProvider = contentProvider;\r
+       }\r
+\r
+       public Date getLastUpdated() {\r
+               return lastUpdated;\r
+       }\r
+\r
+       public void setLastUpdated(Date lastUpdated) {\r
+               this.lastUpdated = lastUpdated;\r
+       }\r
+       \r
+       protected ConnectionKeepAliveStrategy getKeepAliveStrategy() {\r
+               return new ConnectionKeepAliveStrategy() {\r
+                       public long getKeepAliveDuration(HttpResponse response, HttpContext context) {\r
+                               // TODO: change keep alive straategy basing on response: ie forbidden/not found/etc\r
+                               // should have keep alive 0\r
+                               // default return: 5s\r
+                               return 5 * 1000;\r
+                       }\r
+               };\r
+       }\r
+       \r
+       protected HttpPropFind getPropFindQuery() throws OperationCanceledException, AuthenticatorException, 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) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {\r
+           BasicHttpContext httpContext = new BasicHttpContext();\r
+        BasicScheme basicAuth = new BasicScheme();\r
+        httpContext.setAttribute("preemptive-auth", basicAuth);\r
+        \r
+        HttpResponse response = getClient().execute(this.host, query, httpContext);\r
+        return response;\r
+       }\r
+       \r
+       protected TreeNode fireRequest(HttpRequest query) throws ClientProtocolException, OperationCanceledException, AuthenticatorException, IOException {\r
+               HttpResponse response = fireRawRequest(query);\r
+               \r
+               TreeNode root = new TreeNode();\r
+               root.setProperty(TreeNode.NodeProperty.NAME, "/");\r
+               this.parseResponse(response, getUri(), getClient(), this.host, root.getChildList());\r
+               return root;\r
+       }\r
+       \r
+       protected Uri getUri() {\r
+               return Uri.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL));\r
+       }\r
+       \r
+       private DefaultHttpClient getClient() throws OperationCanceledException, AuthenticatorException, IOException {\r
+               if(this.client == null) {\r
+                       String username = getAccount().name.split("@")[0];\r
+                       String password = this.getAccountManager().blockingGetAuthToken(getAccount(), AccountAuthenticator.AUTH_TOKEN_TYPE, true);\r
+                       if (this.getAccountManager().getUserData(getAccount(), AccountAuthenticator.KEY_OC_URL) == null) {\r
+                               throw new UnknownHostException();\r
+                       }\r
+                       Uri uri = getUri();\r
+       \r
+                       int port = (uri.getPort() == -1) ? 80 : uri.getPort();\r
+                       this.client = new DefaultHttpClient();\r
+                       this.client.getCredentialsProvider().setCredentials(\r
+                               new AuthScope(uri.getHost(), port),\r
+                               new UsernamePasswordCredentials(username, password)\r
+                       );\r
+                       this.client.setKeepAliveStrategy(this.getKeepAliveStrategy());\r
+                       this.host = new HttpHost(uri.getHost(), port, (uri.getScheme() == "https") ? "https" : "http");\r
+               }\r
+               \r
+               return this.client;\r
+       }\r
+       \r
+       private void parseResponse(HttpResponse resp, Uri uri, DefaultHttpClient client, HttpHost targetHost, LinkedList<TreeNode> insertList) throws IOException, OperationCanceledException, AuthenticatorException {\r
+               boolean skipFirst = true;\r
+               for (TreeNode n :WebdavUtils.parseResponseToNodes(resp.getEntity().getContent())) {\r
+                       String path = n.stripPathFromFilename(uri.getPath());\r
+                       if (skipFirst) {\r
+                               skipFirst = false;\r
+                               continue;\r
+                       }\r
+                       insertList.add(n);\r
+\r
+                       if (!TextUtils.isEmpty(n.getProperty(NodeProperty.NAME)) &&\r
+                                       n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {\r
+                           \r
+                           HttpPropFind method = new HttpPropFind(uri.getPath() + path + n.getProperty(NodeProperty.NAME).replace(" ", "%20") + "/");\r
+                               HttpResponse response = fireRawRequest(method);\r
+                               parseResponse(response, uri, client, targetHost, n.getChildList());\r
+                       }\r
+               }\r
+       }\r
+       \r
 }
\ No newline at end of file
 }
\ No newline at end of file
index bf00240..ef9da41 100644 (file)
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package eu.alefzero.owncloud.syncadapter;
-
-import java.io.IOException;
-
-import org.apache.http.entity.StringEntity;
-
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.content.ContentProviderClient;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.SyncResult;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.util.Log;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-import eu.alefzero.webdav.HttpPropFind;
-import eu.alefzero.webdav.TreeNode;
-import eu.alefzero.webdav.TreeNode.NodeProperty;
-import eu.alefzero.webdav.WebdavUtils;
-
-/**
- * SyncAdapter implementation for syncing sample SyncAdapter contacts to the
- * platform ContactOperations provider.
- */
-public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {
-       private static final String TAG = "FileSyncAdapter";
-
-       public FileSyncAdapter(Context context, boolean autoInitialize) {
-               super(context, autoInitialize);
-       }
-
-       @Override
-       public synchronized void onPerformSync(
-                       Account account, 
-                       Bundle extras, 
-                       String authority, 
-                       ContentProviderClient provider, 
-                       SyncResult syncResult) {
-
-               try {
-                       this.setAccount(account);
-                       this.setContentProvider(provider);
-
-                       HttpPropFind query = this.getPropFindQuery();
-                       query.setEntity(new StringEntity(WebdavUtils.prepareXmlForPropFind()));
-                       TreeNode root = this.fireRequest(query);
-
-                       commitToDatabase(root, null);
-               } catch (OperationCanceledException e) {
-                       e.printStackTrace();
-               } catch (AuthenticatorException e) {
-                       syncResult.stats.numAuthExceptions++;
-                       e.printStackTrace();
-               } catch (IOException e) {
-                       syncResult.stats.numIoExceptions++;
-                       e.printStackTrace();
-               } catch (RemoteException e) {
-                       e.printStackTrace();
-               }
-       }
-
-       private void commitToDatabase(TreeNode root, String parentId) throws RemoteException {
-               for (TreeNode n : root.getChildList()) {
-                       Log.d(TAG, n.toString());
-                       ContentValues cv = new ContentValues();
-                       cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, n.getProperty(NodeProperty.CONTENT_LENGTH));
-                       cv.put(ProviderTableMeta.FILE_MODIFIED, n.getProperty(NodeProperty.LAST_MODIFIED_DATE));
-                       cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, n.getProperty(NodeProperty.RESOURCE_TYPE));
-                       cv.put(ProviderTableMeta.FILE_PARENT, parentId);
-
-                       String name = n.getProperty(NodeProperty.NAME),
-                                       path = n.getProperty(NodeProperty.PATH);
-                       Cursor c = this.getContentProvider().query(ProviderTableMeta.CONTENT_URI_FILE,
-                                       null,
-                                       ProviderTableMeta.FILE_NAME+"=? AND " + ProviderTableMeta.FILE_PATH + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
-                                       new String[]{name, path, this.getAccount().name},
-                                       null);
-                       if (c.moveToFirst()) {
-                               this.getContentProvider().update(ProviderTableMeta.CONTENT_URI,
-                                               cv,
-                                               ProviderTableMeta._ID+"=?",
-                                                               new String[]{c.getString(c.getColumnIndex(ProviderTableMeta._ID))});
-                               Log.d(TAG, "ID of: "+name+":"+c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
-                       } else {
-                               cv.put(ProviderTableMeta.FILE_NAME, n.getProperty(NodeProperty.NAME));
-                               cv.put(ProviderTableMeta.FILE_PATH, n.getProperty(NodeProperty.PATH));
-                               cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, this.getAccount().name);
-                               Uri entry = this.getContentProvider().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);
-                               Log.d(TAG, "Inserting new entry " + path + name);
-                               c = this.getContentProvider().query(entry, null, null, null, null);
-                               c.moveToFirst();
-                       }
-                       if (n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {
-                               commitToDatabase(n, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));
-                       }
-               }
-               // clean removed files
-               String[] selection = new String[root.getChildList().size()+2];
-               selection[0] = this.getAccount().name;
-               selection[1] = parentId;
-               String qm = "";
-               for (int i = 2; i < selection.length-1; ++i) {
-                       qm += "?,";
-                       selection[i] = root.getChildList().get(i-2).getProperty(NodeProperty.NAME);
-               }
-               if (selection.length >= 3) {
-                       selection[selection.length-1] = root.getChildrenNames()[selection.length-3];
-                       qm += "?";
-               }
-               for (int i = 0; i < selection.length; ++i) {
-                       Log.d(TAG,selection[i]+"");
-               }
-               Log.d(TAG,"Removing files "+ parentId);
-               this.getContentProvider().delete(ProviderTableMeta.CONTENT_URI,
-                               ProviderTableMeta.FILE_ACCOUNT_OWNER+"=? AND " + ProviderTableMeta.FILE_PARENT + (parentId==null?" IS ":"=")+"? AND " + ProviderTableMeta.FILE_NAME + " NOT IN ("+qm+")",
-                               selection);
-       }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package eu.alefzero.owncloud.syncadapter;\r
+\r
+import java.io.IOException;\r
+\r
+import org.apache.http.entity.StringEntity;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AuthenticatorException;\r
+import android.accounts.OperationCanceledException;\r
+import android.content.ContentProviderClient;\r
+import android.content.ContentValues;\r
+import android.content.Context;\r
+import android.content.SyncResult;\r
+import android.database.Cursor;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.RemoteException;\r
+import android.util.Log;\r
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
+import eu.alefzero.webdav.HttpPropFind;\r
+import eu.alefzero.webdav.TreeNode;\r
+import eu.alefzero.webdav.TreeNode.NodeProperty;\r
+import eu.alefzero.webdav.WebdavUtils;\r
+\r
+/**\r
+ * SyncAdapter implementation for syncing sample SyncAdapter contacts to the\r
+ * platform ContactOperations provider.\r
+ * \r
+ * @author Bartek Przybylski\r
+ */\r
+public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter {\r
+       private static final String TAG = "FileSyncAdapter";\r
+\r
+       public FileSyncAdapter(Context context, boolean autoInitialize) {\r
+               super(context, autoInitialize);\r
+       }\r
+\r
+       @Override\r
+       public synchronized void onPerformSync(\r
+                       Account account, \r
+                       Bundle extras, \r
+                       String authority, \r
+                       ContentProviderClient provider, \r
+                       SyncResult syncResult) {\r
+\r
+               try {\r
+                       this.setAccount(account);\r
+                       this.setContentProvider(provider);\r
+\r
+                       HttpPropFind query = this.getPropFindQuery();\r
+                       query.setEntity(new StringEntity(WebdavUtils.prepareXmlForPropFind()));\r
+                       TreeNode root = this.fireRequest(query);\r
+\r
+                       commitToDatabase(root, null);\r
+               } catch (OperationCanceledException e) {\r
+                       e.printStackTrace();\r
+               } catch (AuthenticatorException e) {\r
+                       syncResult.stats.numAuthExceptions++;\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {\r
+                       syncResult.stats.numIoExceptions++;\r
+                       e.printStackTrace();\r
+               } catch (RemoteException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+\r
+       private void commitToDatabase(TreeNode root, String parentId) throws RemoteException {\r
+               for (TreeNode n : root.getChildList()) {\r
+                       Log.d(TAG, n.toString());\r
+                       ContentValues cv = new ContentValues();\r
+                       cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, n.getProperty(NodeProperty.CONTENT_LENGTH));\r
+                       cv.put(ProviderTableMeta.FILE_MODIFIED, n.getProperty(NodeProperty.LAST_MODIFIED_DATE));\r
+                       cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, n.getProperty(NodeProperty.RESOURCE_TYPE));\r
+                       cv.put(ProviderTableMeta.FILE_PARENT, parentId);\r
+\r
+                       String name = n.getProperty(NodeProperty.NAME),\r
+                                       path = n.getProperty(NodeProperty.PATH);\r
+                       Cursor c = this.getContentProvider().query(ProviderTableMeta.CONTENT_URI_FILE,\r
+                                       null,\r
+                                       ProviderTableMeta.FILE_NAME+"=? AND " + ProviderTableMeta.FILE_PATH + "=? AND " + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
+                                       new String[]{name, path, this.getAccount().name},\r
+                                       null);\r
+                       if (c.moveToFirst()) {\r
+                               this.getContentProvider().update(ProviderTableMeta.CONTENT_URI,\r
+                                               cv,\r
+                                               ProviderTableMeta._ID+"=?",\r
+                                                               new String[]{c.getString(c.getColumnIndex(ProviderTableMeta._ID))});\r
+                               Log.d(TAG, "ID of: "+name+":"+c.getString(c.getColumnIndex(ProviderTableMeta._ID)));\r
+                       } else {\r
+                               cv.put(ProviderTableMeta.FILE_NAME, n.getProperty(NodeProperty.NAME));\r
+                               cv.put(ProviderTableMeta.FILE_PATH, n.getProperty(NodeProperty.PATH));\r
+                               cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, this.getAccount().name);\r
+                               Uri entry = this.getContentProvider().insert(ProviderTableMeta.CONTENT_URI_FILE, cv);\r
+                               Log.d(TAG, "Inserting new entry " + path + name);\r
+                               c = this.getContentProvider().query(entry, null, null, null, null);\r
+                               c.moveToFirst();\r
+                       }\r
+                       if (n.getProperty(NodeProperty.RESOURCE_TYPE).equals("DIR")) {\r
+                               commitToDatabase(n, c.getString(c.getColumnIndex(ProviderTableMeta._ID)));\r
+                       }\r
+               }\r
+               // clean removed files\r
+               String[] selection = new String[root.getChildList().size()+2];\r
+               selection[0] = this.getAccount().name;\r
+               selection[1] = parentId;\r
+               String qm = "";\r
+               for (int i = 2; i < selection.length-1; ++i) {\r
+                       qm += "?,";\r
+                       selection[i] = root.getChildList().get(i-2).getProperty(NodeProperty.NAME);\r
+               }\r
+               if (selection.length >= 3) {\r
+                       selection[selection.length-1] = root.getChildrenNames()[selection.length-3];\r
+                       qm += "?";\r
+               }\r
+               for (int i = 0; i < selection.length; ++i) {\r
+                       Log.d(TAG,selection[i]+"");\r
+               }\r
+               Log.d(TAG,"Removing files "+ parentId);\r
+               this.getContentProvider().delete(ProviderTableMeta.CONTENT_URI,\r
+                               ProviderTableMeta.FILE_ACCOUNT_OWNER+"=? AND " + ProviderTableMeta.FILE_PARENT + (parentId==null?" IS ":"=")+"? AND " + ProviderTableMeta.FILE_NAME + " NOT IN ("+qm+")",\r
+                               selection);\r
+       }\r
+}\r
index fa8a354..ed8480e 100644 (file)
@@ -1,31 +1,53 @@
-
-package eu.alefzero.owncloud.syncadapter;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class FileSyncService extends Service {
-    private static final Object syncAdapterLock = new Object();
-    private static AbstractOwnCloudSyncAdapter concretSyncAdapter = null;
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public void onCreate() {
-        synchronized (syncAdapterLock) {
-            if (concretSyncAdapter == null) {
-                concretSyncAdapter = new FileSyncAdapter(getApplicationContext(), true);
-            }
-        }
-    }
-
-    /*
-     * {@inheritDoc}
-     */
-    @Override
-    public IBinder onBind(Intent intent) {
-        return concretSyncAdapter.getSyncAdapterBinder();
-    }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.syncadapter;\r
+\r
+import android.app.Service;\r
+import android.content.Intent;\r
+import android.os.IBinder;\r
+\r
+/**\r
+ * Background service for syncing files to our\r
+ * local Database\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class FileSyncService extends Service {\r
+    private static final Object syncAdapterLock = new Object();\r
+    private static AbstractOwnCloudSyncAdapter concretSyncAdapter = null;\r
+\r
+    /*\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void onCreate() {\r
+        synchronized (syncAdapterLock) {\r
+            if (concretSyncAdapter == null) {\r
+                concretSyncAdapter = new FileSyncAdapter(getApplicationContext(), true);\r
+            }\r
+        }\r
+    }\r
+\r
+    /*\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public IBinder onBind(Intent intent) {\r
+        return concretSyncAdapter.getSyncAdapterBinder();\r
+    }\r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/ActionItem.java b/src/eu/alefzero/owncloud/ui/ActionItem.java
new file mode 100644 (file)
index 0000000..9d53fe0
--- /dev/null
@@ -0,0 +1,59 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui;\r
+\r
+import android.graphics.drawable.Drawable;\r
+import android.view.View.OnClickListener;\r
+\r
+/**\r
+* Represents an Item on the ActionBar.\r
+* @author Bartek Przybylski\r
+* \r
+*/\r
+public class ActionItem {\r
+  private Drawable mIcon;\r
+  private String mTitle;\r
+  private OnClickListener mClickListener;\r
+  \r
+  public ActionItem() { }\r
+  \r
+  public void setTitle(String title) {\r
+    mTitle = title;\r
+  }\r
+  \r
+  public String getTitle() {\r
+    return mTitle;\r
+  }\r
+  \r
+  public void setIcon(Drawable icon) {\r
+    mIcon = icon;\r
+  }\r
+  \r
+  public Drawable getIcon() {\r
+    return mIcon;\r
+  }\r
+  \r
+  public void setOnClickListener(OnClickListener listener) {\r
+    mClickListener = listener;\r
+  }\r
+  \r
+  public OnClickListener getOnClickListerner() {\r
+    return mClickListener;\r
+  }\r
+  \r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/AuthenticatorActivity.java b/src/eu/alefzero/owncloud/ui/AuthenticatorActivity.java
deleted file mode 100644 (file)
index a912160..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/* ownCloud Android client application
- *   Copyright (C) 2011  Bartek Przybylski
- *
- *   This program is free software: you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation, either version 3 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package eu.alefzero.owncloud.ui;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorActivity;
-import android.accounts.AccountManager;
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.View;
-import android.view.Window;
-import android.widget.TextView;
-import android.widget.Toast;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
-import eu.alefzero.owncloud.authenticator.AuthUtils;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-
-public class AuthenticatorActivity extends AccountAuthenticatorActivity {
-    private Thread mAuthThread;
-    private final Handler mHandler = new Handler();
-
-    public static final String PARAM_USERNAME = "param_Username";
-    public static final String PARAM_HOSTNAME = "param_Hostname";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
-        setContentView(R.layout.account_setup);
-        if (getIntent().hasExtra(PARAM_USERNAME)) {
-            String username = getIntent().getStringExtra(PARAM_HOSTNAME);
-            TextView host_text, user_text;
-            host_text = (TextView) findViewById(R.id.host_URL);
-            user_text = (TextView) findViewById(R.id.account_username);
-            host_text.setText(host_text.getText() + username.substring(username.lastIndexOf('@')));
-            user_text.setText(user_text.getText() + username.substring(0, username.lastIndexOf('@') - 1));
-        }
-    }
-
-    @Override
-    protected Dialog onCreateDialog(int id) {
-        final ProgressDialog dialog = new ProgressDialog(this);
-        dialog.setMessage("Trying to login");
-        dialog.setIndeterminate(true);
-        dialog.setCancelable(true);
-        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
-            public void onCancel(DialogInterface dialog) {
-                Log.i(getClass().getName(), "Login canceled");
-                if (mAuthThread != null) {
-                    mAuthThread.interrupt();
-                    finish();
-                }
-            }
-        });
-        return dialog;
-    }
-
-    public void onAuthenticationResult(boolean result, String message) {
-        if (result) {
-            TextView username_text = (TextView) findViewById(R.id.account_username),
-                    password_text = (TextView) findViewById(R.id.account_password);
-
-            URL url;
-            try {
-                url = new URL(message);
-            } catch (MalformedURLException e) {
-                // should never happend
-                Log.e(getClass().getName(), "Malformed URL: " + message);
-                return;
-            }
-
-            String username = username_text.getText().toString().trim();
-            Account account = new Account(username + "@" + url.getHost(), AccountAuthenticator.ACCOUNT_TYPE);
-            AccountManager accManager = AccountManager.get(this);
-            accManager.addAccountExplicitly(account, password_text.getText().toString(), null);
-
-            final Intent intent = new Intent();
-            intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE);
-            intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
-            intent.putExtra(AccountManager.KEY_AUTHTOKEN, AccountAuthenticator.ACCOUNT_TYPE);
-            accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL, url.toString());
-
-            // TODO prepare this URL during a central service
-            intent.putExtra(AccountManager.KEY_USERDATA, username);
-            accManager.setUserData(account, AccountAuthenticator.KEY_CONTACT_URL,
-                    url.toString().replace(AuthUtils.WEBDAV_PATH_2_0, AuthUtils.CARDDAV_PATH_2_0)
-            );
-
-            setAccountAuthenticatorResult(intent.getExtras());
-            setResult(RESULT_OK, intent);
-            Bundle bundle = new Bundle();
-            bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
-            getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle);
-
-            dismissDialog(0);
-            finish();
-        } else {
-            Toast.makeText(this, message, Toast.LENGTH_LONG).show();
-            dismissDialog(0);
-        }
-    }
-
-    public void onCancelClick(View view) {
-        Log.i(getClass().getName(), "Account creating canceled");
-        this.finish();
-    }
-
-    public void onOkClick(View view) {
-        TextView url_text = (TextView) findViewById(R.id.host_URL);
-        TextView username_text = (TextView) findViewById(R.id.account_username);
-        TextView password_text = (TextView) findViewById(R.id.account_password);
-        Log.i(getClass().getName(), "OK clicked");
-        boolean hasErrors = false;
-
-        URL uri = null;
-        if (url_text.getText().toString().trim().length() == 0) {
-            url_text.setTextColor(Color.RED);
-            hasErrors = true;
-        } else {
-            url_text.setTextColor(Color.BLACK);
-        }
-        try {
-            String url_str = url_text.getText().toString();
-            if (!url_str.startsWith("http://") &&
-                    !url_str.startsWith("https://")) {
-                url_str = "http://" + url_str;
-            }
-            uri = new URL(url_str);
-        } catch (MalformedURLException e) {
-            url_text.setTextColor(Color.RED);
-            e.printStackTrace();
-            hasErrors = true;
-        }
-
-        if (username_text.getText().toString().contains(" ") ||
-                username_text.getText().toString().trim().length() == 0) {
-            username_text.setTextColor(Color.RED);
-            hasErrors = true;
-        } else {
-            username_text.setTextColor(Color.BLACK);
-        }
-
-        if (password_text.getText().toString().trim().length() == 0) {
-            password_text.setTextColor(Color.RED);
-            hasErrors = true;
-        } else {
-            password_text.setTextColor(Color.BLACK);
-        }
-        if (hasErrors) {
-            return;
-        }
-        showDialog(0);
-        mAuthThread = AuthUtils.attemptAuth(uri,
-                username_text.getText().toString(),
-                password_text.getText().toString(),
-                mHandler,
-                AuthenticatorActivity.this);
-    }
-}
diff --git a/src/eu/alefzero/owncloud/ui/CustomPopup.java b/src/eu/alefzero/owncloud/ui/CustomPopup.java
new file mode 100644 (file)
index 0000000..7709f92
--- /dev/null
@@ -0,0 +1,148 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui;\r
+\r
+import android.content.Context;\r
+import android.graphics.Rect;\r
+import android.graphics.drawable.BitmapDrawable;\r
+import android.graphics.drawable.Drawable;\r
+import android.view.Gravity;\r
+import android.view.LayoutInflater;\r
+import android.view.MotionEvent;\r
+import android.view.View;\r
+import android.view.WindowManager;\r
+import android.view.View.OnTouchListener;\r
+import android.view.ViewGroup.LayoutParams;\r
+import android.widget.PopupWindow;\r
+\r
+/**\r
+ * Represents a custom PopupWindows\r
+ * @author Lorensius. W. T\r
+ *\r
+ */\r
+public class CustomPopup {\r
+  protected final View mAnchor;\r
+  protected final PopupWindow mWindow;\r
+  private View root;\r
+  private Drawable background = null;\r
+  protected final WindowManager mWManager;\r
+  \r
+  public CustomPopup(View anchor) {\r
+    mAnchor = anchor;\r
+    mWindow = new PopupWindow(anchor.getContext());\r
+    \r
+    mWindow.setTouchInterceptor(new OnTouchListener() {\r
+      \r
+      public boolean onTouch(View v, MotionEvent event) {\r
+        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {\r
+          CustomPopup.this.dismiss();\r
+          return true;\r
+        }\r
+        return false;\r
+      }\r
+    });\r
+    \r
+    mWManager = (WindowManager) anchor.getContext().getSystemService(Context.WINDOW_SERVICE);\r
+    onCreate();\r
+  }\r
+  \r
+  \r
+  public void onCreate() {}\r
+  public void onShow() {}\r
+  \r
+  public void preShow() {\r
+    if (root == null) {\r
+      throw new IllegalStateException("setContentView called with a view to display");\r
+    }\r
+    \r
+    onShow();\r
+    \r
+    if (background == null) {\r
+      mWindow.setBackgroundDrawable(new BitmapDrawable());\r
+    } else {\r
+      mWindow.setBackgroundDrawable(background);\r
+    }\r
+    \r
+    mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);\r
+    mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);\r
+    mWindow.setTouchable(true);\r
+    mWindow.setFocusable(true);\r
+    mWindow.setOutsideTouchable(true);\r
+    \r
+    mWindow.setContentView(root);\r
+  }\r
+  \r
+  public void setBackgroundDrawable(Drawable background) {\r
+    this.background = background;\r
+  }\r
+  \r
+  public void setContentView(View root) {\r
+    this.root = root;\r
+    mWindow.setContentView(root);\r
+  }\r
+  \r
+  public void setContentView(int layoutResId) {\r
+    LayoutInflater inflater = \r
+      (LayoutInflater) mAnchor.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+    setContentView(inflater.inflate(layoutResId, null));\r
+  }\r
+  \r
+  public void showDropDown() {\r
+    showDropDown(0, 0);\r
+  }\r
+  \r
+  public void showDropDown(int x, int y) {\r
+    preShow();\r
+    mWindow.setAnimationStyle(android.R.style.Animation_Dialog);\r
+    mWindow.showAsDropDown(mAnchor, x, y);\r
+  }\r
+  \r
+  public void showLikeQuickAction() {\r
+    showLikeQuickAction(0, 0);\r
+  }\r
+  \r
+  public void showLikeQuickAction(int x, int y) {\r
+    preShow();\r
+    \r
+    mWindow.setAnimationStyle(android.R.style.Animation_Dialog);\r
+    int[] location = new int[2];\r
+    mAnchor.getLocationOnScreen(location);\r
+    \r
+    Rect anchorRect = \r
+      new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] + mAnchor.getHeight());\r
+    \r
+    root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));\r
+    root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
+    \r
+    int rootW = root.getWidth(), rootH = root.getHeight();\r
+    int screenW = mWManager.getDefaultDisplay().getWidth();\r
+    \r
+    int xpos = ((screenW-rootW)/2) + x;\r
+    int ypos = anchorRect.top - rootH + y;\r
+    \r
+    if (rootH > anchorRect.top) {\r
+      ypos = anchorRect.bottom + y;\r
+    }\r
+    mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xpos, ypos);\r
+  }\r
+  \r
+  public void dismiss() {\r
+    mWindow.dismiss();\r
+  }\r
+  \r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/FileDetailActivity.java b/src/eu/alefzero/owncloud/ui/FileDetailActivity.java
deleted file mode 100644 (file)
index 989a601..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package eu.alefzero.owncloud.ui;\r
-\r
-\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.R.id;\r
-import eu.alefzero.owncloud.R.layout;\r
-import eu.alefzero.owncloud.ui.fragment.ActionBar;\r
-import eu.alefzero.owncloud.ui.fragment.FileDetail;\r
-import android.app.Activity;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.res.Configuration;\r
-import android.os.Bundle;\r
-import android.support.v4.app.FragmentActivity;\r
-import android.support.v4.app.FragmentTransaction;\r
-import android.util.AttributeSet;\r
-import android.util.Log;\r
-import android.view.View;\r
-import android.view.Window;\r
-\r
-public class FileDetailActivity extends FragmentActivity {\r
-  private FileDetail mFileDetail;\r
-  \r
-@Override\r
-protected void onCreate(Bundle savedInstanceState) {\r
-  // TODO Auto-generated method stub\r
-  super.onCreate(savedInstanceState);\r
-  getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
-  setContentView(R.layout.file_activity_details);\r
-  \r
-  mFileDetail = new FileDetail();\r
-  FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
-  ft.add(R.id.fileDetail, mFileDetail);\r
-  ft.commit();\r
-  \r
-}\r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/FileDisplayActivity.java b/src/eu/alefzero/owncloud/ui/FileDisplayActivity.java
deleted file mode 100644 (file)
index eb882a0..0000000
+++ /dev/null
@@ -1,355 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2011  Bartek Przybylski\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-\r
-package eu.alefzero.owncloud.ui;\r
-\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.IOException;\r
-import java.util.LinkedList;\r
-import java.util.Stack;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.app.AlertDialog;\r
-import android.app.Dialog;\r
-import android.app.ListActivity;\r
-import android.content.DialogInterface;\r
-import android.content.Intent;\r
-import android.content.DialogInterface.OnCancelListener;\r
-import android.content.res.Configuration;\r
-import android.database.Cursor;\r
-import android.graphics.Bitmap;\r
-import android.graphics.BitmapFactory;\r
-import android.graphics.Matrix;\r
-import android.net.Uri;\r
-import android.os.Bundle;\r
-import android.os.Environment;\r
-import android.support.v4.app.FragmentActivity;\r
-import android.support.v4.app.FragmentTransaction;\r
-import android.text.TextUtils;\r
-import android.util.Log;\r
-import android.view.Menu;\r
-import android.view.MenuInflater;\r
-import android.view.MenuItem;\r
-import android.view.View;\r
-import android.view.Window;\r
-import android.widget.ImageView;\r
-import android.widget.ListView;\r
-import android.widget.TextView;\r
-import eu.alefzero.owncloud.DbHandler;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.R.id;\r
-import eu.alefzero.owncloud.R.layout;\r
-import eu.alefzero.owncloud.R.menu;\r
-import eu.alefzero.owncloud.R.string;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
-import eu.alefzero.owncloud.ui.fragment.FileDetail;\r
-import eu.alefzero.owncloud.ui.fragment.FileList;\r
-import eu.alefzero.owncloud.ui.fragment.ActionBar;\r
-public class FileDisplayActivity extends FragmentActivity {\r
-  private DbHandler mDBHandler;\r
-  private Stack<String> mParents;\r
-  private LinkedList<String> mPath;\r
-  private Account mAccount;\r
-  private Cursor mCursor;\r
-  private boolean mIsDisplayingFile;\r
-\r
-  private static final int DIALOG_CHOOSE_ACCOUNT = 0;\r
-\r
-  @Override\r
-  public void onCreate(Bundle savedInstanceState) {\r
-    super.onCreate(savedInstanceState);\r
-    getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
-    setContentView(R.layout.files);\r
-    \r
-    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
-    //ft.add(R.id.actionBar, new ActionBar());\r
-    ft.add(R.id.fileList, new FileList());\r
-    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {\r
-      ft.add(R.id.fileDetail, new FileDetail());\r
-    }\r
-    ft.commit();\r
-\r
-    /*getSupportFragmentManager().beginTransaction().add(arg0, arg1);\r
-    FileList fl = new FileList();\r
-    ft.add(R.id.fileList, fl);\r
-    ft.commit();\r
-    /*\r
-\r
-    \r
-    if (savedInstanceState != null) {\r
-      mParents = (Stack<String>)savedInstanceState.getSerializable("parentsStack");\r
-      mIsDisplayingFile = savedInstanceState.getBoolean("isDisplayingFile");\r
-      mPath = (LinkedList<String>)savedInstanceState.getSerializable("path");\r
-    } else {\r
-      mParents = new Stack<String>();\r
-      mPath = new LinkedList<String>();\r
-      mIsDisplayingFile = false;\r
-    }\r
-\r
-    mDBHandler = new DbHandler(getBaseContext());\r
-    requestWindowFeature(Window.FEATURE_NO_TITLE);\r
-    setContentView(R.layout.main);\r
-\r
-    AccountManager accMan = AccountManager.get(this);\r
-    Account[] accounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
-\r
-    if (accounts.length == 0) {\r
-      // using string value since in API7 this constatn is not defined\r
-      // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS\r
-      // and Settings.EXTRA_AUTHORITIES\r
-      Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
-      intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});\r
-      startActivity(intent);\r
-    } else if (accounts.length > 1) {\r
-      showDialog(DIALOG_CHOOSE_ACCOUNT);\r
-    } else {\r
-      mAccount = accounts[0];\r
-      populateFileList();\r
-    }*/\r
-  }\r
-\r
-  @Override\r
-  public boolean onOptionsItemSelected(MenuItem item) {\r
-    switch (item.getItemId()) {\r
-      case R.id.settingsItem :\r
-        Intent i = new Intent(this, Preferences.class);\r
-        startActivity(i);\r
-        break;\r
-    }\r
-    return true;\r
-  }\r
-\r
-  @Override\r
-  protected Dialog onCreateDialog(int id) {\r
-    switch (id) {\r
-      case DIALOG_CHOOSE_ACCOUNT:\r
-        return createChooseAccountDialog();\r
-      default:\r
-        throw new IllegalArgumentException("Unknown dialog id: " + id);\r
-    }\r
-  }\r
-  \r
-  @Override\r
-  public boolean onCreateOptionsMenu(Menu menu) {\r
-    MenuInflater inflater = getMenuInflater();\r
-    inflater.inflate(R.menu.menu, menu);\r
-    return true;\r
-  }\r
-    \r
-  private Dialog createChooseAccountDialog() {\r
-    final AccountManager accMan = AccountManager.get(this);\r
-    CharSequence[] items = new CharSequence[accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];\r
-    int i = 0;\r
-    for (Account a : accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)) {\r
-      items[i++] = a.name;\r
-    }\r
-    \r
-    AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
-    builder.setTitle(R.string.common_choose_account);\r
-    builder.setCancelable(true);\r
-    builder.setItems(items, new DialogInterface.OnClickListener() {\r
-        public void onClick(DialogInterface dialog, int item) {\r
-            mAccount = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[item];\r
-            dialog.dismiss();\r
-            populateFileList();\r
-        }\r
-    });\r
-    builder.setOnCancelListener(new OnCancelListener() {\r
-      public void onCancel(DialogInterface dialog) {\r
-        FileDisplayActivity.this.finish();\r
-      }\r
-    });\r
-    AlertDialog alert = builder.create();\r
-    return alert;\r
-  }\r
-\r
-  //@Override\r
-  //public void onBackPressed() {\r
-    /*PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);\r
-    if (mIsDisplayingFile) {\r
-      mIsDisplayingFile = false;\r
-      setContentView(R.layout.main);\r
-      pl = (PathLayout) findViewById(R.id.pathLayout1);\r
-      Uri uri;\r
-      if (mParents.empty()) {\r
-        uri = ProviderTableMeta.CONTENT_URI;\r
-      } else {\r
-        uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek());\r
-      }\r
-      mCursor = managedQuery(uri,\r
-                             null,\r
-                             ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
-                             new String[]{mAccount.name}, null);\r
-  \r
-      if (mCursor.moveToFirst()) {\r
-        String s = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH));\r
-        for (String str : s.split("/")) {\r
-          if (!TextUtils.isEmpty(str))\r
-            pl.push(DisplayUtils.HtmlDecode(str));\r
-        }\r
-      }\r
-      getListView().setAdapter(new FileListListAdapter(mCursor, this));      \r
-      getListView().invalidate();\r
-      return;\r
-    }\r
-    if (mParents.size()==0) {\r
-      super.onBackPressed();\r
-      return;\r
-    } else if (mParents.size() == 1) {\r
-      mParents.pop();\r
-      mPath.removeLast();\r
-      pl.pop();\r
-      mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,\r
-          null,\r
-          ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
-          new String[]{mAccount.name},\r
-          null);\r
-    } else {\r
-      mParents.pop();\r
-      mPath.removeLast();\r
-      pl.pop();\r
-      mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),\r
-          null,\r
-          ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
-          new String[]{mAccount.name},\r
-          null);\r
-    }\r
-    \r
-    setListAdapter(new FileListListAdapter(mCursor, this));\r
-    getListView().invalidate();*/\r
-  //}\r
-\r
-  //@Override\r
-/*  protected void onListItemClick(ListView l, View v, int position, long id) {\r
-    super.onListItemClick(l, v, position, id);\r
-    /*PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);\r
-    if (!mCursor.moveToPosition(position)) {\r
-      throw new IndexOutOfBoundsException("Incorrect item selected");\r
-    }\r
-    if (!mIsDisplayingFile) {\r
-      if (mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {\r
-        String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));\r
-        String dirname = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME));\r
-        pl.push(DisplayUtils.HtmlDecode(dirname));\r
-        mPath.addLast(DisplayUtils.HtmlDecode(dirname));\r
-        mParents.push(id_);\r
-        mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, id_),\r
-                               null,\r
-                               ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
-                               new String[]{mAccount.name}, null);\r
-        setListAdapter(new FileListListAdapter(mCursor, this));\r
-      } else {\r
-        mIsDisplayingFile = true;\r
-        setContentView(R.layout.file_display);\r
-        String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));\r
-        mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, id_),\r
-                               null,\r
-                               null,\r
-                               null,\r
-                               null);\r
-        mCursor.moveToFirst();\r
-        // filename\r
-        TextView tv = (TextView) findViewById(R.id.textView1);\r
-        tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)));\r
-        // filetype\r
-        tv = (TextView) findViewById(R.id.textView2);\r
-        tv.setText(DisplayUtils.convertMIMEtoPrettyPrint(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE))));\r
-        // size\r
-        tv = (TextView) findViewById(R.id.textView3);\r
-        tv.setText(DisplayUtils.bitsToHumanReadable(mCursor.getLong(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH))));\r
-        // modified\r
-        tv = (TextView) findViewById(R.id.textView4);\r
-        tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));\r
-        if (!TextUtils.isEmpty(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH))) &&\r
-            mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).matches("image/*")) {\r
-          ImageView iv = (ImageView) findViewById(R.id.imageView1);\r
-          Bitmap bmp = BitmapFactory.decodeFile(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));\r
-          Matrix m = new Matrix();\r
-          float scale;\r
-          if (bmp.getWidth() > bmp.getHeight()) {\r
-            scale = (float) (200./bmp.getWidth());\r
-          } else {\r
-            scale = (float) (200./bmp.getHeight());\r
-          }\r
-          m.postScale(scale, scale);\r
-          Bitmap newBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);\r
-          iv.setImageBitmap(newBmp);\r
-        }\r
-        setListAdapter(new FileListActionListAdapter(mCursor, this, mAccount));\r
-      }    \r
-      getListView().invalidate();\r
-    } else {\r
-        Intent i = (Intent) getListAdapter().getItem(position);\r
-        if (i.hasExtra("toDownload")) {\r
-          \r
-          Intent intent = new Intent(this, FileDownloader.class);\r
-          intent.putExtra(FileDownloader.EXTRA_FILE_PATH, "/"+((TextView)findViewById(R.id.textView1)).getText().toString());\r
-          intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);\r
-          startService(intent);\r
-          /*\r
-          if (i.getBooleanExtra("toDownload", false)) {\r
-            startActivityForResult(i, 200);\r
-          } else {\r
-            startActivity(i);            \r
-          }*/\r
-       // }\r
-\r
-    //}\r
-//  }\r
-  \r
-  private void populateFileList() {\r
-    if (mParents.empty()) {\r
-      mCursor = getContentResolver().query(ProviderTableMeta.CONTENT_URI,\r
-                                           null,\r
-                                           ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
-                                           new String[]{mAccount.name},\r
-                                           null);\r
-    } else {\r
-      mCursor = getContentResolver().query(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),\r
-                                           null,\r
-                                           ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
-                                           new String[]{mAccount.name}, null);\r
-      if (!mIsDisplayingFile) {\r
-        //PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);\r
-        //for (String s : mPath) {\r
-        //  pl.push(s);\r
-       // }\r
-      }\r
-    }\r
-//    setListAdapter(new FileListListAdapter(mCursor, this));\r
-//    getListView().invalidate();\r
-  }\r
-  \r
-  //@Override\r
-  /*protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
-    super.onActivityResult(requestCode, resultCode, data);\r
-  }\r
-  \r
-  @Override\r
-  protected void onSaveInstanceState(Bundle outState) {\r
-    super.onSaveInstanceState(outState);\r
-    outState.putSerializable("parentsStack", mParents);\r
-    outState.putSerializable("path", mPath);\r
-    outState.putBoolean("isDisplayingFile", mIsDisplayingFile);\r
-  }*/\r
-\r
-}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/ui/LandingActivity.java b/src/eu/alefzero/owncloud/ui/LandingActivity.java
deleted file mode 100644 (file)
index afc7a3f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* ownCloud Android client application\r
- *   Copyright (C) 2012  Lennart Rosam\r
- *\r
- *   This program is free software: you can redistribute it and/or modify\r
- *   it under the terms of the GNU General Public License as published by\r
- *   the Free Software Foundation, either version 3 of the License, or\r
- *   (at your option) any later version.\r
- *\r
- *   This program is distributed in the hope that it will be useful,\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- *   GNU General Public License for more details.\r
- *\r
- *   You should have received a copy of the GNU General Public License\r
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
- *\r
- */\r
-package eu.alefzero.owncloud.ui;\r
-\r
-import android.accounts.Account;\r
-import android.accounts.AccountManager;\r
-import android.app.AlertDialog;\r
-import android.app.Dialog;\r
-import android.content.DialogInterface;\r
-import android.content.Intent;\r
-import android.content.DialogInterface.OnClickListener;\r
-import android.os.Bundle;\r
-import android.support.v4.app.FragmentActivity;\r
-import eu.alefzero.owncloud.R;\r
-import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
-\r
-/**\r
- * This activity is used as a landing page when the user first opens this app.\r
- * \r
- * @author Lennart Rosam\r
- */\r
-public class LandingActivity extends FragmentActivity implements OnClickListener {\r
-\r
-       public static final int DIALOG_SETUP_ACCOUNT = 1;\r
-       \r
-       @Override\r
-       protected void onCreate(Bundle savedInstanceState) {\r
-               super.onCreate(savedInstanceState);\r
-               setContentView(R.layout.main);\r
-               \r
-               // Check, if there are ownCloud accounts\r
-               if(!accountsAreSetup()){\r
-                       showDialog(DIALOG_SETUP_ACCOUNT);\r
-               }\r
-\r
-       }\r
-\r
-       @Override\r
-       protected Dialog onCreateDialog(int id) {\r
-               Dialog dialog;\r
-               switch(id){\r
-               case DIALOG_SETUP_ACCOUNT:\r
-                       AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
-                       builder.setTitle(R.string.main_tit_accsetup);\r
-                       builder.setMessage(R.string.main_wrn_accsetup);\r
-                       builder.setCancelable(false);\r
-                       builder.setPositiveButton(R.string.common_ok, this);\r
-                       builder.setNegativeButton(R.string.common_cancel, this);\r
-                       dialog = builder.create();\r
-                       break;\r
-               default: \r
-                       dialog = null;\r
-               }\r
-                       \r
-               return dialog;\r
-       }\r
-\r
-       @Override\r
-       public void onClick(DialogInterface dialog, int which) {\r
-               // In any case - we won't need it anymore\r
-               dialog.dismiss();\r
-               switch(which){\r
-               case DialogInterface.BUTTON_POSITIVE:\r
-                       Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
-                       intent.putExtra("authorities",\r
-                                       new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
-                       startActivity(intent);\r
-                       break;\r
-               case DialogInterface.BUTTON_NEGATIVE:\r
-                       finish();\r
-               }\r
-               \r
-       }\r
-       \r
-       /**\r
-        * Checks, whether or not there are any ownCloud accounts \r
-        * setup. \r
-        *  \r
-        * @return true, if there is at least one account.\r
-        */\r
-       private boolean accountsAreSetup() {\r
-               AccountManager accMan = AccountManager.get(this);\r
-               Account[] accounts = accMan\r
-                               .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE); \r
-               return accounts.length > 0;\r
-       }\r
-       \r
-\r
-}\r
diff --git a/src/eu/alefzero/owncloud/ui/Preferences.java b/src/eu/alefzero/owncloud/ui/Preferences.java
deleted file mode 100644 (file)
index 5dc260d..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-package eu.alefzero.owncloud.ui;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Vector;
-
-import eu.alefzero.owncloud.DbHandler;
-import eu.alefzero.owncloud.OwnCloudSession;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.R.id;
-import eu.alefzero.owncloud.R.menu;
-import eu.alefzero.owncloud.R.xml;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceScreen;
-import android.util.Log;
-import android.view.ContextMenu;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ContextMenu.ContextMenuInfo;
-import android.widget.AdapterView.AdapterContextMenuInfo;
-
-public class Preferences extends PreferenceActivity {
-  private String TAG = "OwnCloudPreferences";
-  private final int mNewSession = 47;
-  private final int mEditSession = 48;
-  private DbHandler mDbHandler;
-  private Vector<OwnCloudSession> mSessions;
-  private int mSelectedMenuItem;
-  
-  @Override
-  public void onCreate(Bundle savedInstanceState){
-    super.onCreate(savedInstanceState);
-    mDbHandler = new DbHandler(getBaseContext());
-    mSessions = new Vector<OwnCloudSession>();
-    addPreferencesFromResource(R.xml.preferences);
-    registerForContextMenu(getListView());
-    //populateSessionList();
-  }
-  
-  private void populateSessionList() {
-    mSessions.clear();
-    mSessions = mDbHandler.getSessionList();
-    PreferenceScreen ps = getPreferenceScreen();
-    ps.removeAll();
-    addPreferencesFromResource(R.xml.preferences);
-    for (int i = 0; i < mSessions.size(); i++) {
-      Preference preference = new Preference(getBaseContext());
-      preference.setTitle(mSessions.get(i).getName());
-      URI uri;
-      try {
-        uri = new URI(mSessions.get(i).getUrl());
-      } catch (URISyntaxException e) {
-        e.printStackTrace(); // should never happend
-        continue;
-      }
-      preference.setSummary(uri.getScheme() + "://" + uri.getHost()+uri.getPath());
-      ps.addPreference(preference);
-    }
-  }
-
-  @Override
-  public boolean onCreateOptionsMenu(Menu menu) {
-    super.onCreateOptionsMenu(menu);
-    MenuInflater inflater = getMenuInflater();
-    inflater.inflate(R.menu.prefs_menu, menu);
-    return true;
-  }
-  
-  @Override
-  public boolean onMenuItemSelected(int featureId, MenuItem item) {
-    super.onMenuItemSelected(featureId, item);
-    Intent intent;
-    
-    switch (item.getItemId()) {
-      case R.id.addSessionItem:
-        intent = new Intent(this, PreferencesNewSession.class);
-        startActivityForResult(intent, mNewSession);
-        break;
-      case R.id.SessionContextEdit:
-        intent = new Intent(this, PreferencesNewSession.class);
-        intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem).getEntryId());
-        intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem).getName());
-        intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem).getUrl());
-        startActivityForResult(intent, mEditSession);
-        break;
-      case R.id.SessionContextRemove:
-        OwnCloudSession ocs = mSessions.get(mSelectedMenuItem);
-        mDbHandler.removeSessionWithId(ocs.getEntryId());
-        mSessions.remove(ocs);
-        getPreferenceScreen().removePreference(getPreferenceScreen().getPreference(mSelectedMenuItem+1));
-        break;
-      default:
-        Log.w(TAG, "Unknown menu item triggered");
-        return false;
-    }
-    return true;
-  }
-
-  @Override
-  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-    super.onActivityResult(requestCode, resultCode, data);
-    if (resultCode == Activity.RESULT_OK) {
-      switch (requestCode) {
-        case mNewSession:
-          mDbHandler.addSession(data.getStringExtra("sessionName"), 
-                                data.getStringExtra("sessionURL"));
-          getPreferenceScreen().removeAll();
-          addPreferencesFromResource(R.xml.preferences);
-          populateSessionList();
-          break;
-        case mEditSession:
-          mDbHandler.changeSessionFields(data.getIntExtra("sessionId", -1),
-                                         data.getStringExtra("sessionName"),
-                                         data.getStringExtra("sessionURL"));
-          populateSessionList();
-          break;
-      }
-    }
-  }
-
-  @Override
-  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-    super.onCreateContextMenu(menu, v, menuInfo);
-    AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
-    mSelectedMenuItem = info.position-1;
-    menu.setHeaderTitle(mSessions.get(mSelectedMenuItem).getName());
-    
-    MenuInflater inflater = getMenuInflater();
-    inflater.inflate(R.menu.session_context_menu, menu);
-    
-  }
-  
-  @Override
-  protected void onDestroy() {
-    mDbHandler.close();
-    super.onDestroy();
-  }
-  
-}
diff --git a/src/eu/alefzero/owncloud/ui/PreferencesNewSession.java b/src/eu/alefzero/owncloud/ui/PreferencesNewSession.java
deleted file mode 100644 (file)
index 9900abf..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-package eu.alefzero.owncloud.ui;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import eu.alefzero.owncloud.authenticator.AccountAuthenticatorService;
-
-import android.accounts.Account;
-import android.accounts.AccountAuthenticatorActivity;
-import android.accounts.AccountManager;
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.Toast;
-
-public class PreferencesNewSession extends AccountAuthenticatorActivity implements OnClickListener {
-  private Intent mReturnData;
-  private final String TAG = "OwnCloudPreferencesNewSession";
-  @Override
-  public void onCreate(Bundle savedInstanceState){
-    super.onCreate(savedInstanceState);
-    //setContentView(R.layout.add_new_session);
-    /*
-    EditText et;// = (EditText) findViewById(R.id.newSession_sessionName);
-    
-    et = (EditText) findViewById(R.id.newSession_URL);
-    if (getIntent().hasExtra("sessionURL")) {
-      try {
-        URI uri = new URI(getIntent().getStringExtra("sessionURL"));
-        String url = uri.getHost();
-        if (uri.getPort() != -1) {
-          url += ":" + String.valueOf(uri.getPort());
-        }
-        if (uri.getPath() != null) {
-          url += uri.getPath();
-        } else {
-          url += "/";
-        }
-        et.setText(url);
-        et = (EditText) findViewById(R.id.newSession_username);
-        if (uri.getAuthority() != null) {
-          if (uri.getUserInfo().indexOf(':') != -1) {
-            et.setText(uri.getUserInfo().substring(0, uri.getUserInfo().indexOf(':')));
-            et = (EditText) findViewById(R.id.newSession_password);
-            et.setText(uri.getUserInfo().substring(uri.getUserInfo().indexOf(':')+1));
-          } else {
-            et.setText(uri.getUserInfo());
-          }
-        }
-        
-      } catch (URISyntaxException e) {
-        Log.e(TAG, "Incorrect URI syntax " + e.getLocalizedMessage());
-      }
-    }
-    
-    mReturnData = new Intent();
-    setResult(Activity.RESULT_OK, mReturnData);
-    ((Button) findViewById(R.id.button1)).setOnClickListener(this);
-    ((Button) findViewById(R.id.button2)).setOnClickListener(this);*/
-  }
-  
-  @Override
-  protected void onResume() {
-    super.onResume();
-  }
-
-  public void onClick(View v) {
-   /* switch (v.getId()) {
-      case R.id.button1:
-        Intent intent = new Intent();
-        if (getIntent().hasExtra("sessionId")) {
-          intent.putExtra("sessionId", getIntent().getIntExtra("sessionId", -1));
-        }
-        //String sessionName = ((EditText) findViewById(R.id.newSession_sessionName)).getText().toString();
-      //  if (sessionName.trim().equals("") || !isNameValid(sessionName)) {
-     //    Toast.makeText(this, R.string.new_session_session_name_error, Toast.LENGTH_LONG).show();
-     //     break;
-       // }
-        URI uri = prepareURI();
-        if (uri != null) {
-          //intent.putExtra("sessionName", sessionName);
-          intent.putExtra("sessionURL", uri.toString());
-          setResult(Activity.RESULT_OK, intent);
-          AccountManager accMgr = AccountManager.get(this);
-          Account a = new Account("OwnCloud", AccountAuthenticatorService.ACCOUNT_TYPE);
-          accMgr.addAccountExplicitly(a, "asd", null);
-          finish();
-        }
-        break;
-      case R.id.button2:
-        setResult(Activity.RESULT_CANCELED);
-        finish();
-        break;
-    }*/
-  }
-  
-  private URI prepareURI() {
-    URI uri = null;
-   /* String url = "";
-    try {
-      String username = ((EditText) findViewById(R.id.newSession_username)).getText().toString().trim();
-      String password = ((EditText) findViewById(R.id.newSession_password)).getText().toString().trim();
-      String hostname = ((EditText) findViewById(R.id.newSession_URL)).getText().toString().trim();
-      String scheme;
-      if (hostname.matches("[A-Za-z]://")) {
-        scheme = hostname.substring(0, hostname.indexOf("://")+3);
-        hostname = hostname.substring(hostname.indexOf("://")+3);
-      } else {
-        scheme = "http://";
-      }
-      if (!username.equals("")) {
-        if (!password.equals("")) {
-          username += ":" + password + "@";
-        } else {
-          username += "@";
-        }
-      }
-      url = scheme + username + hostname;
-      Log.i(TAG, url);
-      uri = new URI(url);
-    } catch (URISyntaxException e) {
-      Log.e(TAG, "Incorrect URI syntax " + e.getLocalizedMessage());
-      Toast.makeText(this, R.string.new_session_uri_error, Toast.LENGTH_LONG).show();
-    }
-    */return uri;
-  }
-  
-  private boolean isNameValid(String string) {
-    return string.matches("[A-Za-z0-9 _-]*");
-  }
-  
-  @Override
-  public void onBackPressed() {
-    setResult(Activity.RESULT_CANCELED);
-    super.onBackPressed();
-  }
-  
-}
diff --git a/src/eu/alefzero/owncloud/ui/QuickAction.java b/src/eu/alefzero/owncloud/ui/QuickAction.java
new file mode 100644 (file)
index 0000000..6f61253
--- /dev/null
@@ -0,0 +1,289 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui;\r
+\r
+import android.content.Context;\r
+\r
+import android.graphics.Rect;\r
+import android.graphics.drawable.Drawable;\r
+\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import android.widget.LinearLayout;\r
+import android.widget.ScrollView;\r
+\r
+import android.view.Gravity;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+import android.view.ViewGroup.LayoutParams;\r
+import android.view.ViewGroup;\r
+\r
+import java.util.ArrayList;\r
+\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.R.id;\r
+import eu.alefzero.owncloud.R.layout;\r
+import eu.alefzero.owncloud.R.style;\r
+\r
+/**\r
+ * Popup window, shows action list as icon and text like the one in Gallery3D app. \r
+ * \r
+ * @author Lorensius. W. T\r
+ */\r
+public class QuickAction extends CustomPopup {\r
+       private final View root;\r
+       private final ImageView mArrowUp;\r
+       private final ImageView mArrowDown;\r
+       private final LayoutInflater inflater;\r
+       private final Context context;\r
+       \r
+       protected static final int ANIM_GROW_FROM_LEFT = 1;\r
+       protected static final int ANIM_GROW_FROM_RIGHT = 2;\r
+       protected static final int ANIM_GROW_FROM_CENTER = 3;\r
+       protected static final int ANIM_REFLECT = 4;\r
+       protected static final int ANIM_AUTO = 5;\r
+\r
+       private int animStyle;\r
+       private ViewGroup mTrack;\r
+       private ScrollView scroller;\r
+       private ArrayList<ActionItem> actionList;\r
+       \r
+       /**\r
+        * Constructor\r
+        * \r
+        * @param anchor {@link View} on where the popup window should be displayed\r
+        */\r
+       public QuickAction(View anchor) {\r
+               super(anchor);\r
+               \r
+               actionList      = new ArrayList<ActionItem>();\r
+               context         = anchor.getContext();\r
+               inflater        = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+               \r
+               root            = (ViewGroup) inflater.inflate(R.layout.popup, null);\r
+               \r
+               mArrowDown      = (ImageView) root.findViewById(R.id.arrow_down);\r
+               mArrowUp        = (ImageView) root.findViewById(R.id.arrow_up);\r
+               \r
+               setContentView(root);\r
+           \r
+               mTrack                  = (ViewGroup) root.findViewById(R.id.tracks);\r
+               scroller                = (ScrollView) root.findViewById(R.id.scroller);\r
+               animStyle               = ANIM_AUTO;\r
+       }\r
+\r
+       /**\r
+        * Set animation style\r
+        * \r
+        * @param animStyle animation style, default is set to ANIM_AUTO\r
+        */\r
+       public void setAnimStyle(int animStyle) {\r
+               this.animStyle = animStyle;\r
+       }\r
+\r
+       /**\r
+        * Add action item\r
+        * \r
+        * @param action  {@link ActionItem} object\r
+        */\r
+       public void addActionItem(ActionItem action) {\r
+               actionList.add(action); \r
+       }\r
+       \r
+       /**\r
+        * Show popup window. Popup is automatically positioned, on top or bottom of anchor view.\r
+        * \r
+        */\r
+       public void show () {\r
+               preShow();\r
+               \r
+               int xPos, yPos;\r
+               \r
+               int[] location          = new int[2];\r
+       \r
+               mAnchor.getLocationOnScreen(location);\r
+\r
+               Rect anchorRect         = new Rect(location[0], location[1], location[0] + mAnchor.getWidth(), location[1] \r
+                                       + mAnchor.getHeight());\r
+\r
+               createActionList();\r
+               \r
+               root.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));\r
+               root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);\r
+       \r
+               int rootHeight          = root.getMeasuredHeight();\r
+               int rootWidth           = root.getMeasuredWidth();\r
+               \r
+               int screenWidth         = mWManager.getDefaultDisplay().getWidth();\r
+               int screenHeight        = mWManager.getDefaultDisplay().getHeight();\r
+               \r
+               //automatically get X coord of popup (top left)\r
+               if ((anchorRect.left + rootWidth) > screenWidth) {\r
+                       xPos = anchorRect.left - (rootWidth-mAnchor.getWidth());\r
+               } else {\r
+                       if (mAnchor.getWidth() > rootWidth) {\r
+                               xPos = anchorRect.centerX() - (rootWidth/2);\r
+                       } else {\r
+                               xPos = anchorRect.left;\r
+                       }\r
+               }\r
+               \r
+               int dyTop                       = anchorRect.top;\r
+               int dyBottom            = screenHeight - anchorRect.bottom;\r
+\r
+               boolean onTop           = (dyTop > dyBottom) ? true : false;\r
+\r
+               if (onTop) {\r
+                       if (rootHeight > dyTop) {\r
+                               yPos                    = 15;\r
+                               LayoutParams l  = scroller.getLayoutParams();\r
+                               l.height                = dyTop - mAnchor.getHeight();\r
+                       } else {\r
+                               yPos = anchorRect.top - rootHeight;\r
+                       }\r
+               } else {\r
+                       yPos = anchorRect.bottom;\r
+                       \r
+                       if (rootHeight > dyBottom) { \r
+                               LayoutParams l  = scroller.getLayoutParams();\r
+                               l.height                = dyBottom;\r
+                       }\r
+               }\r
+               \r
+               showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), anchorRect.centerX()-xPos);\r
+               \r
+               setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);\r
+               \r
+               mWindow.showAtLocation(mAnchor, Gravity.NO_GRAVITY, xPos, yPos);\r
+       }\r
+       \r
+       /**\r
+        * Set animation style\r
+        * \r
+        * @param screenWidth screen width\r
+        * @param requestedX distance from left edge\r
+        * @param onTop flag to indicate where the popup should be displayed. Set TRUE if displayed on top of anchor view\r
+        *                and vice versa\r
+        */\r
+       private void setAnimationStyle(int screenWidth, int requestedX, boolean onTop) {\r
+               int arrowPos = requestedX - mArrowUp.getMeasuredWidth()/2;\r
+\r
+               switch (animStyle) {\r
+               case ANIM_GROW_FROM_LEFT:\r
+                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);\r
+                       break;\r
+                                       \r
+               case ANIM_GROW_FROM_RIGHT:\r
+                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);\r
+                       break;\r
+                                       \r
+               case ANIM_GROW_FROM_CENTER:\r
+                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);\r
+               break;\r
+                       \r
+               case ANIM_REFLECT:\r
+                       mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Reflect : R.style.Animations_PopDownMenu_Reflect);\r
+               break;\r
+               \r
+               case ANIM_AUTO:\r
+                       if (arrowPos <= screenWidth/4) {\r
+                               mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left : R.style.Animations_PopDownMenu_Left);\r
+                       } else if (arrowPos > screenWidth/4 && arrowPos < 3 * (screenWidth/4)) {\r
+                               mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center : R.style.Animations_PopDownMenu_Center);\r
+                       } else {\r
+                               mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right : R.style.Animations_PopDownMenu_Right);\r
+                       }\r
+                                       \r
+                       break;\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Create action list\r
+        */\r
+       private void createActionList() {\r
+               View view;\r
+               String title;\r
+               Drawable icon;\r
+               OnClickListener listener;\r
+       \r
+               for (int i = 0; i < actionList.size(); i++) {\r
+                       title           = actionList.get(i).getTitle();\r
+                       icon            = actionList.get(i).getIcon();\r
+                       listener        = actionList.get(i).getOnClickListerner();\r
+       \r
+                       view            = getActionItem(title, icon, listener);\r
+               \r
+                       view.setFocusable(true);\r
+                       view.setClickable(true);\r
+                        \r
+                       mTrack.addView(view);\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Get action item {@link View}\r
+        * \r
+        * @param title action item title\r
+        * @param icon {@link Drawable} action item icon\r
+        * @param listener {@link View.OnClickListener} action item listener\r
+        * @return action item {@link View}\r
+        */\r
+       private View getActionItem(String title, Drawable icon, OnClickListener listener) {\r
+               LinearLayout container  = (LinearLayout) inflater.inflate(R.layout.action_item, null);\r
+               \r
+               ImageView img                   = (ImageView) container.findViewById(R.id.icon);\r
+               TextView text                   = (TextView) container.findViewById(R.id.title);\r
+               \r
+               if (icon != null) {\r
+                       img.setImageDrawable(icon);\r
+               }\r
+               \r
+               if (title != null) {                    \r
+                       text.setText(title);\r
+               }\r
+               \r
+               if (listener != null) {\r
+                       container.setOnClickListener(listener);\r
+               }\r
+\r
+               return container;\r
+       }\r
+       \r
+       /**\r
+        * Show arrow\r
+        * \r
+        * @param whichArrow arrow type resource id\r
+        * @param requestedX distance from left screen\r
+        */\r
+       private void showArrow(int whichArrow, int requestedX) {\r
+        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp : mArrowDown;\r
+        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown : mArrowUp;\r
+\r
+        final int arrowWidth = mArrowUp.getMeasuredWidth();\r
+\r
+        showArrow.setVisibility(View.VISIBLE);\r
+        \r
+        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams)showArrow.getLayoutParams();\r
+       \r
+        param.leftMargin = requestedX - arrowWidth / 2;\r
+        \r
+        hideArrow.setVisibility(View.INVISIBLE);\r
+    }\r
+}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java b/src/eu/alefzero/owncloud/ui/activity/AuthenticatorActivity.java
new file mode 100644 (file)
index 0000000..79781f3
--- /dev/null
@@ -0,0 +1,191 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package eu.alefzero.owncloud.ui.activity;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountAuthenticatorActivity;\r
+import android.accounts.AccountManager;\r
+import android.app.Dialog;\r
+import android.app.ProgressDialog;\r
+import android.content.ContentResolver;\r
+import android.content.DialogInterface;\r
+import android.content.Intent;\r
+import android.graphics.Color;\r
+import android.os.Bundle;\r
+import android.os.Handler;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.Window;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
+import eu.alefzero.owncloud.authenticator.AuthUtils;\r
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
+\r
+/**\r
+ * This Activity is used to add an ownCloud account to the App\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class AuthenticatorActivity extends AccountAuthenticatorActivity {\r
+    private Thread mAuthThread;\r
+    private final Handler mHandler = new Handler();\r
+\r
+    public static final String PARAM_USERNAME = "param_Username";\r
+    public static final String PARAM_HOSTNAME = "param_Hostname";\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+        setContentView(R.layout.account_setup);\r
+        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() + username.substring(username.lastIndexOf('@')));\r
+            user_text.setText(user_text.getText() + username.substring(0, username.lastIndexOf('@') - 1));\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected Dialog onCreateDialog(int id) {\r
+        final ProgressDialog dialog = new ProgressDialog(this);\r
+        dialog.setMessage("Trying to login");\r
+        dialog.setIndeterminate(true);\r
+        dialog.setCancelable(true);\r
+        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {\r
+            public void onCancel(DialogInterface dialog) {\r
+                Log.i(getClass().getName(), "Login canceled");\r
+                if (mAuthThread != null) {\r
+                    mAuthThread.interrupt();\r
+                    finish();\r
+                }\r
+            }\r
+        });\r
+        return dialog;\r
+    }\r
+\r
+    public void onAuthenticationResult(boolean result, String message) {\r
+        if (result) {\r
+            TextView username_text = (TextView) findViewById(R.id.account_username),\r
+                    password_text = (TextView) findViewById(R.id.account_password);\r
+\r
+            URL url;\r
+            try {\r
+                url = new URL(message);\r
+            } catch (MalformedURLException e) {\r
+                // should never happend\r
+                Log.e(getClass().getName(), "Malformed URL: " + message);\r
+                return;\r
+            }\r
+\r
+            String username = username_text.getText().toString().trim();\r
+            Account account = new Account(username + "@" + url.getHost(), AccountAuthenticator.ACCOUNT_TYPE);\r
+            AccountManager accManager = AccountManager.get(this);\r
+            accManager.addAccountExplicitly(account, password_text.getText().toString(), null);\r
+\r
+            final Intent intent = new Intent();\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, AccountAuthenticator.ACCOUNT_TYPE);\r
+            accManager.setUserData(account, AccountAuthenticator.KEY_OC_URL, url.toString());\r
+\r
+            // TODO prepare this URL during a central service\r
+            intent.putExtra(AccountManager.KEY_USERDATA, username);\r
+            accManager.setUserData(account, AccountAuthenticator.KEY_CONTACT_URL,\r
+                    url.toString().replace(AuthUtils.WEBDAV_PATH_2_0, AuthUtils.CARDDAV_PATH_2_0)\r
+            );\r
+\r
+            setAccountAuthenticatorResult(intent.getExtras());\r
+            setResult(RESULT_OK, intent);\r
+            Bundle bundle = new Bundle();\r
+            bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);\r
+            getContentResolver().startSync(ProviderTableMeta.CONTENT_URI, bundle);\r
+\r
+            dismissDialog(0);\r
+            finish();\r
+        } else {\r
+            Toast.makeText(this, message, Toast.LENGTH_LONG).show();\r
+            dismissDialog(0);\r
+        }\r
+    }\r
+\r
+    public void onCancelClick(View view) {\r
+        Log.i(getClass().getName(), "Account creating canceled");\r
+        this.finish();\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
+        } else {\r
+            url_text.setTextColor(Color.BLACK);\r
+        }\r
+        try {\r
+            String url_str = url_text.getText().toString();\r
+            if (!url_str.startsWith("http://") &&\r
+                    !url_str.startsWith("https://")) {\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(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(Color.BLACK);\r
+        }\r
+        if (hasErrors) {\r
+            return;\r
+        }\r
+        showDialog(0);\r
+        mAuthThread = AuthUtils.attemptAuth(uri,\r
+                username_text.getText().toString(),\r
+                password_text.getText().toString(),\r
+                mHandler,\r
+                AuthenticatorActivity.this);\r
+    }\r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDetailActivity.java
new file mode 100644 (file)
index 0000000..7aeb9c2
--- /dev/null
@@ -0,0 +1,61 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.activity;\r
+\r
+\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.R.id;\r
+import eu.alefzero.owncloud.R.layout;\r
+import eu.alefzero.owncloud.ui.fragment.ActionBar;\r
+import eu.alefzero.owncloud.ui.fragment.FileDetail;\r
+import android.app.Activity;\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.content.res.Configuration;\r
+import android.os.Bundle;\r
+import android.support.v4.app.FragmentActivity;\r
+import android.support.v4.app.FragmentTransaction;\r
+import android.util.AttributeSet;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.Window;\r
+\r
+/**\r
+ * This activity displays the details of a file like\r
+ * its name, its size and so on.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class FileDetailActivity extends FragmentActivity {\r
+  private FileDetail mFileDetail;\r
+  \r
+@Override\r
+protected void onCreate(Bundle savedInstanceState) {\r
+  // TODO Auto-generated method stub\r
+  super.onCreate(savedInstanceState);\r
+  getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+  setContentView(R.layout.file_activity_details);\r
+  \r
+  mFileDetail = new FileDetail();\r
+  FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
+  ft.add(R.id.fileDetail, mFileDetail);\r
+  ft.commit();\r
+  \r
+}\r
+\r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java b/src/eu/alefzero/owncloud/ui/activity/FileDisplayActivity.java
new file mode 100644 (file)
index 0000000..d27061f
--- /dev/null
@@ -0,0 +1,361 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+\r
+package eu.alefzero.owncloud.ui.activity;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.IOException;\r
+import java.util.LinkedList;\r
+import java.util.Stack;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.app.ListActivity;\r
+import android.content.DialogInterface;\r
+import android.content.Intent;\r
+import android.content.DialogInterface.OnCancelListener;\r
+import android.content.res.Configuration;\r
+import android.database.Cursor;\r
+import android.graphics.Bitmap;\r
+import android.graphics.BitmapFactory;\r
+import android.graphics.Matrix;\r
+import android.net.Uri;\r
+import android.os.Bundle;\r
+import android.os.Environment;\r
+import android.support.v4.app.FragmentActivity;\r
+import android.support.v4.app.FragmentTransaction;\r
+import android.text.TextUtils;\r
+import android.util.Log;\r
+import android.view.Menu;\r
+import android.view.MenuInflater;\r
+import android.view.MenuItem;\r
+import android.view.View;\r
+import android.view.Window;\r
+import android.widget.ImageView;\r
+import android.widget.ListView;\r
+import android.widget.TextView;\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.R.id;\r
+import eu.alefzero.owncloud.R.layout;\r
+import eu.alefzero.owncloud.R.menu;\r
+import eu.alefzero.owncloud.R.string;\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
+import eu.alefzero.owncloud.db.DbHandler;\r
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
+import eu.alefzero.owncloud.ui.fragment.FileDetail;\r
+import eu.alefzero.owncloud.ui.fragment.FileList;\r
+import eu.alefzero.owncloud.ui.fragment.ActionBar;\r
+\r
+/**\r
+ * Displays, what files the user has available in his ownCloud.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class FileDisplayActivity extends FragmentActivity {\r
+  private DbHandler mDBHandler;\r
+  private Stack<String> mParents;\r
+  private LinkedList<String> mPath;\r
+  private Account mAccount;\r
+  private Cursor mCursor;\r
+  private boolean mIsDisplayingFile;\r
+\r
+  private static final int DIALOG_CHOOSE_ACCOUNT = 0;\r
+\r
+  @Override\r
+  public void onCreate(Bundle savedInstanceState) {\r
+    super.onCreate(savedInstanceState);\r
+    getWindow().requestFeature(Window.FEATURE_NO_TITLE);\r
+    setContentView(R.layout.files);\r
+    \r
+    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();\r
+    //ft.add(R.id.actionBar, new ActionBar());\r
+    ft.add(R.id.fileList, new FileList());\r
+    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {\r
+      ft.add(R.id.fileDetail, new FileDetail());\r
+    }\r
+    ft.commit();\r
+\r
+    /*getSupportFragmentManager().beginTransaction().add(arg0, arg1);\r
+    FileList fl = new FileList();\r
+    ft.add(R.id.fileList, fl);\r
+    ft.commit();\r
+    /*\r
+\r
+    \r
+    if (savedInstanceState != null) {\r
+      mParents = (Stack<String>)savedInstanceState.getSerializable("parentsStack");\r
+      mIsDisplayingFile = savedInstanceState.getBoolean("isDisplayingFile");\r
+      mPath = (LinkedList<String>)savedInstanceState.getSerializable("path");\r
+    } else {\r
+      mParents = new Stack<String>();\r
+      mPath = new LinkedList<String>();\r
+      mIsDisplayingFile = false;\r
+    }\r
+\r
+    mDBHandler = new DbHandler(getBaseContext());\r
+    requestWindowFeature(Window.FEATURE_NO_TITLE);\r
+    setContentView(R.layout.main);\r
+\r
+    AccountManager accMan = AccountManager.get(this);\r
+    Account[] accounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);\r
+\r
+    if (accounts.length == 0) {\r
+      // using string value since in API7 this constatn is not defined\r
+      // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS\r
+      // and Settings.EXTRA_AUTHORITIES\r
+      Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+      intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});\r
+      startActivity(intent);\r
+    } else if (accounts.length > 1) {\r
+      showDialog(DIALOG_CHOOSE_ACCOUNT);\r
+    } else {\r
+      mAccount = accounts[0];\r
+      populateFileList();\r
+    }*/\r
+  }\r
+\r
+  @Override\r
+  public boolean onOptionsItemSelected(MenuItem item) {\r
+    switch (item.getItemId()) {\r
+      case R.id.settingsItem :\r
+        Intent i = new Intent(this, Preferences.class);\r
+        startActivity(i);\r
+        break;\r
+    }\r
+    return true;\r
+  }\r
+\r
+  @Override\r
+  protected Dialog onCreateDialog(int id) {\r
+    switch (id) {\r
+      case DIALOG_CHOOSE_ACCOUNT:\r
+        return createChooseAccountDialog();\r
+      default:\r
+        throw new IllegalArgumentException("Unknown dialog id: " + id);\r
+    }\r
+  }\r
+  \r
+  @Override\r
+  public boolean onCreateOptionsMenu(Menu menu) {\r
+    MenuInflater inflater = getMenuInflater();\r
+    inflater.inflate(R.menu.menu, menu);\r
+    return true;\r
+  }\r
+    \r
+  private Dialog createChooseAccountDialog() {\r
+    final AccountManager accMan = AccountManager.get(this);\r
+    CharSequence[] items = new CharSequence[accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];\r
+    int i = 0;\r
+    for (Account a : accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)) {\r
+      items[i++] = a.name;\r
+    }\r
+    \r
+    AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
+    builder.setTitle(R.string.common_choose_account);\r
+    builder.setCancelable(true);\r
+    builder.setItems(items, new DialogInterface.OnClickListener() {\r
+        public void onClick(DialogInterface dialog, int item) {\r
+            mAccount = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[item];\r
+            dialog.dismiss();\r
+            populateFileList();\r
+        }\r
+    });\r
+    builder.setOnCancelListener(new OnCancelListener() {\r
+      public void onCancel(DialogInterface dialog) {\r
+        FileDisplayActivity.this.finish();\r
+      }\r
+    });\r
+    AlertDialog alert = builder.create();\r
+    return alert;\r
+  }\r
+\r
+  //@Override\r
+  //public void onBackPressed() {\r
+    /*PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);\r
+    if (mIsDisplayingFile) {\r
+      mIsDisplayingFile = false;\r
+      setContentView(R.layout.main);\r
+      pl = (PathLayout) findViewById(R.id.pathLayout1);\r
+      Uri uri;\r
+      if (mParents.empty()) {\r
+        uri = ProviderTableMeta.CONTENT_URI;\r
+      } else {\r
+        uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek());\r
+      }\r
+      mCursor = managedQuery(uri,\r
+                             null,\r
+                             ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
+                             new String[]{mAccount.name}, null);\r
+  \r
+      if (mCursor.moveToFirst()) {\r
+        String s = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH));\r
+        for (String str : s.split("/")) {\r
+          if (!TextUtils.isEmpty(str))\r
+            pl.push(DisplayUtils.HtmlDecode(str));\r
+        }\r
+      }\r
+      getListView().setAdapter(new FileListListAdapter(mCursor, this));      \r
+      getListView().invalidate();\r
+      return;\r
+    }\r
+    if (mParents.size()==0) {\r
+      super.onBackPressed();\r
+      return;\r
+    } else if (mParents.size() == 1) {\r
+      mParents.pop();\r
+      mPath.removeLast();\r
+      pl.pop();\r
+      mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,\r
+          null,\r
+          ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
+          new String[]{mAccount.name},\r
+          null);\r
+    } else {\r
+      mParents.pop();\r
+      mPath.removeLast();\r
+      pl.pop();\r
+      mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),\r
+          null,\r
+          ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
+          new String[]{mAccount.name},\r
+          null);\r
+    }\r
+    \r
+    setListAdapter(new FileListListAdapter(mCursor, this));\r
+    getListView().invalidate();*/\r
+  //}\r
+\r
+  //@Override\r
+/*  protected void onListItemClick(ListView l, View v, int position, long id) {\r
+    super.onListItemClick(l, v, position, id);\r
+    /*PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);\r
+    if (!mCursor.moveToPosition(position)) {\r
+      throw new IndexOutOfBoundsException("Incorrect item selected");\r
+    }\r
+    if (!mIsDisplayingFile) {\r
+      if (mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {\r
+        String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));\r
+        String dirname = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME));\r
+        pl.push(DisplayUtils.HtmlDecode(dirname));\r
+        mPath.addLast(DisplayUtils.HtmlDecode(dirname));\r
+        mParents.push(id_);\r
+        mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, id_),\r
+                               null,\r
+                               ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
+                               new String[]{mAccount.name}, null);\r
+        setListAdapter(new FileListListAdapter(mCursor, this));\r
+      } else {\r
+        mIsDisplayingFile = true;\r
+        setContentView(R.layout.file_display);\r
+        String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));\r
+        mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, id_),\r
+                               null,\r
+                               null,\r
+                               null,\r
+                               null);\r
+        mCursor.moveToFirst();\r
+        // filename\r
+        TextView tv = (TextView) findViewById(R.id.textView1);\r
+        tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)));\r
+        // filetype\r
+        tv = (TextView) findViewById(R.id.textView2);\r
+        tv.setText(DisplayUtils.convertMIMEtoPrettyPrint(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE))));\r
+        // size\r
+        tv = (TextView) findViewById(R.id.textView3);\r
+        tv.setText(DisplayUtils.bitsToHumanReadable(mCursor.getLong(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH))));\r
+        // modified\r
+        tv = (TextView) findViewById(R.id.textView4);\r
+        tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));\r
+        if (!TextUtils.isEmpty(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH))) &&\r
+            mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).matches("image/*")) {\r
+          ImageView iv = (ImageView) findViewById(R.id.imageView1);\r
+          Bitmap bmp = BitmapFactory.decodeFile(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));\r
+          Matrix m = new Matrix();\r
+          float scale;\r
+          if (bmp.getWidth() > bmp.getHeight()) {\r
+            scale = (float) (200./bmp.getWidth());\r
+          } else {\r
+            scale = (float) (200./bmp.getHeight());\r
+          }\r
+          m.postScale(scale, scale);\r
+          Bitmap newBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);\r
+          iv.setImageBitmap(newBmp);\r
+        }\r
+        setListAdapter(new FileListActionListAdapter(mCursor, this, mAccount));\r
+      }    \r
+      getListView().invalidate();\r
+    } else {\r
+        Intent i = (Intent) getListAdapter().getItem(position);\r
+        if (i.hasExtra("toDownload")) {\r
+          \r
+          Intent intent = new Intent(this, FileDownloader.class);\r
+          intent.putExtra(FileDownloader.EXTRA_FILE_PATH, "/"+((TextView)findViewById(R.id.textView1)).getText().toString());\r
+          intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);\r
+          startService(intent);\r
+          /*\r
+          if (i.getBooleanExtra("toDownload", false)) {\r
+            startActivityForResult(i, 200);\r
+          } else {\r
+            startActivity(i);            \r
+          }*/\r
+       // }\r
+\r
+    //}\r
+//  }\r
+  \r
+  private void populateFileList() {\r
+    if (mParents.empty()) {\r
+      mCursor = getContentResolver().query(ProviderTableMeta.CONTENT_URI,\r
+                                           null,\r
+                                           ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",\r
+                                           new String[]{mAccount.name},\r
+                                           null);\r
+    } else {\r
+      mCursor = getContentResolver().query(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),\r
+                                           null,\r
+                                           ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
+                                           new String[]{mAccount.name}, null);\r
+      if (!mIsDisplayingFile) {\r
+        //PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);\r
+        //for (String s : mPath) {\r
+        //  pl.push(s);\r
+       // }\r
+      }\r
+    }\r
+//    setListAdapter(new FileListListAdapter(mCursor, this));\r
+//    getListView().invalidate();\r
+  }\r
+  \r
+  //@Override\r
+  /*protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+    super.onActivityResult(requestCode, resultCode, data);\r
+  }\r
+  \r
+  @Override\r
+  protected void onSaveInstanceState(Bundle outState) {\r
+    super.onSaveInstanceState(outState);\r
+    outState.putSerializable("parentsStack", mParents);\r
+    outState.putSerializable("path", mPath);\r
+    outState.putBoolean("isDisplayingFile", mIsDisplayingFile);\r
+  }*/\r
+\r
+}
\ No newline at end of file
diff --git a/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java b/src/eu/alefzero/owncloud/ui/activity/LandingActivity.java
new file mode 100644 (file)
index 0000000..b8f1878
--- /dev/null
@@ -0,0 +1,104 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011 Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.activity;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountManager;\r
+import android.app.AlertDialog;\r
+import android.app.Dialog;\r
+import android.content.DialogInterface;\r
+import android.content.Intent;\r
+import android.content.DialogInterface.OnClickListener;\r
+import android.os.Bundle;\r
+import android.support.v4.app.FragmentActivity;\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
+\r
+/**\r
+ * This activity is used as a landing page when the user first opens this app.\r
+ * @author Lennart Rosam\r
+ * \r
+ */\r
+public class LandingActivity extends FragmentActivity implements OnClickListener {\r
+\r
+       public static final int DIALOG_SETUP_ACCOUNT = 1;\r
+       \r
+       @Override\r
+       protected void onCreate(Bundle savedInstanceState) {\r
+               super.onCreate(savedInstanceState);\r
+               setContentView(R.layout.main);\r
+               \r
+               // Check, if there are ownCloud accounts\r
+               if(!accountsAreSetup()){\r
+                       showDialog(DIALOG_SETUP_ACCOUNT);\r
+               }\r
+\r
+       }\r
+\r
+       @Override\r
+       protected Dialog onCreateDialog(int id) {\r
+               Dialog dialog;\r
+               switch(id){\r
+               case DIALOG_SETUP_ACCOUNT:\r
+                       AlertDialog.Builder builder = new AlertDialog.Builder(this);\r
+                       builder.setTitle(R.string.main_tit_accsetup);\r
+                       builder.setMessage(R.string.main_wrn_accsetup);\r
+                       builder.setCancelable(false);\r
+                       builder.setPositiveButton(R.string.common_ok, this);\r
+                       builder.setNegativeButton(R.string.common_cancel, this);\r
+                       dialog = builder.create();\r
+                       break;\r
+               default: \r
+                       dialog = null;\r
+               }\r
+                       \r
+               return dialog;\r
+       }\r
+\r
+       @Override\r
+       public void onClick(DialogInterface dialog, int which) {\r
+               // In any case - we won't need it anymore\r
+               dialog.dismiss();\r
+               switch(which){\r
+               case DialogInterface.BUTTON_POSITIVE:\r
+                       Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");\r
+                       intent.putExtra("authorities",\r
+                                       new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });\r
+                       startActivity(intent);\r
+                       break;\r
+               case DialogInterface.BUTTON_NEGATIVE:\r
+                       finish();\r
+               }\r
+               \r
+       }\r
+       \r
+       /**\r
+        * Checks, whether or not there are any ownCloud accounts \r
+        * setup. \r
+        *  \r
+        * @return true, if there is at least one account.\r
+        */\r
+       private boolean accountsAreSetup() {\r
+               AccountManager accMan = AccountManager.get(this);\r
+               Account[] accounts = accMan\r
+                               .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE); \r
+               return accounts.length > 0;\r
+       }\r
+       \r
+\r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/Preferences.java b/src/eu/alefzero/owncloud/ui/activity/Preferences.java
new file mode 100644 (file)
index 0000000..dadffaf
--- /dev/null
@@ -0,0 +1,168 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.activity;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+import java.util.Vector;\r
+\r
+import eu.alefzero.owncloud.OwnCloudSession;\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.R.id;\r
+import eu.alefzero.owncloud.R.menu;\r
+import eu.alefzero.owncloud.R.xml;\r
+import eu.alefzero.owncloud.db.DbHandler;\r
+\r
+import android.app.Activity;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.preference.Preference;\r
+import android.preference.PreferenceActivity;\r
+import android.preference.PreferenceScreen;\r
+import android.util.Log;\r
+import android.view.ContextMenu;\r
+import android.view.Menu;\r
+import android.view.MenuInflater;\r
+import android.view.MenuItem;\r
+import android.view.View;\r
+import android.view.ContextMenu.ContextMenuInfo;\r
+import android.widget.AdapterView.AdapterContextMenuInfo;\r
+\r
+/**\r
+ * An Activity that allows the user to change the application's settings.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class Preferences extends PreferenceActivity {\r
+  private String TAG = "OwnCloudPreferences";\r
+  private final int mNewSession = 47;\r
+  private final int mEditSession = 48;\r
+  private DbHandler mDbHandler;\r
+  private Vector<OwnCloudSession> mSessions;\r
+  private int mSelectedMenuItem;\r
+  \r
+  @Override\r
+  public void onCreate(Bundle savedInstanceState){\r
+    super.onCreate(savedInstanceState);\r
+    mDbHandler = new DbHandler(getBaseContext());\r
+    mSessions = new Vector<OwnCloudSession>();\r
+    addPreferencesFromResource(R.xml.preferences);\r
+    registerForContextMenu(getListView());\r
+    //populateSessionList();\r
+  }\r
+  \r
+  private void populateSessionList() {\r
+    mSessions.clear();\r
+    mSessions = mDbHandler.getSessionList();\r
+    PreferenceScreen ps = getPreferenceScreen();\r
+    ps.removeAll();\r
+    addPreferencesFromResource(R.xml.preferences);\r
+    for (int i = 0; i < mSessions.size(); i++) {\r
+      Preference preference = new Preference(getBaseContext());\r
+      preference.setTitle(mSessions.get(i).getName());\r
+      URI uri;\r
+      try {\r
+        uri = new URI(mSessions.get(i).getUrl());\r
+      } catch (URISyntaxException e) {\r
+        e.printStackTrace(); // should never happend\r
+        continue;\r
+      }\r
+      preference.setSummary(uri.getScheme() + "://" + uri.getHost()+uri.getPath());\r
+      ps.addPreference(preference);\r
+    }\r
+  }\r
+\r
+  @Override\r
+  public boolean onCreateOptionsMenu(Menu menu) {\r
+    super.onCreateOptionsMenu(menu);\r
+    MenuInflater inflater = getMenuInflater();\r
+    inflater.inflate(R.menu.prefs_menu, menu);\r
+    return true;\r
+  }\r
+  \r
+  @Override\r
+  public boolean onMenuItemSelected(int featureId, MenuItem item) {\r
+    super.onMenuItemSelected(featureId, item);\r
+    Intent intent;\r
+    \r
+    switch (item.getItemId()) {\r
+      case R.id.addSessionItem:\r
+        intent = new Intent(this, PreferencesNewSession.class);\r
+        startActivityForResult(intent, mNewSession);\r
+        break;\r
+      case R.id.SessionContextEdit:\r
+        intent = new Intent(this, PreferencesNewSession.class);\r
+        intent.putExtra("sessionId", mSessions.get(mSelectedMenuItem).getEntryId());\r
+        intent.putExtra("sessionName", mSessions.get(mSelectedMenuItem).getName());\r
+        intent.putExtra("sessionURL", mSessions.get(mSelectedMenuItem).getUrl());\r
+        startActivityForResult(intent, mEditSession);\r
+        break;\r
+      case R.id.SessionContextRemove:\r
+        OwnCloudSession ocs = mSessions.get(mSelectedMenuItem);\r
+        mDbHandler.removeSessionWithId(ocs.getEntryId());\r
+        mSessions.remove(ocs);\r
+        getPreferenceScreen().removePreference(getPreferenceScreen().getPreference(mSelectedMenuItem+1));\r
+        break;\r
+      default:\r
+        Log.w(TAG, "Unknown menu item triggered");\r
+        return false;\r
+    }\r
+    return true;\r
+  }\r
+\r
+  @Override\r
+  protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+    super.onActivityResult(requestCode, resultCode, data);\r
+    if (resultCode == Activity.RESULT_OK) {\r
+      switch (requestCode) {\r
+        case mNewSession:\r
+          mDbHandler.addSession(data.getStringExtra("sessionName"), \r
+                                data.getStringExtra("sessionURL"));\r
+          getPreferenceScreen().removeAll();\r
+          addPreferencesFromResource(R.xml.preferences);\r
+          populateSessionList();\r
+          break;\r
+        case mEditSession:\r
+          mDbHandler.changeSessionFields(data.getIntExtra("sessionId", -1),\r
+                                         data.getStringExtra("sessionName"),\r
+                                         data.getStringExtra("sessionURL"));\r
+          populateSessionList();\r
+          break;\r
+      }\r
+    }\r
+  }\r
+\r
+  @Override\r
+  public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {\r
+    super.onCreateContextMenu(menu, v, menuInfo);\r
+    AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;\r
+    mSelectedMenuItem = info.position-1;\r
+    menu.setHeaderTitle(mSessions.get(mSelectedMenuItem).getName());\r
+    \r
+    MenuInflater inflater = getMenuInflater();\r
+    inflater.inflate(R.menu.session_context_menu, menu);\r
+    \r
+  }\r
+  \r
+  @Override\r
+  protected void onDestroy() {\r
+    mDbHandler.close();\r
+    super.onDestroy();\r
+  }\r
+  \r
+}\r
diff --git a/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java b/src/eu/alefzero/owncloud/ui/activity/PreferencesNewSession.java
new file mode 100644 (file)
index 0000000..9511415
--- /dev/null
@@ -0,0 +1,143 @@
+package eu.alefzero.owncloud.ui.activity;\r
+\r
+import java.net.URI;\r
+import java.net.URISyntaxException;\r
+\r
+import eu.alefzero.owncloud.authenticator.AccountAuthenticatorService;\r
+\r
+import android.accounts.Account;\r
+import android.accounts.AccountAuthenticatorActivity;\r
+import android.accounts.AccountManager;\r
+import android.app.Activity;\r
+import android.content.Intent;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+import android.widget.Button;\r
+import android.widget.EditText;\r
+import android.widget.Toast;\r
+\r
+public class PreferencesNewSession extends AccountAuthenticatorActivity implements OnClickListener {\r
+  private Intent mReturnData;\r
+  private final String TAG = "OwnCloudPreferencesNewSession";\r
+  @Override\r
+  public void onCreate(Bundle savedInstanceState){\r
+    super.onCreate(savedInstanceState);\r
+    //setContentView(R.layout.add_new_session);\r
+    /*\r
+    EditText et;// = (EditText) findViewById(R.id.newSession_sessionName);\r
+    \r
+    et = (EditText) findViewById(R.id.newSession_URL);\r
+    if (getIntent().hasExtra("sessionURL")) {\r
+      try {\r
+        URI uri = new URI(getIntent().getStringExtra("sessionURL"));\r
+        String url = uri.getHost();\r
+        if (uri.getPort() != -1) {\r
+          url += ":" + String.valueOf(uri.getPort());\r
+        }\r
+        if (uri.getPath() != null) {\r
+          url += uri.getPath();\r
+        } else {\r
+          url += "/";\r
+        }\r
+        et.setText(url);\r
+        et = (EditText) findViewById(R.id.newSession_username);\r
+        if (uri.getAuthority() != null) {\r
+          if (uri.getUserInfo().indexOf(':') != -1) {\r
+            et.setText(uri.getUserInfo().substring(0, uri.getUserInfo().indexOf(':')));\r
+            et = (EditText) findViewById(R.id.newSession_password);\r
+            et.setText(uri.getUserInfo().substring(uri.getUserInfo().indexOf(':')+1));\r
+          } else {\r
+            et.setText(uri.getUserInfo());\r
+          }\r
+        }\r
+        \r
+      } catch (URISyntaxException e) {\r
+        Log.e(TAG, "Incorrect URI syntax " + e.getLocalizedMessage());\r
+      }\r
+    }\r
+    \r
+    mReturnData = new Intent();\r
+    setResult(Activity.RESULT_OK, mReturnData);\r
+    ((Button) findViewById(R.id.button1)).setOnClickListener(this);\r
+    ((Button) findViewById(R.id.button2)).setOnClickListener(this);*/\r
+  }\r
+  \r
+  @Override\r
+  protected void onResume() {\r
+    super.onResume();\r
+  }\r
+\r
+  public void onClick(View v) {\r
+   /* switch (v.getId()) {\r
+      case R.id.button1:\r
+        Intent intent = new Intent();\r
+        if (getIntent().hasExtra("sessionId")) {\r
+          intent.putExtra("sessionId", getIntent().getIntExtra("sessionId", -1));\r
+        }\r
+        //String sessionName = ((EditText) findViewById(R.id.newSession_sessionName)).getText().toString();\r
+      //  if (sessionName.trim().equals("") || !isNameValid(sessionName)) {\r
+     //    Toast.makeText(this, R.string.new_session_session_name_error, Toast.LENGTH_LONG).show();\r
+     //     break;\r
+       // }\r
+        URI uri = prepareURI();\r
+        if (uri != null) {\r
+          //intent.putExtra("sessionName", sessionName);\r
+          intent.putExtra("sessionURL", uri.toString());\r
+          setResult(Activity.RESULT_OK, intent);\r
+          AccountManager accMgr = AccountManager.get(this);\r
+          Account a = new Account("OwnCloud", AccountAuthenticatorService.ACCOUNT_TYPE);\r
+          accMgr.addAccountExplicitly(a, "asd", null);\r
+          finish();\r
+        }\r
+        break;\r
+      case R.id.button2:\r
+        setResult(Activity.RESULT_CANCELED);\r
+        finish();\r
+        break;\r
+    }*/\r
+  }\r
+  \r
+  private URI prepareURI() {\r
+    URI uri = null;\r
+   /* String url = "";\r
+    try {\r
+      String username = ((EditText) findViewById(R.id.newSession_username)).getText().toString().trim();\r
+      String password = ((EditText) findViewById(R.id.newSession_password)).getText().toString().trim();\r
+      String hostname = ((EditText) findViewById(R.id.newSession_URL)).getText().toString().trim();\r
+      String scheme;\r
+      if (hostname.matches("[A-Za-z]://")) {\r
+        scheme = hostname.substring(0, hostname.indexOf("://")+3);\r
+        hostname = hostname.substring(hostname.indexOf("://")+3);\r
+      } else {\r
+        scheme = "http://";\r
+      }\r
+      if (!username.equals("")) {\r
+        if (!password.equals("")) {\r
+          username += ":" + password + "@";\r
+        } else {\r
+          username += "@";\r
+        }\r
+      }\r
+      url = scheme + username + hostname;\r
+      Log.i(TAG, url);\r
+      uri = new URI(url);\r
+    } catch (URISyntaxException e) {\r
+      Log.e(TAG, "Incorrect URI syntax " + e.getLocalizedMessage());\r
+      Toast.makeText(this, R.string.new_session_uri_error, Toast.LENGTH_LONG).show();\r
+    }\r
+    */return uri;\r
+  }\r
+  \r
+  private boolean isNameValid(String string) {\r
+    return string.matches("[A-Za-z0-9 _-]*");\r
+  }\r
+  \r
+  @Override\r
+  public void onBackPressed() {\r
+    setResult(Activity.RESULT_CANCELED);\r
+    super.onBackPressed();\r
+  }\r
+  \r
+}\r
index 02f1db2..ab69f07 100644 (file)
-package eu.alefzero.owncloud.ui.adapter;
-
-import java.security.Provider;
-
-import eu.alefzero.owncloud.DisplayUtils;
-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.db.ProviderMeta;
-import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DataSetObserver;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.OnLongClickListener;
-import android.widget.AdapterView;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
-
-public class FileListListAdapter implements ListAdapter {
-
-  private Cursor mCursor;
-  private Context mContext;
-  
-  public FileListListAdapter(Cursor c, Context context) {
-    mCursor = c;
-    mContext = context;
-  }
-  
-  public boolean areAllItemsEnabled() {
-    return true;
-  }
-
-  public boolean isEnabled(int position) {
-    // TODO Auto-generated method stub
-    return true;
-  }
-
-  public int getCount() {
-    // TODO Auto-generated method stub
-    return mCursor.getCount();
-  }
-
-  public Object getItem(int position) {
-    // TODO Auto-generated method stub
-    return null;
-  }
-
-  public long getItemId(int position) {
-    // TODO Auto-generated method stub
-    return 0;
-  }
-
-  public int getItemViewType(int position) {
-    // TODO Auto-generated method stub
-    return 0;
-  }
-
-  public View getView(int position, View convertView, ViewGroup parent) {
-    View v = convertView;
-    if (v == null) {
-      LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-      v = vi.inflate(R.layout.list_layout, null);
-    }
-    if (mCursor.moveToPosition(position)) {
-      TextView tv = (TextView) v.findViewById(R.id.Filename);
-      tv.setText(DisplayUtils.HtmlDecode(mCursor.getString(mCursor.getColumnIndex(ProviderMeta.ProviderTableMeta.FILE_NAME))));
-      if (!mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {
-        ImageView iv = (ImageView) v.findViewById(R.id.imageView1);
-        iv.setImageResource(R.drawable.file);
-      }
-    }
-    
-    return v;
-  }
-
-  public int getViewTypeCount() {
-    // TODO Auto-generated method stub
-    return 4;
-  }
-
-  public boolean hasStableIds() {
-    // TODO Auto-generated method stub
-    return true;
-  }
-
-  public boolean isEmpty() {
-    // TODO Auto-generated method stub
-    return false;
-  }
-
-  public void registerDataSetObserver(DataSetObserver observer) {
-    // TODO Auto-generated method stub
-    
-  }
-
-  public void unregisterDataSetObserver(DataSetObserver observer) {
-    // TODO Auto-generated method stub
-    
-  }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.adapter;\r
+\r
+import java.security.Provider;\r
+\r
+import eu.alefzero.owncloud.DisplayUtils;\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.R.drawable;\r
+import eu.alefzero.owncloud.R.id;\r
+import eu.alefzero.owncloud.R.layout;\r
+import eu.alefzero.owncloud.db.ProviderMeta;\r
+import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
+\r
+import android.content.Context;\r
+import android.database.Cursor;\r
+import android.database.DataSetObserver;\r
+import android.util.Log;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.view.View.OnLongClickListener;\r
+import android.widget.AdapterView;\r
+import android.widget.ImageView;\r
+import android.widget.ListAdapter;\r
+import android.widget.TextView;\r
+import android.widget.AdapterView.OnItemClickListener;\r
+\r
+/**\r
+ * This Adapter populates a ListView with all files and \r
+ * folders in an ownCloud instance.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class FileListListAdapter implements ListAdapter {\r
+\r
+  private Cursor mCursor;\r
+  private Context mContext;\r
+  \r
+  public FileListListAdapter(Cursor c, Context context) {\r
+    mCursor = c;\r
+    mContext = context;\r
+  }\r
+  \r
+  public boolean areAllItemsEnabled() {\r
+    return true;\r
+  }\r
+\r
+  public boolean isEnabled(int position) {\r
+    // TODO Auto-generated method stub\r
+    return true;\r
+  }\r
+\r
+  public int getCount() {\r
+    // TODO Auto-generated method stub\r
+    return mCursor.getCount();\r
+  }\r
+\r
+  public Object getItem(int position) {\r
+    // TODO Auto-generated method stub\r
+    return null;\r
+  }\r
+\r
+  public long getItemId(int position) {\r
+    // TODO Auto-generated method stub\r
+    return 0;\r
+  }\r
+\r
+  public int getItemViewType(int position) {\r
+    // TODO Auto-generated method stub\r
+    return 0;\r
+  }\r
+\r
+  public View getView(int position, View convertView, ViewGroup parent) {\r
+    View v = convertView;\r
+    if (v == null) {\r
+      LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r
+      v = vi.inflate(R.layout.list_layout, null);\r
+    }\r
+    if (mCursor.moveToPosition(position)) {\r
+      TextView tv = (TextView) v.findViewById(R.id.Filename);\r
+      tv.setText(DisplayUtils.HtmlDecode(mCursor.getString(mCursor.getColumnIndex(ProviderMeta.ProviderTableMeta.FILE_NAME))));\r
+      if (!mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {\r
+        ImageView iv = (ImageView) v.findViewById(R.id.imageView1);\r
+        iv.setImageResource(R.drawable.file);\r
+      }\r
+    }\r
+    \r
+    return v;\r
+  }\r
+\r
+  public int getViewTypeCount() {\r
+    // TODO Auto-generated method stub\r
+    return 4;\r
+  }\r
+\r
+  public boolean hasStableIds() {\r
+    // TODO Auto-generated method stub\r
+    return true;\r
+  }\r
+\r
+  public boolean isEmpty() {\r
+    // TODO Auto-generated method stub\r
+    return false;\r
+  }\r
+\r
+  public void registerDataSetObserver(DataSetObserver observer) {\r
+    // TODO Auto-generated method stub\r
+    \r
+  }\r
+\r
+  public void unregisterDataSetObserver(DataSetObserver observer) {\r
+    // TODO Auto-generated method stub\r
+    \r
+  }\r
+}\r
index d14ac0f..694225d 100644 (file)
-package eu.alefzero.owncloud.ui.adapter;
-
-import android.content.Context;
-import android.content.Intent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-import eu.alefzero.owncloud.R;
-import eu.alefzero.owncloud.ui.FileDisplayActivity;
-import eu.alefzero.owncloud.ui.Preferences;
-
-/**
- * Populates the landing screen icons.
- * @author Benutzer
- *
- */
-public class LandingScreenAdapter extends BaseAdapter {
-       
-       private Context mContext;
-
-       private final Integer[] mLandingScreenIcons = { R.drawable.home,
-                       R.drawable.music, R.drawable.contacts,
-                       R.drawable.calendar,
-                       android.R.drawable.ic_menu_agenda,
-                       R.drawable.settings };
-
-       private final Integer[] mLandingScreenTexts = { R.string.main_files,
-                       R.string.main_music, R.string.main_contacts,
-                       R.string.main_calendar, R.string.main_bookmarks,
-                       R.string.main_settings };
-
-       public LandingScreenAdapter(Context context) {
-               mContext = context;
-       }
-
-       @Override
-       public int getCount() {
-               return mLandingScreenIcons.length;
-       }
-
-       @Override
-       /**
-        * Returns the Intent associated with this object
-        * or null if the functionality is not yet implemented
-        */
-       public Object getItem(int position) {
-               Intent intent = new Intent();
-               switch (position) {
-               case 0:
-                       intent.setClass(mContext, FileDisplayActivity.class);
-                       break;
-               case 5:
-                       intent.setClass(mContext, Preferences.class);
-                       break;
-               default:
-                       intent = null;
-               }
-               return intent;
-       }
-
-       @Override
-       public long getItemId(int position) {
-               return position;
-       }
-
-       @Override
-       public View getView(int position, View convertView, ViewGroup parent) {
-               if (convertView == null) {
-                       LayoutInflater inflator = LayoutInflater.from(mContext);
-                       convertView = inflator
-                                       .inflate(R.layout.landing_page_item, null);
-
-                       ImageView icon = (ImageView) convertView
-                                       .findViewById(R.id.gridImage);
-                       TextView iconText = (TextView) convertView
-                                       .findViewById(R.id.gridText);
-
-                       icon.setImageResource(mLandingScreenIcons[position]);
-                       iconText.setText(mLandingScreenTexts[position]);
-               }
-               return convertView;
-       }
-
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.adapter;\r
+\r
+import android.content.Context;\r
+import android.content.Intent;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+import android.widget.BaseAdapter;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.ui.activity.FileDisplayActivity;\r
+import eu.alefzero.owncloud.ui.activity.Preferences;\r
+\r
+/**\r
+ * Populates the landing screen icons.\r
+ * @author Lennart Rosam\r
+ *\r
+ */\r
+public class LandingScreenAdapter extends BaseAdapter {\r
+       \r
+       private Context mContext;\r
+\r
+       private final Integer[] mLandingScreenIcons = { R.drawable.home,\r
+                       R.drawable.music, R.drawable.contacts,\r
+                       R.drawable.calendar,\r
+                       android.R.drawable.ic_menu_agenda,\r
+                       R.drawable.settings };\r
+\r
+       private final Integer[] mLandingScreenTexts = { R.string.main_files,\r
+                       R.string.main_music, R.string.main_contacts,\r
+                       R.string.main_calendar, R.string.main_bookmarks,\r
+                       R.string.main_settings };\r
+\r
+       public LandingScreenAdapter(Context context) {\r
+               mContext = context;\r
+       }\r
+\r
+       @Override\r
+       public int getCount() {\r
+               return mLandingScreenIcons.length;\r
+       }\r
+\r
+       @Override\r
+       /**\r
+        * Returns the Intent associated with this object\r
+        * or null if the functionality is not yet implemented\r
+        */\r
+       public Object getItem(int position) {\r
+               Intent intent = new Intent();\r
+               switch (position) {\r
+               case 0:\r
+                       intent.setClass(mContext, FileDisplayActivity.class);\r
+                       break;\r
+               case 5:\r
+                       intent.setClass(mContext, Preferences.class);\r
+                       break;\r
+               default:\r
+                       intent = null;\r
+               }\r
+               return intent;\r
+       }\r
+\r
+       @Override\r
+       public long getItemId(int position) {\r
+               return position;\r
+       }\r
+\r
+       @Override\r
+       public View getView(int position, View convertView, ViewGroup parent) {\r
+               if (convertView == null) {\r
+                       LayoutInflater inflator = LayoutInflater.from(mContext);\r
+                       convertView = inflator\r
+                                       .inflate(R.layout.landing_page_item, null);\r
+\r
+                       ImageView icon = (ImageView) convertView\r
+                                       .findViewById(R.id.gridImage);\r
+                       TextView iconText = (TextView) convertView\r
+                                       .findViewById(R.id.gridText);\r
+\r
+                       icon.setImageResource(mLandingScreenIcons[position]);\r
+                       iconText.setText(mLandingScreenTexts[position]);\r
+               }\r
+               return convertView;\r
+       }\r
+\r
+}\r
index 9a3291b..8810be7 100644 (file)
@@ -1,45 +1,66 @@
-package eu.alefzero.owncloud.ui.fragment;
-
-import eu.alefzero.owncloud.PathLayout;
-import eu.alefzero.owncloud.R;
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-public class ActionBar extends Fragment {
-
-  @Override
-  public void onCreate(Bundle savedInstanceState) {
-    super.onCreate(savedInstanceState);
-    
-  }
-  @Override
-  public View onCreateView(LayoutInflater inflater, ViewGroup container,
-      Bundle savedInstanceState) {
-    View v = inflater.inflate(R.layout.action_bar, container, false);
-    return v;
-  }
-  
-  @Override
-  public void onAttach(Activity activity) {
-    super.onAttach(activity);
-  }
-  
-  public void setPath(String path) {
-    if (getPathLayout() != null)
-      getPathLayout().addPath(path);
-  }
-  
-  public String getCurrentPath() {
-    if (getPathLayout() != null)
-       return getPathLayout().getFullPath();
-    return "";
-  }
-  
-  private PathLayout getPathLayout() {
-    return (PathLayout) getActivity().findViewById(R.id.pathLayout1);
-  }
-}
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.fragment;\r
+\r
+import eu.alefzero.owncloud.R;\r
+import android.app.Activity;\r
+import android.os.Bundle;\r
+import android.support.v4.app.Fragment;\r
+import android.view.LayoutInflater;\r
+import android.view.View;\r
+import android.view.ViewGroup;\r
+\r
+/**\r
+ * A custom ActionBar implementation used in the FileDisplayActivity\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class ActionBar extends Fragment {\r
+\r
+  @Override\r
+  public void onCreate(Bundle savedInstanceState) {\r
+    super.onCreate(savedInstanceState);\r
+    \r
+  }\r
+  @Override\r
+  public View onCreateView(LayoutInflater inflater, ViewGroup container,\r
+      Bundle savedInstanceState) {\r
+    View v = inflater.inflate(R.layout.action_bar, container, false);\r
+    return v;\r
+  }\r
+  \r
+  @Override\r
+  public void onAttach(Activity activity) {\r
+    super.onAttach(activity);\r
+  }\r
+  \r
+  public void setPath(String path) {\r
+    if (getPathLayout() != null)\r
+      getPathLayout().addPath(path);\r
+  }\r
+  \r
+  public String getCurrentPath() {\r
+    if (getPathLayout() != null)\r
+       return getPathLayout().getFullPath();\r
+    return "";\r
+  }\r
+  \r
+  private PathLayout getPathLayout() {\r
+    return (PathLayout) getActivity().findViewById(R.id.pathLayout1);\r
+  }\r
+}\r
index de11bc6..50f35a5 100644 (file)
@@ -1,3 +1,20 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
 import eu.alefzero.owncloud.R;\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
 import eu.alefzero.owncloud.R;\r
@@ -13,6 +30,11 @@ import android.view.ViewGroup;
 import android.widget.TextView;\r
 import android.widget.Toast;\r
 \r
 import android.widget.TextView;\r
 import android.widget.Toast;\r
 \r
+/**\r
+ * This Fragment is used to display the details about a file.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
 public class FileDetail extends Fragment {\r
   \r
   public Intent mIntent;\r
 public class FileDetail extends Fragment {\r
   \r
   public Intent mIntent;\r
index e3d1f26..1fb8abc 100644 (file)
@@ -1,10 +1,27 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
 import eu.alefzero.owncloud.R;\r
 import eu.alefzero.owncloud.R.id;\r
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
 import eu.alefzero.owncloud.R;\r
 import eu.alefzero.owncloud.R.id;\r
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
-import eu.alefzero.owncloud.ui.FileDetailActivity;\r
+import eu.alefzero.owncloud.ui.activity.FileDetailActivity;\r
 import eu.alefzero.owncloud.ui.adapter.FileListListAdapter;\r
 import eu.alefzero.owncloud.ui.fragment.ActionBar;\r
 import android.accounts.Account;\r
 import eu.alefzero.owncloud.ui.adapter.FileListListAdapter;\r
 import eu.alefzero.owncloud.ui.fragment.ActionBar;\r
 import android.accounts.Account;\r
@@ -25,6 +42,11 @@ import android.widget.ListView;
 import android.widget.TextView;\r
 import android.widget.Toast;\r
 \r
 import android.widget.TextView;\r
 import android.widget.Toast;\r
 \r
+/**\r
+ * A Fragment that lists all files and folders in a given path.\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
 public class FileList extends ListFragment {\r
   private Cursor mCursor;\r
   private Account mAccount;\r
 public class FileList extends ListFragment {\r
   private Cursor mCursor;\r
   private Account mAccount;\r
index 6965114..dd7ca31 100644 (file)
@@ -1,3 +1,20 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
 import android.content.Intent;\r
 package eu.alefzero.owncloud.ui.fragment;\r
 \r
 import android.content.Intent;\r
@@ -13,6 +30,13 @@ import android.widget.Toast;
 import eu.alefzero.owncloud.R;\r
 import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;\r
 \r
 import eu.alefzero.owncloud.R;\r
 import eu.alefzero.owncloud.ui.adapter.LandingScreenAdapter;\r
 \r
+/**\r
+ * Used on the Landing page to display what Components of \r
+ * the ownCloud there are. Like Files, Music, Contacts, etc.\r
+ * \r
+ * @author Lennart Rosam\r
+ *\r
+ */\r
 public class LandingPageFragment extends Fragment implements OnItemClickListener {\r
 \r
        @Override\r
 public class LandingPageFragment extends Fragment implements OnItemClickListener {\r
 \r
        @Override\r
diff --git a/src/eu/alefzero/owncloud/ui/fragment/PathLayout.java b/src/eu/alefzero/owncloud/ui/fragment/PathLayout.java
new file mode 100644 (file)
index 0000000..e9714c7
--- /dev/null
@@ -0,0 +1,117 @@
+/* ownCloud Android client application\r
+ *   Copyright (C) 2011  Bartek Przybylski\r
+ *\r
+ *   This program is free software: you can redistribute it and/or modify\r
+ *   it under the terms of the GNU General Public License as published by\r
+ *   the Free Software Foundation, either version 3 of the License, or\r
+ *   (at your option) any later version.\r
+ *\r
+ *   This program is distributed in the hope that it will be useful,\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *   GNU General Public License for more details.\r
+ *\r
+ *   You should have received a copy of the GNU General Public License\r
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ */\r
+package eu.alefzero.owncloud.ui.fragment;\r
+\r
+import java.util.LinkedList;\r
+import java.util.Stack;\r
+\r
+import eu.alefzero.owncloud.R;\r
+import eu.alefzero.owncloud.R.drawable;\r
+\r
+import android.content.Context;\r
+import android.util.AttributeSet;\r
+import android.widget.HorizontalScrollView;\r
+import android.widget.ImageView;\r
+import android.widget.LinearLayout;\r
+import android.widget.ScrollView;\r
+import android.widget.TextView;\r
+\r
+/**\r
+ * Part of the ActionBar Layout\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class PathLayout extends LinearLayout {\r
+\r
+  private LinkedList<String> paths;\r
+  ScrollView internalScroll;\r
+  LinearLayout view;\r
+\r
+  public PathLayout(Context context) {\r
+    super(context);\r
+    initialize();\r
+  }\r
+  \r
+  public PathLayout(Context context, AttributeSet attrs) {\r
+    super(context, attrs);\r
+    initialize();\r
+  }\r
+\r
+  public String pop() {\r
+    if (paths.size() == 0) {\r
+      return null;\r
+    }\r
+    int start = paths.size()*2-2;\r
+    int count = 2;\r
+    if (paths.size() == 1) {\r
+      start++;\r
+      count--;\r
+    }\r
+    view.removeViews(start, count);\r
+    return paths.removeLast();\r
+  }\r
+\r
+  public void addPath(String path) {\r
+    for (String s : path.split("/")) if (s.length() != 0) push(s);\r
+  }\r
+  \r
+  public void push(String path) {\r
+    // its weird that we cannot declare static imgView as path separator\r
+    if (paths.size() != 0) {\r
+      ImageView iv = new ImageView(getContext());\r
+      iv.setImageDrawable(getResources().getDrawable(R.drawable.breadcrumb));\r
+      iv.setPadding(2, 0, 2, 0);\r
+      view.addView(iv);\r
+    }\r
+    TextView tv = new TextView(getContext());\r
+    tv.setLayoutParams(getLayoutParams());\r
+    tv.setText(path);\r
+    view.addView(tv);\r
+    HorizontalScrollView hsv = (HorizontalScrollView) internalScroll.getChildAt(0);\r
+    hsv.smoothScrollTo(hsv.getMaxScrollAmount()*2, 0);\r
+    paths.addLast(path);\r
+  }\r
+  \r
+  public String peek() {\r
+    return paths.peek();\r
+  }\r
+\r
+  public String getFullPath() {\r
+    String ret = new String();\r
+    for (int i = 0; i < paths.size(); i++) {\r
+      ret += "/" + paths.get(i);\r
+    }\r
+    return ret;\r
+  }\r
+  \r
+  private void initialize() {\r
+    paths = new LinkedList<String>();\r
+    internalScroll = new ScrollView(getContext());\r
+    internalScroll.setFillViewport(true);\r
+    HorizontalScrollView hsv = new HorizontalScrollView(getContext());\r
+    hsv.setSmoothScrollingEnabled(true);\r
+    internalScroll.addView(hsv);\r
+    view = new LinearLayout(getContext());\r
+    addView(internalScroll);\r
+    hsv.addView(view);\r
+    ImageView iv = new ImageView(getContext());\r
+    iv.setImageDrawable(getResources().getDrawable(R.drawable.breadcrumb));\r
+    view.addView(iv);\r
+  }\r
+\r
+}\r
index c7acab9..8fcac16 100644 (file)
@@ -1,19 +1,36 @@
-package eu.alefzero.webdav;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-
-public class HttpMkCol extends HttpEntityEnclosingRequestBase {
-
-  public final static String METHOD_NAME = "MKCOL";
-  
-  public HttpMkCol(final String uri) {
-    setURI(URI.create(uri));
-  }
-
-  @Override
-  public String getMethod() {
-    return METHOD_NAME;
-  }
-}
+/* 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
index f7b930c..a3d0063 100644 (file)
@@ -1,32 +1,49 @@
-package eu.alefzero.webdav;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-import org.apache.http.protocol.HTTP;
-
-public class HttpPropFind extends HttpEntityEnclosingRequestBase {
-
-  public final static String METHOD_NAME = "PROPFIND";
-  
-  public HttpPropFind(final URI uri) {
-    super();
-    setURI(uri);
-  }
-
-  public HttpPropFind(final String uri) {
-    this.setDepth("1");
-    setURI(URI.create(uri));
-    this.setHeader(HTTP.CONTENT_TYPE, "text/xml" + HTTP.CHARSET_PARAM + HTTP.UTF_8.toLowerCase());
-  }
-  
-  @Override
-  public String getMethod() {
-    return METHOD_NAME;
-  }
-  
-  public void setDepth(String depth) {
-    this.setHeader("Depth", depth);
-  }
-  
-}
+/* 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
index bdd352e..82898d3 100644 (file)
@@ -1,26 +1,43 @@
-package eu.alefzero.webdav;
-
-import java.net.URI;
-
-import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
-
-public class HttpPropPatch extends HttpEntityEnclosingRequestBase {
-
-  public static final String METHOD_NAME = "PROPPATCH";
-  
-  public HttpPropPatch(URI uri) {
-    super();
-    setURI(uri);
-  }
-  
-  public HttpPropPatch(final String uri) {
-    super();
-    setURI(URI.create(uri));
-  }
-  
-  @Override
-  public String getMethod() {
-    return METHOD_NAME;
-  }
-  
-}
+/* 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 ef09254..5656fde 100644 (file)
@@ -1,21 +1,38 @@
-package eu.alefzero.webdav;
-
-import java.util.List;
-import java.util.ListIterator;
-
-import org.w3c.dom.Document;
-
-import android.util.Xml;
-
-public class TreeNodeContainer extends TreeNode {
-  
-  @Override
-  void refreshData(Document document) {
-    ListIterator<TreeNode> iterator = children_.listIterator();
-    while (iterator.hasNext()) {
-      iterator.next().refreshData(document);
-    }
-  }
-  
-  private List<TreeNode> children_;
-}
+/* 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.util.List;\r
+import java.util.ListIterator;\r
+\r
+import org.w3c.dom.Document;\r
+\r
+import android.util.Xml;\r
+\r
+public class TreeNodeContainer extends TreeNode {\r
+  \r
+  @Override\r
+  void refreshData(Document document) {\r
+    ListIterator<TreeNode> iterator = children_.listIterator();\r
+    while (iterator.hasNext()) {\r
+      iterator.next().refreshData(document);\r
+    }\r
+  }\r
+  \r
+  private List<TreeNode> children_;\r
+}\r
diff --git a/src/eu/alefzero/webdav/WebdavClient.java b/src/eu/alefzero/webdav/WebdavClient.java
new file mode 100644 (file)
index 0000000..4d97ceb
--- /dev/null
@@ -0,0 +1,196 @@
+/* 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.io.BufferedInputStream;\r
+import java.io.BufferedOutputStream;\r
+import java.io.File;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+import java.io.OutputStreamWriter;\r
+\r
+import org.apache.http.HttpHost;\r
+import org.apache.http.HttpResponse;\r
+import org.apache.http.HttpStatus;\r
+import org.apache.http.HttpVersion;\r
+import org.apache.http.auth.AuthScope;\r
+import org.apache.http.auth.UsernamePasswordCredentials;\r
+import org.apache.http.client.methods.HttpGet;\r
+import org.apache.http.client.methods.HttpPut;\r
+import org.apache.http.conn.ClientConnectionManager;\r
+import org.apache.http.conn.params.ConnManagerPNames;\r
+import org.apache.http.conn.params.ConnPerRouteBean;\r
+import org.apache.http.conn.scheme.PlainSocketFactory;\r
+import org.apache.http.conn.scheme.Scheme;\r
+import org.apache.http.conn.scheme.SchemeRegistry;\r
+import org.apache.http.conn.ssl.SSLSocketFactory;\r
+import org.apache.http.entity.FileEntity;\r
+import org.apache.http.entity.mime.content.FileBody;\r
+import org.apache.http.impl.auth.BasicScheme;\r
+import org.apache.http.impl.client.DefaultHttpClient;\r
+import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;\r
+import org.apache.http.params.BasicHttpParams;\r
+import org.apache.http.params.HttpParams;\r
+import org.apache.http.params.HttpProtocolParams;\r
+import org.apache.http.protocol.BasicHttpContext;\r
+\r
+import eu.alefzero.owncloud.authenticator.EasySSLSocketFactory;\r
+\r
+import android.net.Uri;\r
+import android.util.Log;\r
+\r
+/**\r
+ * A basic WebDAV-Client\r
+ * @author Bartek Przybylski\r
+ *\r
+ */\r
+public class WebdavClient {\r
+  private DefaultHttpClient mHttpClient;\r
+  private BasicHttpContext mHttpContext;\r
+  private HttpHost mTargetHost;\r
+  private SchemeRegistry mSchemeRegistry;\r
+  private Uri mUri;\r
+  final private static String TAG = "WebdavClient";\r
+  \r
+  public WebdavClient(Uri uri) {\r
+    mUri = uri;\r
+    mSchemeRegistry = new SchemeRegistry();\r
+    setupHttpClient();\r
+  }\r
+  \r
+  public void setCredentials(String username, String password) {\r
+    // determine default port for http or https\r
+    int targetPort = mTargetHost.getPort() == -1 ? \r
+                        ( mUri.getScheme().equals("https") ? 443 : 80)\r
+                        : mUri.getPort();\r
+\r
+    mHttpClient.getCredentialsProvider().setCredentials(\r
+        new AuthScope(mUri.getHost(), targetPort), \r
+        new UsernamePasswordCredentials(username, password));\r
+    BasicScheme basicAuth = new BasicScheme();\r
+    mHttpContext.setAttribute("preemptive-auth", basicAuth);\r
+  }\r
+  \r
+  public void allowUnsignedCertificates() {\r
+    // https\r
+    mSchemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));\r
+  }\r
+  \r
+  public boolean downloadFile(String filepath, File targetPath) {\r
+    HttpGet get = new HttpGet(mUri.toString() + filepath.replace(" ", "%20"));\r
+    get.setHeader("Host", mUri.getHost());\r
+    get.setHeader("User-Agent", "Android-ownCloud");\r
+    \r
+    try {\r
+      HttpResponse response = mHttpClient.execute(mTargetHost, get, mHttpContext);\r
+      if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {\r
+        return false;\r
+      }\r
+      BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());\r
+      FileOutputStream fos = new FileOutputStream(targetPath);\r
+      \r
+      byte[] bytes = new byte[512];\r
+      int readResult;\r
+      while ((readResult = bis.read(bytes)) != -1) fos.write(bytes, 0, readResult);\r
+      \r
+    } catch (IOException e) {\r
+      e.printStackTrace();\r
+      return false;\r
+    }\r
+    return true;\r
+  }\r
+  \r
+  void getFileList(String dirPath) {\r
+    \r
+  }\r
+  \r
+  public boolean putFile(String localFile,\r
+                  String remoteTarget,\r
+                  String contentType) {\r
+    boolean result = true;\r
+    HttpPut method = new HttpPut(mUri.toString() + remoteTarget.replace(" ", "%20"));\r
+    method.setHeader("Content-type", contentType);\r
+    method.setHeader("Host", mUri.getHost());\r
+    method.setHeader("User-Agent", "Android-ownCloud");\r
+\r
+    try {\r
+      FileBody fb = new FileBody(new File(localFile, contentType));\r
+      final FileEntity fileEntity = new FileEntity(new File(localFile), contentType);\r
+\r
+      method.setEntity(fileEntity);\r
+      Log.i(TAG, "executing:" + method.getRequestLine().toString());\r
+\r
+      mHttpClient.execute(mTargetHost, method, mHttpContext);\r
+      /*mHandler.post(new Runnable() {\r
+      public void run() {\r
+        Uploader.this.PartialupdateUpload(c.getString(c.getColumnIndex(Media.DATA)),\r
+                                                  c.getString(c.getColumnIndex(Media.DISPLAY_NAME)),\r
+                                                  mUploadPath + (mUploadPath.equals("/")?"":"/"),\r
+                                                  fileEntity.getContentType().getValue(),\r
+                                                  fileEntity.getContentLength()+"");\r
+      }\r
+    });\r
+    Log.i(TAG, "Uploading, done");\r
+*/\r
+      Log.i(TAG, "Uploading, done");\r
+    } catch (final Exception e) {\r
+      Log.i(TAG, ""+e.getMessage());\r
+      result = false;\r
+    }\r
+    \r
+    return result;\r
+  }\r
+  \r
+  public boolean createDirectory(String path) {\r
+    HttpMkCol method = new HttpMkCol(mUri.toString() + path + "/");\r
+    method.setHeader("User-Agent", "Android-ownCloud");\r
+    \r
+    try {\r
+      mHttpClient.execute(mTargetHost, method, mHttpContext);\r
+      Log.i(TAG, "Creating dir completed");\r
+    } catch (final Exception e) {\r
+      e.printStackTrace();\r
+      return false;\r
+    }\r
+    return true;\r
+  }\r
+  \r
+  private void setupHttpClient() {\r
+    // http scheme\r
+    mSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));\r
+    mSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));\r
+    \r
+    HttpParams params = new BasicHttpParams();\r
+    params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);\r
+    params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));\r
+    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);\r
+    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);\r
+\r
+    mHttpContext = new BasicHttpContext();\r
+    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, mSchemeRegistry);\r
+\r
+    int port = mUri.getPort() == -1 ? \r
+                 mUri.getScheme().equals("https") ? 443 : 80\r
+               : mUri.getPort();\r
+    \r
+    mTargetHost = new HttpHost(mUri.getHost(), port, mUri.getScheme());\r
+    \r
+    mHttpClient = new DefaultHttpClient(cm, params);\r
+  }\r
+}\r