1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 package eu
.alefzero
.owncloud
;
21 import java
.util
.LinkedList
;
22 import java
.util
.Stack
;
24 import android
.accounts
.Account
;
25 import android
.accounts
.AccountManager
;
26 import android
.app
.AlertDialog
;
27 import android
.app
.Dialog
;
28 import android
.app
.ListActivity
;
29 import android
.content
.DialogInterface
;
30 import android
.content
.Intent
;
31 import android
.content
.DialogInterface
.OnCancelListener
;
32 import android
.content
.res
.Configuration
;
33 import android
.database
.Cursor
;
34 import android
.graphics
.Bitmap
;
35 import android
.graphics
.BitmapFactory
;
36 import android
.graphics
.Matrix
;
37 import android
.net
.Uri
;
38 import android
.os
.Bundle
;
39 import android
.text
.TextUtils
;
40 import android
.util
.Log
;
41 import android
.view
.Menu
;
42 import android
.view
.MenuInflater
;
43 import android
.view
.MenuItem
;
44 import android
.view
.View
;
45 import android
.view
.Window
;
46 import android
.widget
.ImageView
;
47 import android
.widget
.ListView
;
48 import android
.widget
.TextView
;
49 import eu
.alefzero
.owncloud
.authenticator
.AccountAuthenticator
;
50 import eu
.alefzero
.owncloud
.db
.ProviderMeta
.ProviderTableMeta
;
52 public class OwnCloudMainScreen
extends ListActivity
{
53 private DbHandler mDBHandler
;
54 private Stack
<String
> mParents
;
55 private LinkedList
<String
> mPath
;
56 private Account mAccount
;
57 private Cursor mCursor
;
58 private boolean mIsDisplayingFile
;
60 private static final int DIALOG_CHOOSE_ACCOUNT
= 0;
62 @SuppressWarnings("unchecked")
64 public void onCreate(Bundle savedInstanceState
) {
65 super.onCreate(savedInstanceState
);
67 if (savedInstanceState
!= null
) {
68 mParents
= (Stack
<String
>)savedInstanceState
.getSerializable("parentsStack");
69 mIsDisplayingFile
= savedInstanceState
.getBoolean("isDisplayingFile");
70 mPath
= (LinkedList
<String
>)savedInstanceState
.getSerializable("path");
72 mParents
= new Stack
<String
>();
73 mPath
= new LinkedList
<String
>();
74 mIsDisplayingFile
= false
;
77 mDBHandler
= new DbHandler(getBaseContext());
78 requestWindowFeature(Window
.FEATURE_NO_TITLE
);
79 setContentView(R
.layout
.main
);
81 AccountManager accMan
= AccountManager
.get(this);
82 Account
[] accounts
= accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
);
84 if (accounts
.length
== 0) {
85 // using string value since in API7 this constatn is not defined
86 // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS
87 // and Settings.EXTRA_AUTHORITIES
88 Intent intent
= new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
89 intent
.putExtra("authorities", new String
[] {AccountAuthenticator
.AUTH_TOKEN_TYPE
});
90 startActivity(intent
);
91 } else if (accounts
.length
> 1) {
92 showDialog(DIALOG_CHOOSE_ACCOUNT
);
94 mAccount
= accounts
[0];
100 public boolean onOptionsItemSelected(MenuItem item
) {
101 switch (item
.getItemId()) {
102 case R
.id
.settingsItem
:
103 Intent i
= new Intent(this, Preferences
.class);
111 protected Dialog
onCreateDialog(int id
) {
113 case DIALOG_CHOOSE_ACCOUNT
:
114 return createChooseAccountDialog();
116 throw new IllegalArgumentException("Unknown dialog id: " + id
);
121 public boolean onCreateOptionsMenu(Menu menu
) {
122 MenuInflater inflater
= getMenuInflater();
123 inflater
.inflate(R
.menu
.menu
, menu
);
128 protected void onDestroy() {
133 private Dialog
createChooseAccountDialog() {
134 final AccountManager accMan
= AccountManager
.get(this);
135 CharSequence
[] items
= new CharSequence
[accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
).length
];
137 for (Account a
: accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
)) {
141 AlertDialog
.Builder builder
= new AlertDialog
.Builder(this);
142 builder
.setTitle(R
.string
.common_choose_account
);
143 builder
.setCancelable(true
);
144 builder
.setItems(items
, new DialogInterface
.OnClickListener() {
145 public void onClick(DialogInterface dialog
, int item
) {
146 mAccount
= accMan
.getAccountsByType(AccountAuthenticator
.ACCOUNT_TYPE
)[item
];
151 builder
.setOnCancelListener(new OnCancelListener() {
152 public void onCancel(DialogInterface dialog
) {
153 OwnCloudMainScreen
.this.finish();
156 AlertDialog alert
= builder
.create();
161 public void onBackPressed() {
162 PathLayout pl
= (PathLayout
) findViewById(R
.id
.pathLayout1
);
163 if (mIsDisplayingFile
) {
164 mIsDisplayingFile
= false
;
165 setContentView(R
.layout
.main
);
166 pl
= (PathLayout
) findViewById(R
.id
.pathLayout1
);
168 if (mParents
.empty()) {
169 uri
= ProviderTableMeta
.CONTENT_URI
;
171 uri
= Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_DIR
, mParents
.peek());
173 mCursor
= managedQuery(uri
,
175 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?",
176 new String
[]{mAccount
.name
}, null
);
178 if (mCursor
.moveToFirst()) {
179 String s
= mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_PATH
));
180 for (String str
: s
.split("/")) {
181 if (!TextUtils
.isEmpty(str
))
182 pl
.push(DisplayUtils
.HtmlDecode(str
));
185 getListView().setAdapter(new FileListListAdapter(mCursor
, this));
186 getListView().invalidate();
189 if (mParents
.size()==0) {
190 super.onBackPressed();
192 } else if (mParents
.size() == 1) {
196 mCursor
= managedQuery(ProviderTableMeta
.CONTENT_URI
,
198 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?",
199 new String
[]{mAccount
.name
},
205 mCursor
= managedQuery(Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_DIR
, mParents
.peek()),
207 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?",
208 new String
[]{mAccount
.name
},
212 setListAdapter(new FileListListAdapter(mCursor
, this));
213 getListView().invalidate();
217 protected void onListItemClick(ListView l
, View v
, int position
, long id
) {
218 super.onListItemClick(l
, v
, position
, id
);
219 PathLayout pl
= (PathLayout
) findViewById(R
.id
.pathLayout1
);
220 if (!mCursor
.moveToPosition(position
)) {
221 throw new IndexOutOfBoundsException("Incorrect item selected");
223 if (!mIsDisplayingFile
) {
224 if (mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_CONTENT_TYPE
)).equals("DIR")) {
225 String id_
= mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
._ID
));
226 String dirname
= mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_NAME
));
227 pl
.push(DisplayUtils
.HtmlDecode(dirname
));
228 mPath
.addLast(DisplayUtils
.HtmlDecode(dirname
));
230 mCursor
= managedQuery(Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_DIR
, id_
),
232 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?",
233 new String
[]{mAccount
.name
}, null
);
234 setListAdapter(new FileListListAdapter(mCursor
, this));
236 mIsDisplayingFile
= true
;
237 setContentView(R
.layout
.file_display
);
238 String id_
= mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
._ID
));
239 mCursor
= managedQuery(Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_FILE
, id_
),
244 mCursor
.moveToFirst();
246 TextView tv
= (TextView
) findViewById(R
.id
.textView1
);
247 tv
.setText(mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_NAME
)));
249 tv
= (TextView
) findViewById(R
.id
.textView2
);
250 tv
.setText(DisplayUtils
.convertMIMEtoPrettyPrint(mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_CONTENT_TYPE
))));
252 tv
= (TextView
) findViewById(R
.id
.textView3
);
253 tv
.setText(DisplayUtils
.bitsToHumanReadable(mCursor
.getLong(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_CONTENT_LENGTH
))));
255 tv
= (TextView
) findViewById(R
.id
.textView4
);
256 tv
.setText(mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_MODIFIED
)));
257 if (!TextUtils
.isEmpty(mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_STORAGE_PATH
))) &&
258 mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_CONTENT_TYPE
)).matches("image/*")) {
259 ImageView iv
= (ImageView
) findViewById(R
.id
.imageView1
);
260 Bitmap bmp
= BitmapFactory
.decodeFile(mCursor
.getString(mCursor
.getColumnIndex(ProviderTableMeta
.FILE_STORAGE_PATH
)));
261 Matrix m
= new Matrix();
263 if (bmp
.getWidth() > bmp
.getHeight()) {
264 scale
= (float) (200./bmp
.getWidth());
266 scale
= (float) (200./bmp
.getHeight());
268 m
.postScale(scale
, scale
);
269 Bitmap newBmp
= Bitmap
.createBitmap(bmp
, 0, 0, bmp
.getWidth(), bmp
.getHeight(), m
, true
);
270 iv
.setImageBitmap(newBmp
);
272 setListAdapter(new FileListActionListAdapter(mCursor
, this, mAccount
));
274 getListView().invalidate();
277 Intent i
= (Intent
) getListAdapter().getItem(position
);
278 if (i
.hasExtra("toDownload")) {
279 if (i
.getBooleanExtra("toDownload", false
)) {
280 startActivityForResult(i
, 200);
285 } catch (ClassCastException e
) {}
289 private void populateFileList() {
290 if (mParents
.empty()) {
291 mCursor
= getContentResolver().query(ProviderTableMeta
.CONTENT_URI
,
293 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+"=?",
294 new String
[]{mAccount
.name
},
297 mCursor
= getContentResolver().query(Uri
.withAppendedPath(ProviderTableMeta
.CONTENT_URI_DIR
, mParents
.peek()),
299 ProviderTableMeta
.FILE_ACCOUNT_OWNER
+ "=?",
300 new String
[]{mAccount
.name
}, null
);
301 if (!mIsDisplayingFile
) {
302 PathLayout pl
= (PathLayout
) findViewById(R
.id
.pathLayout1
);
303 for (String s
: mPath
) {
308 setListAdapter(new FileListListAdapter(mCursor
, this));
309 getListView().invalidate();
313 protected void onActivityResult(int requestCode
, int resultCode
, Intent data
) {
314 super.onActivityResult(requestCode
, resultCode
, data
);
318 protected void onSaveInstanceState(Bundle outState
) {
319 super.onSaveInstanceState(outState
);
320 outState
.putSerializable("parentsStack", mParents
);
321 outState
.putSerializable("path", mPath
);
322 outState
.putBoolean("isDisplayingFile", mIsDisplayingFile
);