7493c7014c85e1609495f6e00e34f687074f9590
[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 java.io.File;
22 import java.util.ArrayList;
23
24 import android.accounts.Account;
25 import android.accounts.AccountManager;
26 import android.app.AlertDialog;
27 import android.app.AlertDialog.Builder;
28 import android.app.Dialog;
29 import android.content.BroadcastReceiver;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.DialogInterface;
33 import android.content.DialogInterface.OnClickListener;
34 import android.content.Intent;
35 import android.content.IntentFilter;
36 import android.content.SharedPreferences;
37 import android.content.pm.PackageInfo;
38 import android.content.pm.PackageManager.NameNotFoundException;
39 import android.database.Cursor;
40 import android.net.Uri;
41 import android.os.Bundle;
42 import android.preference.PreferenceManager;
43 import android.provider.MediaStore;
44 import android.support.v4.app.FragmentTransaction;
45 import android.util.Log;
46 import android.view.View;
47 import android.view.ViewGroup;
48 import android.widget.ArrayAdapter;
49 import android.widget.EditText;
50 import android.widget.TextView;
51 import android.widget.Toast;
52
53 import com.actionbarsherlock.app.ActionBar;
54 import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
55 import com.actionbarsherlock.app.SherlockFragmentActivity;
56 import com.actionbarsherlock.view.Menu;
57 import com.actionbarsherlock.view.MenuInflater;
58 import com.actionbarsherlock.view.MenuItem;
59 import com.actionbarsherlock.view.Window;
60
61 import eu.alefzero.owncloud.AccountUtils;
62 import eu.alefzero.owncloud.CrashHandler;
63 import eu.alefzero.owncloud.R;
64 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
65 import eu.alefzero.owncloud.datamodel.DataStorageManager;
66 import eu.alefzero.owncloud.datamodel.FileDataStorageManager;
67 import eu.alefzero.owncloud.datamodel.OCFile;
68 import eu.alefzero.owncloud.files.services.FileDownloader;
69 import eu.alefzero.owncloud.files.services.FileUploader;
70 import eu.alefzero.owncloud.syncadapter.FileSyncService;
71 import eu.alefzero.owncloud.ui.fragment.FileDetailFragment;
72 import eu.alefzero.owncloud.ui.fragment.FileListFragment;
73 import eu.alefzero.webdav.WebdavClient;
74
75 /**
76 * Displays, what files the user has available in his ownCloud.
77 *
78 * @author Bartek Przybylski
79 *
80 */
81
82 public class FileDisplayActivity extends SherlockFragmentActivity implements
83 FileListFragment.ContainerActivity, OnNavigationListener, OnClickListener, android.view.View.OnClickListener {
84
85 private ArrayAdapter<String> mDirectories;
86 private OCFile mCurrentDir;
87 private String[] mDirs = null;
88
89 private DataStorageManager mStorageManager;
90 private SyncBroadcastReceiver mSyncBroadcastReceiver;
91 private UploadFinishReceiver mUploadFinishReceiver;
92
93 private View mLayoutView = null;
94 private FileListFragment mFileList;
95
96 private boolean mDualPane;
97
98 private boolean mForcedLoginToCreateFirstAccount = false;
99
100 private static final String KEY_DIR_ARRAY = "DIR_ARRAY";
101 private static final String KEY_CURRENT_DIR = "DIR";
102
103 private static final int DIALOG_SETUP_ACCOUNT = 0;
104 private static final int DIALOG_CREATE_DIR = 1;
105 private static final int DIALOG_ABOUT_APP = 2;
106
107 private static final int ACTION_SELECT_FILE = 1;
108
109 @Override
110 public void onCreate(Bundle savedInstanceState) {
111 Log.i(getClass().toString(), "onCreate() start");
112 super.onCreate(savedInstanceState);
113
114 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
115
116 Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(getApplicationContext()));
117
118 if(savedInstanceState != null) {
119 mDirs = savedInstanceState.getStringArray(KEY_DIR_ARRAY);
120 mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
121 mDirectories.add(OCFile.PATH_SEPARATOR);
122 if (mDirs != null)
123 for (String s : mDirs)
124 mDirectories.insert(s, 0);
125 mCurrentDir = savedInstanceState.getParcelable(FileDetailFragment.EXTRA_FILE);
126 }
127
128 mLayoutView = getLayoutInflater().inflate(R.layout.files, null); // always inflate this at onCreate() ; just once!
129
130 if (AccountUtils.accountsAreSetup(this)) {
131
132 initDelayedTilAccountAvailabe();
133
134 // PIN CODE request ; best location is to decide, let's try this first
135 //if (savedInstanceState == null) {
136 if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
137 requestPinCode();
138 }
139
140
141 } else {
142
143 setContentView(R.layout.no_account_available);
144 getSupportActionBar().setNavigationMode(ActionBar.DISPLAY_SHOW_TITLE);
145 findViewById(R.id.setup_account).setOnClickListener(this);
146
147 setSupportProgressBarIndeterminateVisibility(false);
148
149 Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
150 intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
151 startActivity(intent); // although the code is here, the activity won't be created until this.onStart() and this.onResume() are finished;
152 mForcedLoginToCreateFirstAccount = true;
153 }
154
155 Log.i(getClass().toString(), "onCreate() end");
156 }
157
158 @Override
159 public boolean onCreateOptionsMenu(Menu menu) {
160 MenuInflater inflater = getSherlock().getMenuInflater();
161 inflater.inflate(R.menu.menu, menu);
162 return true;
163 }
164
165 @Override
166 public boolean onOptionsItemSelected(MenuItem item) {
167 boolean retval = true;
168 switch (item.getItemId()) {
169 case R.id.createDirectoryItem: {
170 showDialog(DIALOG_CREATE_DIR);
171 break;
172 }
173 case R.id.startSync: {
174 ContentResolver.cancelSync(null, "org.owncloud"); // cancel the current synchronizations of any ownCloud account
175 Bundle bundle = new Bundle();
176 bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
177 ContentResolver.requestSync(
178 AccountUtils.getCurrentOwnCloudAccount(this),
179 "org.owncloud", bundle);
180 break;
181 }
182 case R.id.action_upload: {
183 Intent action = new Intent(Intent.ACTION_GET_CONTENT);
184 action = action.setType("*/*")
185 .addCategory(Intent.CATEGORY_OPENABLE);
186 startActivityForResult(
187 Intent.createChooser(action, "Upload file from..."),
188 ACTION_SELECT_FILE);
189 break;
190 }
191 case R.id.action_settings: {
192 Intent settingsIntent = new Intent(this, Preferences.class);
193 startActivity(settingsIntent);
194 break;
195 }
196 case R.id.about_app : {
197 showDialog(DIALOG_ABOUT_APP);
198 break;
199 }
200 case android.R.id.home: {
201 if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
202 onBackPressed();
203 }
204 break;
205 }
206 default:
207 retval = false;
208 }
209 return retval;
210 }
211
212 @Override
213 public boolean onNavigationItemSelected(int itemPosition, long itemId) {
214 int i = itemPosition;
215 while (i-- != 0) {
216 onBackPressed();
217 }
218 return true;
219 }
220
221 /**
222 * Called, when the user selected something for uploading
223 */
224 public void onActivityResult(int requestCode, int resultCode, Intent data) {
225 if (requestCode == ACTION_SELECT_FILE) {
226 if (resultCode == RESULT_OK) {
227 String filepath = null;
228 try {
229 Uri selectedImageUri = data.getData();
230
231 String filemanagerstring = selectedImageUri.getPath();
232 String selectedImagePath = getPath(selectedImageUri);
233
234 if (selectedImagePath != null)
235 filepath = selectedImagePath;
236 else
237 filepath = filemanagerstring;
238
239 } catch (Exception e) {
240 Log.e("FileDisplay", "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
241 e.printStackTrace();
242
243 } finally {
244 if (filepath == null) {
245 Log.e("FileDisplay", "Couldnt resolve path to file");
246 Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
247 t.show();
248 return;
249 }
250 }
251
252 Intent i = new Intent(this, FileUploader.class);
253 i.putExtra(FileUploader.KEY_ACCOUNT,
254 AccountUtils.getCurrentOwnCloudAccount(this));
255 String remotepath = new String();
256 for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
257 remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
258 }
259 if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
260 remotepath += OCFile.PATH_SEPARATOR;
261 remotepath += new File(filepath).getName();
262
263 i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
264 i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
265 i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
266 startService(i);
267 }
268
269 }/* dvelasco: WIP - not working as expected ... yet :)
270 else if (requestCode == ACTION_CREATE_FIRST_ACCOUNT) {
271 if (resultCode != RESULT_OK) {
272 finish(); // the user cancelled the AuthenticatorActivity
273 }
274 }*/
275 }
276
277 @Override
278 public void onBackPressed() {
279 if (mDirectories == null || mDirectories.getCount() <= 1) {
280 finish();
281 return;
282 }
283 popDirname();
284 mFileList.onNavigateUp();
285 mCurrentDir = mFileList.getCurrentFile();
286
287 if(mCurrentDir.getParentId() == 0){
288 ActionBar actionBar = getSupportActionBar();
289 actionBar.setDisplayHomeAsUpEnabled(false);
290 }
291 }
292
293 @Override
294 protected void onSaveInstanceState(Bundle outState) {
295 // responsability of restore is prefered in onCreate() before than in onRestoreInstanceState when there are Fragments involved
296 Log.i(getClass().toString(), "onSaveInstanceState() start");
297 super.onSaveInstanceState(outState);
298 if(mDirectories != null && mDirectories.getCount() != 0){
299 mDirs = new String[mDirectories.getCount()-1];
300 for (int j = mDirectories.getCount() - 2, i = 0; j >= 0; --j, ++i) {
301 mDirs[i] = mDirectories.getItem(j);
302 }
303 }
304 outState.putStringArray(KEY_DIR_ARRAY, mDirs);
305 outState.putParcelable(FileDetailFragment.EXTRA_FILE, mCurrentDir);
306 Log.i(getClass().toString(), "onSaveInstanceState() end");
307 }
308
309 @Override
310 protected void onResume() {
311 Log.i(getClass().toString(), "onResume() start");
312 super.onResume();
313
314 if (AccountUtils.accountsAreSetup(this)) {
315 // at least an account exist: normal operation
316
317 // set the layout only if it couldn't be set in onCreate
318 if (mForcedLoginToCreateFirstAccount) {
319 initDelayedTilAccountAvailabe();
320 mForcedLoginToCreateFirstAccount = false;
321 }
322
323 // Listen for sync messages
324 IntentFilter syncIntentFilter = new IntentFilter(FileSyncService.SYNC_MESSAGE);
325 mSyncBroadcastReceiver = new SyncBroadcastReceiver();
326 registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
327
328 // Listen for upload messages
329 IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
330 mUploadFinishReceiver = new UploadFinishReceiver();
331 registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
332
333 // Storage manager initialization
334 mStorageManager = new FileDataStorageManager(
335 AccountUtils.getCurrentOwnCloudAccount(this),
336 getContentResolver());
337
338 // File list fragments
339 mFileList = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
340
341
342 // Figure out what directory to list.
343 // Priority: Intent (here), savedInstanceState (onCreate), root dir (dir is null)
344 if(getIntent().hasExtra(FileDetailFragment.EXTRA_FILE)){
345 mCurrentDir = (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
346 if(mCurrentDir != null && !mCurrentDir.isDirectory()){
347 mCurrentDir = mStorageManager.getFileById(mCurrentDir.getParentId());
348 }
349
350 // Clear intent extra, so rotating the screen will not return us to this directory
351 getIntent().removeExtra(FileDetailFragment.EXTRA_FILE);
352 }
353
354 if (mCurrentDir == null)
355 mCurrentDir = mStorageManager.getFileByPath("/");
356
357 // Drop-Down navigation and file list restore
358 mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
359
360
361 // Given the case we have a file to display:
362 if(mCurrentDir != null){
363 ArrayList<OCFile> files = new ArrayList<OCFile>();
364 OCFile currFile = mCurrentDir;
365 while(currFile != null){
366 files.add(currFile);
367 currFile = mStorageManager.getFileById(currFile.getParentId());
368 }
369
370 // Insert in mDirs
371 mDirs = new String[files.size()];
372 for(int i = files.size() - 1; i >= 0; i--){
373 mDirs[i] = files.get(i).getFileName();
374 }
375 }
376
377 if (mDirs != null) {
378 for (String s : mDirs)
379 mDirectories.add(s);
380 } else {
381 mDirectories.add(OCFile.PATH_SEPARATOR);
382 }
383
384 // Actionbar setup
385 ActionBar action_bar = getSupportActionBar();
386 action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
387 action_bar.setDisplayShowTitleEnabled(false);
388 action_bar.setListNavigationCallbacks(mDirectories, this);
389 if(mCurrentDir != null && mCurrentDir.getParentId() != 0){
390 action_bar.setDisplayHomeAsUpEnabled(true);
391 } else {
392 action_bar.setDisplayHomeAsUpEnabled(false);
393 }
394
395 // List dir here
396 mFileList.listDirectory(mCurrentDir);
397 }
398 Log.i(getClass().toString(), "onResume() end");
399 }
400
401 @Override
402 protected void onPause() {
403 Log.i(getClass().toString(), "onPause() start");
404 super.onPause();
405 if (mSyncBroadcastReceiver != null) {
406 unregisterReceiver(mSyncBroadcastReceiver);
407 mSyncBroadcastReceiver = null;
408 }
409 if (mUploadFinishReceiver != null) {
410 unregisterReceiver(mUploadFinishReceiver);
411 mUploadFinishReceiver = null;
412 }
413 getIntent().putExtra(FileDetailFragment.EXTRA_FILE, mCurrentDir);
414 Log.i(getClass().toString(), "onPause() end");
415 }
416
417 @Override
418 protected Dialog onCreateDialog(int id) {
419 Dialog dialog = null;
420 AlertDialog.Builder builder;
421 switch (id) {
422 case DIALOG_SETUP_ACCOUNT:
423 builder = new AlertDialog.Builder(this);
424 builder.setTitle(R.string.main_tit_accsetup);
425 builder.setMessage(R.string.main_wrn_accsetup);
426 builder.setCancelable(false);
427 builder.setPositiveButton(android.R.string.ok, this);
428 builder.setNegativeButton(android.R.string.cancel, this);
429 dialog = builder.create();
430 break;
431 case DIALOG_ABOUT_APP: {
432 builder = new AlertDialog.Builder(this);
433 builder.setTitle("About");
434 PackageInfo pkg;
435 try {
436 pkg = getPackageManager().getPackageInfo(getPackageName(), 0);
437 builder.setMessage("ownCloud android client\n\nversion: " + pkg.versionName );
438 builder.setIcon(android.R.drawable.ic_menu_info_details);
439 dialog = builder.create();
440 } catch (NameNotFoundException e) {
441 builder = null;
442 dialog = null;
443 e.printStackTrace();
444 }
445 break;
446 }
447 case DIALOG_CREATE_DIR: {
448 builder = new Builder(this);
449 final EditText dirNameInput = new EditText(getBaseContext());
450 final Account a = AccountUtils.getCurrentOwnCloudAccount(this);
451 builder.setView(dirNameInput);
452 builder.setTitle(R.string.uploader_info_dirname);
453 int typed_color = getResources().getColor(R.color.setup_text_typed);
454 dirNameInput.setTextColor(typed_color);
455 builder.setPositiveButton(android.R.string.ok,
456 new OnClickListener() {
457 public void onClick(DialogInterface dialog, int which) {
458 String directoryName = dirNameInput.getText().toString();
459 if (directoryName.trim().length() == 0) {
460 dialog.cancel();
461 return;
462 }
463
464 // Figure out the path where the dir needs to be created
465 String path;
466 if (mCurrentDir == null) {
467 // this is just a patch; we should ensure that mCurrentDir never is null
468 if (!mStorageManager.fileExists(OCFile.PATH_SEPARATOR)) {
469 OCFile file = new OCFile(OCFile.PATH_SEPARATOR);
470 mStorageManager.saveFile(file);
471 }
472 mCurrentDir = mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR);
473 }
474 path = FileDisplayActivity.this.mCurrentDir.getRemotePath();
475
476 // Create directory
477 path += directoryName + OCFile.PATH_SEPARATOR;
478 Thread thread = new Thread(new DirectoryCreator(path, a));
479 thread.start();
480
481 // Save new directory in local database
482 OCFile newDir = new OCFile(path);
483 newDir.setMimetype("DIR");
484 newDir.setParentId(mCurrentDir.getFileId());
485 mStorageManager.saveFile(newDir);
486
487 // Display the new folder right away
488 dialog.dismiss();
489 mFileList.listDirectory(mCurrentDir);
490 }
491 });
492 builder.setNegativeButton(R.string.common_cancel,
493 new OnClickListener() {
494 public void onClick(DialogInterface dialog, int which) {
495 dialog.cancel();
496 }
497 });
498 dialog = builder.create();
499 break;
500 }
501 default:
502 dialog = null;
503 }
504
505 return dialog;
506 }
507
508
509 /**
510 * Responds to the "There are no ownCloud Accounts setup" dialog
511 * TODO: Dialog is 100% useless -> Remove
512 */
513 @Override
514 public void onClick(DialogInterface dialog, int which) {
515 // In any case - we won't need it anymore
516 dialog.dismiss();
517 switch (which) {
518 case DialogInterface.BUTTON_POSITIVE:
519 Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
520 intent.putExtra("authorities",
521 new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
522 startActivity(intent);
523 break;
524 case DialogInterface.BUTTON_NEGATIVE:
525 finish();
526 }
527
528 }
529
530 /**
531 * Translates a content URI of an image to a physical path
532 * on the disk
533 * @param uri The URI to resolve
534 * @return The path to the image or null if it could not be found
535 */
536 public String getPath(Uri uri) {
537 String[] projection = { MediaStore.Images.Media.DATA };
538 Cursor cursor = managedQuery(uri, projection, null, null, null);
539 if (cursor != null) {
540 int column_index = cursor
541 .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
542 cursor.moveToFirst();
543 return cursor.getString(column_index);
544 }
545 return null;
546 }
547
548 /**
549 * Pushes a directory to the drop down list
550 * @param directory to push
551 * @throws IllegalArgumentException If the {@link OCFile#isDirectory()} returns false.
552 */
553 public void pushDirname(OCFile directory) {
554 if(!directory.isDirectory()){
555 throw new IllegalArgumentException("Only directories may be pushed!");
556 }
557 mDirectories.insert(directory.getFileName(), 0);
558 mCurrentDir = directory;
559 }
560
561 /**
562 * Pops a directory name from the drop down list
563 * @return True, unless the stack is empty
564 */
565 public boolean popDirname() {
566 mDirectories.remove(mDirectories.getItem(0));
567 return !mDirectories.isEmpty();
568 }
569
570 private class DirectoryCreator implements Runnable {
571 private String mTargetPath;
572 private Account mAccount;
573 private AccountManager mAm;
574
575 public DirectoryCreator(String targetPath, Account account) {
576 mTargetPath = targetPath;
577 mAccount = account;
578 mAm = (AccountManager) getSystemService(ACCOUNT_SERVICE);
579 }
580
581 @Override
582 public void run() {
583 WebdavClient wdc = new WebdavClient(mAccount, getApplicationContext());
584
585 String username = mAccount.name.substring(0,
586 mAccount.name.lastIndexOf('@'));
587 String password = mAm.getPassword(mAccount);
588
589 wdc.setCredentials(username, password);
590 wdc.allowSelfsignedCertificates();
591 wdc.createDirectory(mTargetPath);
592 }
593
594 }
595
596 // Custom array adapter to override text colors
597 private class CustomArrayAdapter<T> extends ArrayAdapter<T> {
598
599 public CustomArrayAdapter(FileDisplayActivity ctx, int view) {
600 super(ctx, view);
601 }
602
603 public View getView(int position, View convertView, ViewGroup parent) {
604 View v = super.getView(position, convertView, parent);
605
606 ((TextView) v).setTextColor(getResources().getColorStateList(
607 android.R.color.white));
608 return v;
609 }
610
611 public View getDropDownView(int position, View convertView,
612 ViewGroup parent) {
613 View v = super.getDropDownView(position, convertView, parent);
614
615 ((TextView) v).setTextColor(getResources().getColorStateList(
616 android.R.color.white));
617
618 return v;
619 }
620
621 }
622
623 private class SyncBroadcastReceiver extends BroadcastReceiver {
624 /**
625 * {@link BroadcastReceiver} to enable syncing feedback in UI
626 */
627 @Override
628 public void onReceive(Context context, Intent intent) {
629 boolean inProgress = intent.getBooleanExtra(
630 FileSyncService.IN_PROGRESS, false);
631 String account_name = intent
632 .getStringExtra(FileSyncService.ACCOUNT_NAME);
633
634 Log.d("FileDisplay", "sync of account " + account_name
635 + " is in_progress: " + inProgress);
636
637 if (account_name.equals(AccountUtils.getCurrentOwnCloudAccount(context).name)) {
638
639 String synchFolderRemotePath = intent.getStringExtra(FileSyncService.SYNC_FOLDER_REMOTE_PATH);
640
641 boolean fillBlankRoot = false;
642 if (mCurrentDir == null) {
643 mCurrentDir = mStorageManager.getFileByPath("/");
644 fillBlankRoot = (mCurrentDir != null);
645 }
646
647 if ((synchFolderRemotePath != null && mCurrentDir != null && (mCurrentDir.getRemotePath().equals(synchFolderRemotePath)))
648 || fillBlankRoot ) {
649 if (!fillBlankRoot)
650 mCurrentDir = getStorageManager().getFileByPath(synchFolderRemotePath);
651 FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager()
652 .findFragmentById(R.id.fileList);
653 if (fileListFragment != null) {
654 fileListFragment.listDirectory(mCurrentDir);
655 }
656 }
657
658 setSupportProgressBarIndeterminateVisibility(inProgress);
659
660 }
661 }
662 }
663
664
665 private class UploadFinishReceiver extends BroadcastReceiver {
666 /**
667 * Once the file upload has finished -> update view
668 * @author David A. Velasco
669 * {@link BroadcastReceiver} to enable upload feedback in UI
670 */
671 @Override
672 public void onReceive(Context context, Intent intent) {
673 long parentDirId = intent.getLongExtra(FileUploader.EXTRA_PARENT_DIR_ID, -1);
674 OCFile parentDir = mStorageManager.getFileById(parentDirId);
675
676 if (parentDir != null && (
677 (mCurrentDir == null && parentDir.getFileName().equals("/")) ||
678 parentDir.equals(mCurrentDir))
679 ) {
680 FileListFragment fileListFragment = (FileListFragment) getSupportFragmentManager().findFragmentById(R.id.fileList);
681 if (fileListFragment != null) {
682 fileListFragment.listDirectory();
683 }
684 }
685 }
686
687 }
688
689
690 @Override
691 public void onClick(View v) {
692 if (v.getId() == R.id.setup_account) {
693 Intent intent = new Intent(android.provider.Settings.ACTION_ADD_ACCOUNT);
694 intent.putExtra(android.provider.Settings.EXTRA_AUTHORITIES, new String[] { AccountAuthenticator.AUTH_TOKEN_TYPE });
695 startActivity(intent);
696 mForcedLoginToCreateFirstAccount = true;
697 }
698 }
699
700
701
702
703
704 /**
705 * {@inheritDoc}
706 */
707 @Override
708 public DataStorageManager getStorageManager() {
709 return mStorageManager;
710 }
711
712
713 /**
714 * {@inheritDoc}
715 */
716 @Override
717 public void onDirectoryClick(OCFile directory) {
718 pushDirname(directory);
719 ActionBar actionBar = getSupportActionBar();
720 actionBar.setDisplayHomeAsUpEnabled(true);
721
722 if (mDualPane) {
723 // Resets the FileDetailsFragment on Tablets so that it always displays
724 FileDetailFragment fileDetails = (FileDetailFragment) getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
725 if (fileDetails != null) {
726 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
727 transaction.remove(fileDetails);
728 transaction.add(R.id.file_details_container, new FileDetailFragment(null, null));
729 transaction.commit();
730 }
731 }
732 }
733
734
735 /**
736 * {@inheritDoc}
737 */
738 @Override
739 public void onFileClick(OCFile file) {
740
741 // If we are on a large device -> update fragment
742 if (mDualPane) {
743 // buttons in the details view are problematic when trying to reuse an existing fragment; create always a new one solves some of them, BUT no all; downloads are 'dangerous'
744 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
745 transaction.replace(R.id.file_details_container, new FileDetailFragment(file, AccountUtils.getCurrentOwnCloudAccount(this)), FileDetailFragment.FTAG);
746 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
747 transaction.commit();
748
749 } else { // small or medium screen device -> new Activity
750 Intent showDetailsIntent = new Intent(this, FileDetailActivity.class);
751 showDetailsIntent.putExtra(FileDetailFragment.EXTRA_FILE, file);
752 showDetailsIntent.putExtra(FileDownloader.EXTRA_ACCOUNT, AccountUtils.getCurrentOwnCloudAccount(this));
753 startActivity(showDetailsIntent);
754 }
755 }
756
757 /**
758 * Operations in this method should be preferably performed in onCreate to have a lighter onResume method.
759 *
760 * But we need to delay them to onResume for the first start of the application, when no account exists and the login activity must be shown; and
761 * put instead the ugly view that shows the 'Setup' button to restart the login activity.
762 *
763 * In other way, if the users cancels or presses BACK in the login page that first time (users can be cruel sometimes) would show a blank view (the
764 * FragmentList view empty).
765 *
766 * This is temporal, until we found out how to get a result in this activity after launching the ADD_ACCOUNT Intent with startActivityForResult (not trivial)
767 */
768 private void initDelayedTilAccountAvailabe() {
769 setContentView(mLayoutView);
770 mDualPane = (findViewById(R.id.file_details_container) != null);
771 if (mDualPane && getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG) == null) {
772 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
773 transaction.replace(R.id.file_details_container, new FileDetailFragment(null, null)); // empty FileDetailFragment
774 transaction.commit();
775 }
776 setSupportProgressBarIndeterminateVisibility(false);
777 }
778
779
780 /**
781 * Launch an intent to request the PIN code to the user before letting him use the app
782 */
783 private void requestPinCode() {
784 boolean pinStart = false;
785 SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
786 pinStart = appPrefs.getBoolean("set_pincode", false);
787 if (pinStart) {
788 Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
789 i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
790 startActivity(i);
791 }
792 }
793
794
795 }