65592b190f9c774a4ecef1ae23cdd1bf8ea2e74c
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / OwnCloudMainScreen.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 *
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.
8 *
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.
13 *
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/>.
16 *
17 */
18
19 package eu.alefzero.owncloud;
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.IOException;
25 import java.util.LinkedList;
26 import java.util.Stack;
27
28 import android.accounts.Account;
29 import android.accounts.AccountManager;
30 import android.app.AlertDialog;
31 import android.app.Dialog;
32 import android.app.ListActivity;
33 import android.content.DialogInterface;
34 import android.content.Intent;
35 import android.content.DialogInterface.OnCancelListener;
36 import android.content.res.Configuration;
37 import android.database.Cursor;
38 import android.graphics.Bitmap;
39 import android.graphics.BitmapFactory;
40 import android.graphics.Matrix;
41 import android.net.Uri;
42 import android.os.Bundle;
43 import android.os.Environment;
44 import android.text.TextUtils;
45 import android.util.Log;
46 import android.view.Menu;
47 import android.view.MenuInflater;
48 import android.view.MenuItem;
49 import android.view.View;
50 import android.view.Window;
51 import android.widget.ImageView;
52 import android.widget.ListView;
53 import android.widget.TextView;
54 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
55 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;
56
57 public class OwnCloudMainScreen extends ListActivity {
58 private DbHandler mDBHandler;
59 private Stack<String> mParents;
60 private LinkedList<String> mPath;
61 private Account mAccount;
62 private Cursor mCursor;
63 private boolean mIsDisplayingFile;
64
65 private static final int DIALOG_CHOOSE_ACCOUNT = 0;
66
67 @SuppressWarnings("unchecked")
68 @Override
69 public void onCreate(Bundle savedInstanceState) {
70 super.onCreate(savedInstanceState);
71
72 if (savedInstanceState != null) {
73 mParents = (Stack<String>)savedInstanceState.getSerializable("parentsStack");
74 mIsDisplayingFile = savedInstanceState.getBoolean("isDisplayingFile");
75 mPath = (LinkedList<String>)savedInstanceState.getSerializable("path");
76 } else {
77 mParents = new Stack<String>();
78 mPath = new LinkedList<String>();
79 mIsDisplayingFile = false;
80 }
81
82 mDBHandler = new DbHandler(getBaseContext());
83 requestWindowFeature(Window.FEATURE_NO_TITLE);
84 setContentView(R.layout.main);
85
86 AccountManager accMan = AccountManager.get(this);
87 Account[] accounts = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
88
89 if (accounts.length == 0) {
90 // using string value since in API7 this constatn is not defined
91 // in API7 < this constatant is defined in Settings.ADD_ACCOUNT_SETTINGS
92 // and Settings.EXTRA_AUTHORITIES
93 Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
94 intent.putExtra("authorities", new String[] {AccountAuthenticator.AUTH_TOKEN_TYPE});
95 startActivity(intent);
96 } else if (accounts.length > 1) {
97 showDialog(DIALOG_CHOOSE_ACCOUNT);
98 } else {
99 mAccount = accounts[0];
100 populateFileList();
101 }
102 }
103
104 @Override
105 public boolean onOptionsItemSelected(MenuItem item) {
106 switch (item.getItemId()) {
107 case R.id.settingsItem :
108 Intent i = new Intent(this, Preferences.class);
109 startActivity(i);
110 break;
111 }
112 return true;
113 }
114
115 @Override
116 protected Dialog onCreateDialog(int id) {
117 switch (id) {
118 case DIALOG_CHOOSE_ACCOUNT:
119 return createChooseAccountDialog();
120 default:
121 throw new IllegalArgumentException("Unknown dialog id: " + id);
122 }
123 }
124
125 @Override
126 public boolean onCreateOptionsMenu(Menu menu) {
127 MenuInflater inflater = getMenuInflater();
128 inflater.inflate(R.menu.menu, menu);
129 return true;
130 }
131
132 @Override
133 protected void onDestroy() {
134 mDBHandler.close();
135 super.onDestroy();
136 }
137
138 private Dialog createChooseAccountDialog() {
139 final AccountManager accMan = AccountManager.get(this);
140 CharSequence[] items = new CharSequence[accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE).length];
141 int i = 0;
142 for (Account a : accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)) {
143 items[i++] = a.name;
144 }
145
146 AlertDialog.Builder builder = new AlertDialog.Builder(this);
147 builder.setTitle(R.string.common_choose_account);
148 builder.setCancelable(true);
149 builder.setItems(items, new DialogInterface.OnClickListener() {
150 public void onClick(DialogInterface dialog, int item) {
151 mAccount = accMan.getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE)[item];
152 dialog.dismiss();
153 populateFileList();
154 }
155 });
156 builder.setOnCancelListener(new OnCancelListener() {
157 public void onCancel(DialogInterface dialog) {
158 OwnCloudMainScreen.this.finish();
159 }
160 });
161 AlertDialog alert = builder.create();
162 return alert;
163 }
164
165 @Override
166 public void onBackPressed() {
167 PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);
168 if (mIsDisplayingFile) {
169 mIsDisplayingFile = false;
170 setContentView(R.layout.main);
171 pl = (PathLayout) findViewById(R.id.pathLayout1);
172 Uri uri;
173 if (mParents.empty()) {
174 uri = ProviderTableMeta.CONTENT_URI;
175 } else {
176 uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek());
177 }
178 mCursor = managedQuery(uri,
179 null,
180 ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
181 new String[]{mAccount.name}, null);
182
183 if (mCursor.moveToFirst()) {
184 String s = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_PATH));
185 for (String str : s.split("/")) {
186 if (!TextUtils.isEmpty(str))
187 pl.push(DisplayUtils.HtmlDecode(str));
188 }
189 }
190 getListView().setAdapter(new FileListListAdapter(mCursor, this));
191 getListView().invalidate();
192 return;
193 }
194 if (mParents.size()==0) {
195 super.onBackPressed();
196 return;
197 } else if (mParents.size() == 1) {
198 mParents.pop();
199 mPath.removeLast();
200 pl.pop();
201 mCursor = managedQuery(ProviderTableMeta.CONTENT_URI,
202 null,
203 ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
204 new String[]{mAccount.name},
205 null);
206 } else {
207 mParents.pop();
208 mPath.removeLast();
209 pl.pop();
210 mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
211 null,
212 ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
213 new String[]{mAccount.name},
214 null);
215 }
216
217 setListAdapter(new FileListListAdapter(mCursor, this));
218 getListView().invalidate();
219 }
220
221 @Override
222 protected void onListItemClick(ListView l, View v, int position, long id) {
223 super.onListItemClick(l, v, position, id);
224 PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);
225 if (!mCursor.moveToPosition(position)) {
226 throw new IndexOutOfBoundsException("Incorrect item selected");
227 }
228 if (!mIsDisplayingFile) {
229 if (mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).equals("DIR")) {
230 String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
231 String dirname = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME));
232 pl.push(DisplayUtils.HtmlDecode(dirname));
233 mPath.addLast(DisplayUtils.HtmlDecode(dirname));
234 mParents.push(id_);
235 mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, id_),
236 null,
237 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
238 new String[]{mAccount.name}, null);
239 setListAdapter(new FileListListAdapter(mCursor, this));
240 } else {
241 mIsDisplayingFile = true;
242 setContentView(R.layout.file_display);
243 String id_ = mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta._ID));
244 mCursor = managedQuery(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, id_),
245 null,
246 null,
247 null,
248 null);
249 mCursor.moveToFirst();
250 // filename
251 TextView tv = (TextView) findViewById(R.id.textView1);
252 tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_NAME)));
253 // filetype
254 tv = (TextView) findViewById(R.id.textView2);
255 tv.setText(DisplayUtils.convertMIMEtoPrettyPrint(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE))));
256 // size
257 tv = (TextView) findViewById(R.id.textView3);
258 tv.setText(DisplayUtils.bitsToHumanReadable(mCursor.getLong(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_LENGTH))));
259 // modified
260 tv = (TextView) findViewById(R.id.textView4);
261 tv.setText(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_MODIFIED)));
262 if (!TextUtils.isEmpty(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH))) &&
263 mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_CONTENT_TYPE)).matches("image/*")) {
264 ImageView iv = (ImageView) findViewById(R.id.imageView1);
265 Bitmap bmp = BitmapFactory.decodeFile(mCursor.getString(mCursor.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
266 Matrix m = new Matrix();
267 float scale;
268 if (bmp.getWidth() > bmp.getHeight()) {
269 scale = (float) (200./bmp.getWidth());
270 } else {
271 scale = (float) (200./bmp.getHeight());
272 }
273 m.postScale(scale, scale);
274 Bitmap newBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
275 iv.setImageBitmap(newBmp);
276 }
277 setListAdapter(new FileListActionListAdapter(mCursor, this, mAccount));
278 }
279 getListView().invalidate();
280 } else {
281 try {
282 Intent i = (Intent) getListAdapter().getItem(position);
283 if (i.hasExtra("toDownload")) {
284
285 Uri data = Uri.parse(Environment.getExternalStorageDirectory().getAbsolutePath() + "/owncloud/filename");
286 Log.d("DUPA", data.toString());
287 File f = new File(data.toString());
288 FileInputStream fis = new FileInputStream(f);
289 byte buffer[] = new byte[512];
290 fis.read(buffer);
291 Log.d("DUPA", new String(buffer));
292
293 Intent intent = new Intent(this, FileDownloader.class);
294 intent.putExtra(FileDownloader.EXTRA_FILE_PATH, "/"+((TextView)findViewById(R.id.textView1)).getText().toString());
295 intent.putExtra(FileDownloader.EXTRA_ACCOUNT, mAccount);
296 startService(intent);
297 /*
298 if (i.getBooleanExtra("toDownload", false)) {
299 startActivityForResult(i, 200);
300 } else {
301 startActivity(i);
302 }*/
303 }
304 } catch (ClassCastException e) {} catch (FileNotFoundException e) {
305 // TODO Auto-generated catch block
306 e.printStackTrace();
307 } catch (IOException e) {
308 // TODO Auto-generated catch block
309 e.printStackTrace();
310 }
311 }
312 }
313
314 private void populateFileList() {
315 if (mParents.empty()) {
316 mCursor = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
317 null,
318 ProviderTableMeta.FILE_ACCOUNT_OWNER+"=?",
319 new String[]{mAccount.name},
320 null);
321 } else {
322 mCursor = getContentResolver().query(Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, mParents.peek()),
323 null,
324 ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",
325 new String[]{mAccount.name}, null);
326 if (!mIsDisplayingFile) {
327 PathLayout pl = (PathLayout) findViewById(R.id.pathLayout1);
328 for (String s : mPath) {
329 pl.push(s);
330 }
331 }
332 }
333 setListAdapter(new FileListListAdapter(mCursor, this));
334 getListView().invalidate();
335 }
336
337 @Override
338 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
339 super.onActivityResult(requestCode, resultCode, data);
340 }
341
342 @Override
343 protected void onSaveInstanceState(Bundle outState) {
344 super.onSaveInstanceState(outState);
345 outState.putSerializable("parentsStack", mParents);
346 outState.putSerializable("path", mPath);
347 outState.putBoolean("isDisplayingFile", mIsDisplayingFile);
348 }
349
350 }