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