1db5246e56e75529036c8a4382d79af7a4df74be
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / ui / activity / FileDisplayActivity.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.ui.activity;
20
21 import android.accounts.Account;
22 import android.accounts.AccountManager;
23 import android.app.AlertDialog;
24 import android.app.AlertDialog.Builder;
25 import android.app.Dialog;
26 import android.content.BroadcastReceiver;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.DialogInterface;
30 import android.content.DialogInterface.OnClickListener;
31 import android.content.Intent;
32 import android.content.IntentFilter;
33 import android.database.Cursor;
34 import android.net.Uri;
35 import android.os.Bundle;
36 import android.provider.MediaStore;
37 import android.util.Log;
38 import android.view.View;
39 import android.view.ViewGroup;
40 import android.widget.ArrayAdapter;
41 import android.widget.EditText;
42 import android.widget.TextView;
43
44 import com.actionbarsherlock.app.ActionBar;
45 import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
46 import com.actionbarsherlock.app.SherlockFragmentActivity;
47 import com.actionbarsherlock.view.Menu;
48 import com.actionbarsherlock.view.MenuInflater;
49 import com.actionbarsherlock.view.MenuItem;
50 import com.actionbarsherlock.view.Window;
51
52 import eu.alefzero.owncloud.AccountUtils;
53 import eu.alefzero.owncloud.R;
54 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
55 import eu.alefzero.owncloud.datamodel.DataStorageManager;
56 import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
57 import eu.alefzero.owncloud.datamodel.OCFile;
58 import eu.alefzero.owncloud.syncadapter.FileSyncService;
59 import eu.alefzero.owncloud.ui.fragment.FileListFragment;
60 import eu.alefzero.webdav.WebdavClient;
61
62 /**
63 * Displays, what files the user has available in his ownCloud.
64 *
65 * @author Bartek Przybylski
66 *
67 */
68
69 public class FileDisplayActivity extends SherlockFragmentActivity implements
70 OnNavigationListener, OnClickListener {
71 private ArrayAdapter<String> mDirectories;
72 private DataStorageManager mStorageManager;
73
74 private SyncBroadcastReceiver syncBroadcastRevceiver;
75
76 private static final int DIALOG_SETUP_ACCOUNT = 0;
77 private static final int DIALOG_CREATE_DIR = 1;
78
79 private static final int REQUEST_ACCOUNT_SETUP = 0;
80 private static final int ACTION_SELECT_FILE = 1;
81
82 public void pushPath(String path) {
83 mDirectories.insert(path, 0);
84 }
85
86 public boolean popPath() {
87 mDirectories.remove(mDirectories.getItem(0));
88 return !mDirectories.isEmpty();
89 }
90
91 @Override
92 protected Dialog onCreateDialog(int id) {
93 Dialog dialog;
94 AlertDialog.Builder builder;
95 switch(id){
96 case DIALOG_SETUP_ACCOUNT:
97 builder = new AlertDialog.Builder(this);
98 builder.setTitle(R.string.main_tit_accsetup);
99 builder.setMessage(R.string.main_wrn_accsetup);
100 builder.setCancelable(false);
101 builder.setPositiveButton(android.R.string.ok, this);
102 builder.setNegativeButton(android.R.string.cancel, this);
103 dialog = builder.create();
104 break;
105 case DIALOG_CREATE_DIR:
106 {
107 builder = new Builder(this);
108 final EditText dirName = new EditText(getBaseContext());
109 final Account a = AccountUtils.getCurrentOwnCloudAccount(this);
110 builder.setView(dirName);
111 builder.setTitle(R.string.uploader_info_dirname);
112 int typed_color = getResources().getColor(R.color.setup_text_typed);
113 dirName.setTextColor(typed_color);
114
115 builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
116 public void onClick(DialogInterface dialog, int which) {
117 String s = dirName.getText().toString();
118 if (s.trim().length() == 0) {
119 dialog.cancel();
120 return;
121 }
122
123 String path = "";
124 for (int i = mDirectories.getCount() - 2; i >= 0; --i) {
125 path += "/" + mDirectories.getItem(i);
126 }
127 OCFile parent = mStorageManager.getFileByPath(path + "/");
128 path += s + "/";
129 Thread thread = new Thread(new DirectoryCreator(path, a));
130 thread.start();
131
132 OCFile new_file = new OCFile(path);
133 new_file.setMimetype("DIR");
134 new_file.setParentId(parent.getParentId());
135 mStorageManager.saveFile(new_file);
136
137 dialog.dismiss();
138 }
139 });
140 builder.setNegativeButton(R.string.common_cancel,
141 new OnClickListener() {
142 public void onClick(DialogInterface dialog, int which) {
143 dialog.cancel();
144 }
145 });
146 dialog = builder.create();
147 break;
148 }
149 default:
150 dialog = null;
151 }
152
153 return dialog;
154 }
155
156 @Override
157 public void onCreate(Bundle savedInstanceState) {
158 super.onCreate(savedInstanceState);
159
160 if(!accountsAreSetup()){
161 showDialog(DIALOG_SETUP_ACCOUNT);
162 return;
163 }
164
165 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
166 setProgressBarIndeterminateVisibility(false);
167 }
168
169 @Override
170 public boolean onOptionsItemSelected(MenuItem item) {
171 boolean retval = true;
172 switch (item.getItemId()) {
173 case R.id.settingsItem: {
174 Intent i = new Intent(this, Preferences.class);
175 startActivity(i);
176 break;
177 }
178 case R.id.createDirectoryItem: {
179 showDialog(DIALOG_CREATE_DIR);
180 break;
181 }
182 case R.id.startSync: {
183 Bundle bundle = new Bundle();
184 bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
185 ContentResolver.requestSync(AccountUtils.getCurrentOwnCloudAccount(this),
186 "org.owncloud",
187 bundle);
188 break;
189 }
190 case R.id.action_upload: {
191 Intent action = new Intent(Intent.ACTION_GET_CONTENT);
192 action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
193 startActivityForResult(Intent.createChooser(action, "Upload file from..."), ACTION_SELECT_FILE);
194 break;
195 }
196
197 case android.R.id.home: {
198 Intent i = new Intent(this, AccountSelectActivity.class);
199 startActivity(i);
200 finish();
201 break;
202 }
203 default:
204 retval = false;
205 }
206 return retval;
207 }
208
209 @Override
210 public void onBackPressed(){
211 if(mDirectories.getCount() == 1) {
212 finish();
213 return;
214 }
215 popPath();
216 ((FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList))
217 .onNavigateUp();
218 }
219
220 @Override
221 public boolean onCreateOptionsMenu(Menu menu) {
222 MenuInflater inflater = getSherlock().getMenuInflater();
223 inflater.inflate(R.menu.menu, menu);
224 return true;
225 }
226
227 @Override
228 protected void onRestoreInstanceState(Bundle savedInstanceState) {
229 super.onRestoreInstanceState(savedInstanceState);
230 // Check, if there are ownCloud accounts
231 if(!accountsAreSetup()){
232 showDialog(DIALOG_SETUP_ACCOUNT);
233 }
234 }
235
236
237 @Override
238 protected void onResume() {
239 super.onResume();
240 if(!accountsAreSetup()){
241 showDialog(DIALOG_SETUP_ACCOUNT);
242 return;
243 }
244
245 IntentFilter f = new IntentFilter(FileSyncService.SYNC_MESSAGE);
246 b = new BR();
247 registerReceiver(b, f);
248 if (getSupportFragmentManager().findFragmentById(R.id.fileList) == null)
249 setContentView(R.layout.files);
250
251 mDirectories = new CustomArrayAdapter<String>(this,
252 R.layout.sherlock_spinner_dropdown_item);
253 mDirectories.add("/");
254
255 mStorageManager = new FileDataStorageManager(AccountUtils.getCurrentOwnCloudAccount(this), getContentResolver());
256 ActionBar action_bar = getSupportActionBar();
257 action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
258 action_bar.setDisplayShowTitleEnabled(false);
259 action_bar.setListNavigationCallbacks(mDirectories, this);
260 action_bar.setDisplayHomeAsUpEnabled(true);
261 }
262
263 public void onActivityResult(int requestCode, int resultCode, Intent data) {
264 if (resultCode == RESULT_OK) {
265 if (requestCode == ACTION_SELECT_FILE) {
266 Uri selectedImageUri = data.getData();
267
268 String filemanagerstring = selectedImageUri.getPath();
269
270 String selectedImagePath = getPath(selectedImageUri);
271
272 //DEBUG PURPOSE - you can delete this if you want
273 if(selectedImagePath!=null)
274 System.out.println(selectedImagePath);
275 else System.out.println("selectedImagePath is null");
276 if(filemanagerstring!=null)
277 System.out.println(filemanagerstring);
278 else System.out.println("filemanagerstring is null");
279
280 //NOW WE HAVE OUR WANTED STRING
281 if(selectedImagePath!=null)
282 System.out.println("selectedImagePath is the right one for you!");
283 else
284 System.out.println("filemanagerstring is the right one for you!");
285 }
286 }
287 }
288
289 public String getPath(Uri uri) {
290 String[] projection = { MediaStore.Images.Media.DATA };
291 Cursor cursor = managedQuery(uri, projection, null, null, null);
292 if(cursor!=null)
293 {
294 //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL
295 //THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA
296 int column_index = cursor
297 .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
298 cursor.moveToFirst();
299 return cursor.getString(column_index);
300 }
301 else return null;
302 }
303
304 @Override
305 protected void onPause() {
306 super.onPause();
307 if (b != null) {
308 unregisterReceiver(b);
309 b = null;
310 }
311
312 }
313
314 @Override
315 public boolean onNavigationItemSelected(int itemPosition, long itemId) {
316 int i = itemPosition;
317 while (i-- != 0) {
318 onBackPressed();
319 }
320 return true;
321 }
322
323 private class DirectoryCreator implements Runnable {
324 private String mTargetPath;
325 private Account mAccount;
326 private AccountManager mAm;
327
328 public DirectoryCreator(String targetPath, Account account) {
329 mTargetPath = targetPath;
330 mAccount = account;
331 mAm = (AccountManager) getSystemService(ACCOUNT_SERVICE);
332 }
333
334 @Override
335 public void run() {
336 WebdavClient wdc = new WebdavClient(Uri.parse(mAm.getUserData(
337 mAccount, AccountAuthenticator.KEY_OC_URL)));
338
339 String username = mAccount.name.substring(0,
340 mAccount.name.lastIndexOf('@'));
341 String password = mAm.getPassword(mAccount);
342
343 wdc.setCredentials(username, password);
344 wdc.allowUnsignedCertificates();
345 wdc.createDirectory(mTargetPath);
346 }
347
348 }
349
350 // Custom array adapter to override text colors
351 private class CustomArrayAdapter<T> extends ArrayAdapter<T> {
352
353 public CustomArrayAdapter(FileDisplayActivity ctx,
354 int view) {
355 super(ctx, view);
356 }
357
358 public View getView(int position, View convertView,
359 ViewGroup parent) {
360 View v = super.getView(position, convertView, parent);
361
362 ((TextView) v).setTextColor(
363 getResources()
364 .getColorStateList(android.R.color.white));
365 return v;
366 }
367
368 public View getDropDownView(int position, View convertView,
369 ViewGroup parent) {
370 View v = super.getDropDownView(position, convertView,
371 parent);
372
373 ((TextView) v).setTextColor(getResources().getColorStateList(
374 android.R.color.white));
375
376 return v;
377 }
378
379
380
381 }
382
383 public void onClick(DialogInterface dialog, int which) {
384 // In any case - we won't need it anymore
385 dialog.dismiss();
386 switch(which){
387 case DialogInterface.BUTTON_POSITIVE:
388 Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
389 intent.putExtra("authorities",
390 new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
391 startActivity(intent);
392 break;
393 case DialogInterface.BUTTON_NEGATIVE:
394 finish();
395 }
396
397 }
398
399 /**
400 * Checks, whether or not there are any ownCloud accounts
401 * setup.
402 *
403 * @return true, if there is at least one account.
404 */
405 private boolean accountsAreSetup() {
406 AccountManager accMan = AccountManager.get(this);
407 Account[] accounts = accMan
408 .getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
409 return accounts.length > 0;
410 }
411
412 private class SyncBroadcastReceiver extends BroadcastReceiver {
413 /**
414 * {@link BroadcastReceiver} to enable syncing feedback in UI
415 */
416 @Override
417 public void onReceive(Context context, Intent intent) {
418 boolean inProgress = intent.getBooleanExtra(FileSyncService.IN_PROGRESS, false);
419 String account_name = intent.getStringExtra(FileSyncService.ACCOUNT_NAME);
420 Log.d("FileDisplay", "sync of account " + account_name + " is in_progress: " + inProgress);
421 setProgressBarIndeterminateVisibility(inProgress);
422 if (!inProgress) {
423 FileListFragment fileListFramgent = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
424 if (fileListFramgent != null)
425 fileListFramgent.populateFileList();
426 }
427 }
428
429 }
430
431 }