2 * ownCloud Android client application
4 * @author Bartek Przybylski
5 * @author David A. Velasco
6 * Copyright (C) 2011 Bartek Przybylski
7 * Copyright (C) 2015 ownCloud Inc.
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2,
11 * as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 package com
.owncloud
.android
.ui
.activity
;
26 import java
.util
.ArrayList
;
28 import android
.accounts
.Account
;
29 import android
.accounts
.AccountManager
;
30 import android
.accounts
.AuthenticatorException
;
31 import android
.annotation
.TargetApi
;
32 import android
.app
.AlertDialog
;
33 import android
.content
.BroadcastReceiver
;
34 import android
.content
.ComponentName
;
35 import android
.content
.ContentResolver
;
36 import android
.content
.Context
;
37 import android
.content
.DialogInterface
;
38 import android
.content
.Intent
;
39 import android
.content
.IntentFilter
;
40 import android
.content
.ServiceConnection
;
41 import android
.content
.SharedPreferences
;
42 import android
.content
.SyncRequest
;
43 import android
.content
.res
.Configuration
;
44 import android
.content
.res
.Resources
.NotFoundException
;
45 import android
.database
.Cursor
;
46 import android
.net
.Uri
;
47 import android
.os
.Build
;
48 import android
.os
.Bundle
;
49 import android
.os
.IBinder
;
50 import android
.preference
.PreferenceManager
;
51 import android
.provider
.OpenableColumns
;
52 import android
.support
.v4
.app
.ActionBarDrawerToggle
;
53 import android
.support
.v4
.app
.Fragment
;
54 import android
.support
.v4
.app
.FragmentManager
;
55 import android
.support
.v4
.app
.FragmentTransaction
;
57 import android
.support
.v4
.view
.GravityCompat
;
58 import android
.support
.v4
.widget
.DrawerLayout
;
59 import android
.support
.v7
.app
.ActionBar
;
60 import android
.view
.Menu
;
61 import android
.view
.MenuInflater
;
62 import android
.view
.MenuItem
;
63 import android
.view
.View
;
64 import android
.view
.ViewGroup
;
65 import android
.view
.Window
;
67 import android
.widget
.AdapterView
;
68 import android
.widget
.ArrayAdapter
;
69 import android
.widget
.ImageView
;
70 import android
.widget
.LinearLayout
;
71 import android
.widget
.ListView
;
72 import android
.widget
.TextView
;
73 import android
.widget
.Toast
;
75 import com
.owncloud
.android
.BuildConfig
;
76 import com
.owncloud
.android
.MainApp
;
77 import com
.owncloud
.android
.R
;
78 import com
.owncloud
.android
.authentication
.AccountUtils
;
79 import com
.owncloud
.android
.datamodel
.OCFile
;
80 import com
.owncloud
.android
.files
.services
.FileDownloader
;
81 import com
.owncloud
.android
.files
.services
.FileDownloader
.FileDownloaderBinder
;
82 import com
.owncloud
.android
.files
.services
.FileUploader
;
83 import com
.owncloud
.android
.files
.services
.FileUploader
.FileUploaderBinder
;
84 import com
.owncloud
.android
.lib
.common
.OwnCloudAccount
;
85 import com
.owncloud
.android
.lib
.common
.OwnCloudClient
;
86 import com
.owncloud
.android
.lib
.common
.OwnCloudClientManagerFactory
;
87 import com
.owncloud
.android
.lib
.common
.OwnCloudCredentials
;
88 import com
.owncloud
.android
.lib
.common
.accounts
.AccountUtils
.AccountNotFoundException
;
89 import com
.owncloud
.android
.lib
.common
.network
.CertificateCombinedException
;
90 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperation
;
91 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
;
92 import com
.owncloud
.android
.lib
.common
.operations
.RemoteOperationResult
.ResultCode
;
93 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
;
94 import com
.owncloud
.android
.operations
.CreateFolderOperation
;
95 import com
.owncloud
.android
.operations
.CreateShareOperation
;
96 import com
.owncloud
.android
.operations
.MoveFileOperation
;
97 import com
.owncloud
.android
.operations
.RemoveFileOperation
;
98 import com
.owncloud
.android
.operations
.RenameFileOperation
;
99 import com
.owncloud
.android
.operations
.SynchronizeFileOperation
;
100 import com
.owncloud
.android
.operations
.RefreshFolderOperation
;
101 import com
.owncloud
.android
.operations
.UnshareLinkOperation
;
102 import com
.owncloud
.android
.services
.observer
.FileObserverService
;
103 import com
.owncloud
.android
.syncadapter
.FileSyncAdapter
;
104 import com
.owncloud
.android
.ui
.NavigationDrawerItem
;
105 import com
.owncloud
.android
.ui
.adapter
.NavigationDrawerListAdapter
;
106 import com
.owncloud
.android
.ui
.dialog
.ConfirmationDialogFragment
;
107 import com
.owncloud
.android
.ui
.dialog
.CreateFolderDialogFragment
;
108 import com
.owncloud
.android
.ui
.dialog
.SslUntrustedCertDialog
;
109 import com
.owncloud
.android
.ui
.dialog
.SslUntrustedCertDialog
.OnSslUntrustedCertListener
;
110 import com
.owncloud
.android
.ui
.dialog
.UploadSourceDialogFragment
;
111 import com
.owncloud
.android
.ui
.fragment
.FileDetailFragment
;
112 import com
.owncloud
.android
.ui
.fragment
.FileFragment
;
113 import com
.owncloud
.android
.ui
.fragment
.OCFileListFragment
;
114 import com
.owncloud
.android
.ui
.preview
.PreviewImageActivity
;
115 import com
.owncloud
.android
.ui
.preview
.PreviewImageFragment
;
116 import com
.owncloud
.android
.ui
.preview
.PreviewMediaFragment
;
117 import com
.owncloud
.android
.ui
.preview
.PreviewVideoActivity
;
118 import com
.owncloud
.android
.utils
.DisplayUtils
;
119 import com
.owncloud
.android
.utils
.ErrorMessageAdapter
;
120 import com
.owncloud
.android
.utils
.FileStorageUtils
;
121 import com
.owncloud
.android
.utils
.UriUtils
;
125 * Displays, what files the user has available in his ownCloud.
128 public class FileDisplayActivity
extends HookActivity
implements
129 FileFragment
.ContainerActivity
, ActionBar
.OnNavigationListener
,
130 OnSslUntrustedCertListener
, OnEnforceableRefreshListener
{
132 private ArrayAdapter
<String
> mDirectories
;
134 private SyncBroadcastReceiver mSyncBroadcastReceiver
;
135 private UploadFinishReceiver mUploadFinishReceiver
;
136 private DownloadFinishReceiver mDownloadFinishReceiver
;
137 private RemoteOperationResult mLastSslUntrustedServerResult
= null
;
139 private boolean mDualPane
;
140 private View mLeftFragmentContainer
;
141 private View mRightFragmentContainer
;
143 private static final String KEY_WAITING_TO_PREVIEW
= "WAITING_TO_PREVIEW";
144 private static final String KEY_SYNC_IN_PROGRESS
= "SYNC_IN_PROGRESS";
145 private static final String KEY_WAITING_TO_SEND
= "WAITING_TO_SEND";
147 public static final String ACTION_DETAILS
= "com.owncloud.android.ui.activity.action.DETAILS";
149 public static final int ACTION_SELECT_CONTENT_FROM_APPS
= 1;
150 public static final int ACTION_SELECT_MULTIPLE_FILES
= 2;
151 public static final int ACTION_MOVE_FILES
= 3;
153 private static final String TAG
= FileDisplayActivity
.class.getSimpleName();
155 private static final String TAG_LIST_OF_FILES
= "LIST_OF_FILES";
156 private static final String TAG_SECOND_FRAGMENT
= "SECOND_FRAGMENT";
158 private OCFile mWaitingToPreview
;
160 private boolean mSyncInProgress
= false
;
162 private static String DIALOG_UNTRUSTED_CERT
= "DIALOG_UNTRUSTED_CERT";
163 private static String DIALOG_CREATE_FOLDER
= "DIALOG_CREATE_FOLDER";
164 private static String DIALOG_UPLOAD_SOURCE
= "DIALOG_UPLOAD_SOURCE";
165 private static String DIALOG_CERT_NOT_SAVED
= "DIALOG_CERT_NOT_SAVED";
167 private OCFile mWaitingToSend
;
170 private DrawerLayout mDrawerLayout
;
171 private ActionBarDrawerToggle mDrawerToggle
;
172 private ListView mDrawerList
;
175 private String
[] mDrawerTitles
;
176 private String
[] mDrawerContentDescriptions
;
178 private ArrayList
<NavigationDrawerItem
> mDrawerItems
;
180 private NavigationDrawerListAdapter mNavigationDrawerAdapter
= null
;
182 private boolean mShowAccounts
= false
;
185 protected void onCreate(Bundle savedInstanceState
) {
186 Log_OC
.v(TAG
, "onCreate() start");
187 requestWindowFeature(Window
.FEATURE_INDETERMINATE_PROGRESS
);
189 super.onCreate(savedInstanceState
); // this calls onAccountChanged() when ownCloud Account
192 /// grant that FileObserverService is watching favorite files
193 if (savedInstanceState
== null
) {
194 Intent initObserversIntent
= FileObserverService
.makeInitIntent(this);
195 startService(initObserversIntent
);
198 /// Load of saved instance state
199 if(savedInstanceState
!= null
) {
200 mWaitingToPreview
= (OCFile
) savedInstanceState
.getParcelable(
201 FileDisplayActivity
.KEY_WAITING_TO_PREVIEW
);
202 mSyncInProgress
= savedInstanceState
.getBoolean(KEY_SYNC_IN_PROGRESS
);
203 mWaitingToSend
= (OCFile
) savedInstanceState
.getParcelable(
204 FileDisplayActivity
.KEY_WAITING_TO_SEND
);
207 mWaitingToPreview
= null
;
208 mSyncInProgress
= false
;
209 mWaitingToSend
= null
;
214 // Inflate and set the layout view
215 setContentView(R
.layout
.files
);
220 mDualPane
= getResources().getBoolean(R
.bool
.large_land_layout
);
221 mLeftFragmentContainer
= findViewById(R
.id
.left_fragment_container
);
222 mRightFragmentContainer
= findViewById(R
.id
.right_fragment_container
);
223 if (savedInstanceState
== null
) {
224 createMinFragments();
228 mDirectories
= new CustomArrayAdapter
<String
>(this,
229 R
.layout
.support_simple_spinner_dropdown_item
);
230 getSupportActionBar().setHomeButtonEnabled(true
); // mandatory since Android ICS,
231 // according to the official
233 setSupportProgressBarIndeterminateVisibility(mSyncInProgress
234 /*|| mRefreshSharesInProgress*/);
235 // always AFTER setContentView(...) ; to work around bug in its implementation
237 // TODO Remove??, it is done in onPostCreate
238 mDrawerToggle
.syncState();
242 Log_OC
.v(TAG
, "onCreate() end");
245 private void initDrawer(){
246 mDrawerLayout
= (DrawerLayout
) findViewById(R
.id
.drawer_layout
);
247 // Notification Drawer
248 LinearLayout navigationDrawerLayout
= (LinearLayout
) findViewById(R
.id
.left_drawer
);
249 mDrawerList
= (ListView
) navigationDrawerLayout
.findViewById(R
.id
.drawer_list
);
251 // load Account in the Drawer Title
253 ImageView userIcon
= (ImageView
) navigationDrawerLayout
.findViewById(R
.id
.drawer_userIcon
);
254 userIcon
.setImageResource(DisplayUtils
.getSeasonalIconId());
257 TextView username
= (TextView
) navigationDrawerLayout
.findViewById(R
.id
.drawer_username
);
258 Account account
= AccountUtils
.getCurrentOwnCloudAccount(getApplicationContext());
260 if (account
!= null
) {
261 int lastAtPos
= account
.name
.lastIndexOf("@");
262 username
.setText(account
.name
.substring(0, lastAtPos
));
265 // load slide menu items
266 mDrawerTitles
= getResources().getStringArray(R
.array
.drawer_items
);
268 // nav drawer content description from resources
269 mDrawerContentDescriptions
= getResources().
270 getStringArray(R
.array
.drawer_content_descriptions
);
273 mDrawerItems
= new ArrayList
<NavigationDrawerItem
>();
274 // adding nav drawer items to array
276 mDrawerItems
.add(new NavigationDrawerItem(mDrawerTitles
[0], mDrawerContentDescriptions
[0]));
278 mDrawerItems
.add(new NavigationDrawerItem(mDrawerTitles
[1], mDrawerContentDescriptions
[1]));
280 // TODO Enable when "On Device" is recovered
282 //mDrawerItems.add(new NavigationDrawerItem(mDrawerTitles[2],
283 // mDrawerContentDescriptions[2]));
286 mDrawerItems
.add(new NavigationDrawerItem(mDrawerTitles
[2], mDrawerContentDescriptions
[2]));
288 if (BuildConfig
.DEBUG
) {
289 mDrawerItems
.add(new NavigationDrawerItem(mDrawerTitles
[3],
290 mDrawerContentDescriptions
[3]));
293 // setting the nav drawer list adapter
294 mNavigationDrawerAdapter
= new NavigationDrawerListAdapter(getApplicationContext(), this,
296 mDrawerList
.setAdapter(mNavigationDrawerAdapter
);
298 mDrawerToggle
= new ActionBarDrawerToggle(
301 R
.drawable
.ic_drawer
,
302 R
.string
.drawer_open
,
305 /** Called when a drawer has settled in a completely closed state. */
306 public void onDrawerClosed(View view
) {
307 super.onDrawerClosed(view
);
308 getSupportActionBar().setDisplayShowTitleEnabled(true
);
309 getSupportActionBar().setNavigationMode(ActionBar
.NAVIGATION_MODE_LIST
);
310 initFragmentsWithFile();
311 invalidateOptionsMenu();
314 /** Called when a drawer has settled in a completely open state. */
315 public void onDrawerOpened(View drawerView
) {
316 super.onDrawerOpened(drawerView
);
317 getSupportActionBar().setTitle(R
.string
.drawer_open
);
318 getSupportActionBar().setNavigationMode(ActionBar
.NAVIGATION_MODE_STANDARD
);
319 invalidateOptionsMenu();
323 mDrawerToggle
.setDrawerIndicatorEnabled(true
);
324 // Set the list's click listener
325 mDrawerList
.setOnItemClickListener(new DrawerItemClickListener());
327 // Set the drawer toggle as the DrawerListener
328 mDrawerLayout
.setDrawerListener(mDrawerToggle
);
332 protected void onStart() {
333 Log_OC
.v(TAG
, "onStart() start");
335 getSupportActionBar().setIcon(DisplayUtils
.getSeasonalIconId());
336 Log_OC
.v(TAG
, "onStart() end");
340 protected void onPostCreate(Bundle savedInstanceState
) {
341 super.onPostCreate(savedInstanceState
);
342 // Sync the toggle state after onRestoreInstanceState has occurred.
343 mDrawerToggle
.syncState();
347 public void onConfigurationChanged(Configuration newConfig
) {
348 super.onConfigurationChanged(newConfig
);
349 mDrawerToggle
.onConfigurationChanged(newConfig
);
353 protected void onDestroy() {
354 Log_OC
.v(TAG
, "onDestroy() start");
356 Log_OC
.v(TAG
, "onDestroy() end");
360 * Called when the ownCloud {@link Account} associated to the Activity was just updated.
363 protected void onAccountSet(boolean stateWasRecovered
) {
364 super.onAccountSet(stateWasRecovered
);
365 if (getAccount() != null
) {
366 /// Check whether the 'main' OCFile handled by the Activity is contained in the
368 OCFile file
= getFile();
369 // get parent from path
370 String parentPath
= "";
372 if (file
.isDown() && file
.getLastSyncDateForProperties() == 0) {
373 // upload in progress - right now, files are not inserted in the local
374 // cache until the upload is successful get parent from path
375 parentPath
= file
.getRemotePath().substring(0,
376 file
.getRemotePath().lastIndexOf(file
.getFileName()));
377 if (getStorageManager().getFileByPath(parentPath
) == null
)
378 file
= null
; // not able to know the directory where the file is uploading
380 file
= getStorageManager().getFileByPath(file
.getRemotePath());
381 // currentDir = null if not in the current Account
385 // fall back to root folder
386 file
= getStorageManager().getFileByPath(OCFile
.ROOT_PATH
); // never returns null
389 setNavigationListWithFolder(file
);
391 if (!stateWasRecovered
) {
392 Log_OC
.d(TAG
, "Initializing Fragments in onAccountChanged..");
393 initFragmentsWithFile();
394 if (file
.isFolder()) {
395 startSyncFolderOperation(file
, false
);
399 updateFragmentsVisibility(!file
.isFolder());
400 updateNavigationElementsInActionBar(file
.isFolder() ? null
: file
);
406 private void setNavigationListWithFolder(OCFile file
) {
407 mDirectories
.clear();
408 OCFile fileIt
= file
;
410 while(fileIt
!= null
&& fileIt
.getFileName() != OCFile
.ROOT_PATH
) {
411 if (fileIt
.isFolder()) {
412 mDirectories
.add(fileIt
.getFileName());
414 // get parent from path
415 parentPath
= fileIt
.getRemotePath().substring(0,
416 fileIt
.getRemotePath().lastIndexOf(fileIt
.getFileName()));
417 fileIt
= getStorageManager().getFileByPath(parentPath
);
419 mDirectories
.add(OCFile
.PATH_SEPARATOR
);
423 private void createMinFragments() {
424 OCFileListFragment listOfFiles
= new OCFileListFragment();
425 FragmentTransaction transaction
= getSupportFragmentManager().beginTransaction();
426 transaction
.add(R
.id
.left_fragment_container
, listOfFiles
, TAG_LIST_OF_FILES
);
427 transaction
.commit();
430 private void initFragmentsWithFile() {
431 if (getAccount() != null
&& getFile() != null
) {
433 OCFileListFragment listOfFiles
= getListOfFilesFragment();
434 if (listOfFiles
!= null
) {
435 listOfFiles
.listDirectory(getCurrentDir());
436 // TODO Enable when "On Device" is recovered
437 // listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice());
439 Log_OC
.e(TAG
, "Still have a chance to lose the initializacion of list fragment >(");
443 OCFile file
= getFile();
444 Fragment secondFragment
= chooseInitialSecondFragment(file
);
445 if (secondFragment
!= null
) {
446 setSecondFragment(secondFragment
);
447 updateFragmentsVisibility(true
);
448 updateNavigationElementsInActionBar(file
);
451 cleanSecondFragment();
455 Log_OC
.wtf(TAG
, "initFragments() called with invalid NULLs!");
456 if (getAccount() == null
) {
457 Log_OC
.wtf(TAG
, "\t account is NULL");
459 if (getFile() == null
) {
460 Log_OC
.wtf(TAG
, "\t file is NULL");
465 private Fragment
chooseInitialSecondFragment(OCFile file
) {
466 Fragment secondFragment
= null
;
467 if (file
!= null
&& !file
.isFolder()) {
468 if (file
.isDown() && PreviewMediaFragment
.canBePreviewed(file
)
469 && file
.getLastSyncDateForProperties() > 0 // temporal fix
471 int startPlaybackPosition
=
472 getIntent().getIntExtra(PreviewVideoActivity
.EXTRA_START_POSITION
, 0);
474 getIntent().getBooleanExtra(PreviewVideoActivity
.EXTRA_AUTOPLAY
, true
);
475 secondFragment
= new PreviewMediaFragment(file
, getAccount(),
476 startPlaybackPosition
, autoplay
);
479 secondFragment
= new FileDetailFragment(file
, getAccount());
482 return secondFragment
;
487 * Replaces the second fragment managed by the activity with the received as
490 * Assumes never will be more than two fragments managed at the same time.
492 * @param fragment New second Fragment to set.
494 private void setSecondFragment(Fragment fragment
) {
495 FragmentTransaction transaction
= getSupportFragmentManager().beginTransaction();
496 transaction
.replace(R
.id
.right_fragment_container
, fragment
, TAG_SECOND_FRAGMENT
);
497 transaction
.commit();
501 private void updateFragmentsVisibility(boolean existsSecondFragment
) {
503 if (mLeftFragmentContainer
.getVisibility() != View
.VISIBLE
) {
504 mLeftFragmentContainer
.setVisibility(View
.VISIBLE
);
506 if (mRightFragmentContainer
.getVisibility() != View
.VISIBLE
) {
507 mRightFragmentContainer
.setVisibility(View
.VISIBLE
);
510 } else if (existsSecondFragment
) {
511 if (mLeftFragmentContainer
.getVisibility() != View
.GONE
) {
512 mLeftFragmentContainer
.setVisibility(View
.GONE
);
514 if (mRightFragmentContainer
.getVisibility() != View
.VISIBLE
) {
515 mRightFragmentContainer
.setVisibility(View
.VISIBLE
);
519 if (mLeftFragmentContainer
.getVisibility() != View
.VISIBLE
) {
520 mLeftFragmentContainer
.setVisibility(View
.VISIBLE
);
522 if (mRightFragmentContainer
.getVisibility() != View
.GONE
) {
523 mRightFragmentContainer
.setVisibility(View
.GONE
);
529 private OCFileListFragment
getListOfFilesFragment() {
530 Fragment listOfFiles
= getSupportFragmentManager().findFragmentByTag(
531 FileDisplayActivity
.TAG_LIST_OF_FILES
);
532 if (listOfFiles
!= null
) {
533 return (OCFileListFragment
)listOfFiles
;
535 Log_OC
.wtf(TAG
, "Access to unexisting list of files fragment!!");
539 public FileFragment
getSecondFragment() {
540 Fragment second
= getSupportFragmentManager().findFragmentByTag(
541 FileDisplayActivity
.TAG_SECOND_FRAGMENT
);
542 if (second
!= null
) {
543 return (FileFragment
)second
;
548 protected void cleanSecondFragment() {
549 Fragment second
= getSecondFragment();
550 if (second
!= null
) {
551 FragmentTransaction tr
= getSupportFragmentManager().beginTransaction();
555 updateFragmentsVisibility(false
);
556 updateNavigationElementsInActionBar(null
);
559 protected void refreshListOfFilesFragment() {
560 OCFileListFragment fileListFragment
= getListOfFilesFragment();
561 if (fileListFragment
!= null
) {
562 fileListFragment
.listDirectory();
563 // TODO Enable when "On Device" is recovered ?
564 // fileListFragment.listDirectory(MainApp.getOnlyOnDevice());
568 protected void refreshSecondFragment(String downloadEvent
, String downloadedRemotePath
,
570 FileFragment secondFragment
= getSecondFragment();
571 boolean waitedPreview
= (mWaitingToPreview
!= null
&&
572 mWaitingToPreview
.getRemotePath().equals(downloadedRemotePath
));
573 if (secondFragment
!= null
&& secondFragment
instanceof FileDetailFragment
) {
574 FileDetailFragment detailsFragment
= (FileDetailFragment
) secondFragment
;
575 OCFile fileInFragment
= detailsFragment
.getFile();
576 if (fileInFragment
!= null
&&
577 !downloadedRemotePath
.equals(fileInFragment
.getRemotePath())) {
578 // the user browsed to other file ; forget the automatic preview
579 mWaitingToPreview
= null
;
581 } else if (downloadEvent
.equals(FileDownloader
.getDownloadAddedMessage())) {
582 // grant that the right panel updates the progress bar
583 detailsFragment
.listenForTransferProgress();
584 detailsFragment
.updateFileDetails(true
, false
);
586 } else if (downloadEvent
.equals(FileDownloader
.getDownloadFinishMessage())) {
587 // update the right panel
588 boolean detailsFragmentChanged
= false
;
591 mWaitingToPreview
= getStorageManager().getFileById(
592 mWaitingToPreview
.getFileId()); // update the file from database,
593 // for the local storage path
594 if (PreviewMediaFragment
.canBePreviewed(mWaitingToPreview
)) {
595 startMediaPreview(mWaitingToPreview
, 0, true
);
596 detailsFragmentChanged
= true
;
598 getFileOperationsHelper().openFile(mWaitingToPreview
);
601 mWaitingToPreview
= null
;
603 if (!detailsFragmentChanged
) {
604 detailsFragment
.updateFileDetails(false
, (success
));
611 public boolean onPrepareOptionsMenu(Menu menu
) {
612 boolean drawerOpen
= mDrawerLayout
.isDrawerOpen(GravityCompat
.START
);
613 menu
.findItem(R
.id
.action_upload
).setVisible(!drawerOpen
);
614 menu
.findItem(R
.id
.action_create_dir
).setVisible(!drawerOpen
);
615 menu
.findItem(R
.id
.action_sort
).setVisible(!drawerOpen
);
617 return super.onPrepareOptionsMenu(menu
);
621 public boolean onCreateOptionsMenu(Menu menu
) {
622 MenuInflater inflater
= getMenuInflater();
623 inflater
.inflate(R
.menu
.main_menu
, menu
);
629 public boolean onOptionsItemSelected(MenuItem item
) {
630 boolean retval
= true
;
631 switch (item
.getItemId()) {
632 case R
.id
.action_create_dir
: {
633 CreateFolderDialogFragment dialog
= CreateFolderDialogFragment
.newInstance(getCurrentDir());
634 dialog
.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER
);
637 case R
.id
.action_upload
: {
638 UploadSourceDialogFragment dialog
= UploadSourceDialogFragment
.newInstance(getAccount());
639 dialog
.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE
);
643 case android
.R
.id
.home
: {
644 if (mDrawerLayout
.isDrawerOpen(GravityCompat
.START
)) {
645 mDrawerLayout
.closeDrawer(GravityCompat
.START
);
647 mDrawerLayout
.openDrawer(GravityCompat
.START
);
649 // TODO add hamburger to left of android.R.id.home
652 case R
.id
.action_sort
: {
653 SharedPreferences appPreferences
= PreferenceManager
654 .getDefaultSharedPreferences(this);
656 // Read sorting order, default to sort by name ascending
657 Integer sortOrder
= appPreferences
658 .getInt("sortOrder", FileStorageUtils
.SORT_NAME
);
660 AlertDialog
.Builder builder
= new AlertDialog
.Builder(this);
661 builder
.setTitle(R
.string
.actionbar_sort_title
)
662 .setSingleChoiceItems(R
.array
.actionbar_sortby
, sortOrder
, new DialogInterface
.OnClickListener() {
663 public void onClick(DialogInterface dialog
, int which
) {
676 builder
.create().show();
680 retval
= super.onOptionsItemSelected(item
);
685 private void startSynchronization() {
686 Log_OC
.d(TAG
, "Got to start sync");
687 if (android
.os
.Build
.VERSION
.SDK_INT
< android
.os
.Build
.VERSION_CODES
.KITKAT
) {
688 Log_OC
.d(TAG
, "Canceling all syncs for " + MainApp
.getAuthority());
689 ContentResolver
.cancelSync(null
, MainApp
.getAuthority());
690 // cancel the current synchronizations of any ownCloud account
691 Bundle bundle
= new Bundle();
692 bundle
.putBoolean(ContentResolver
.SYNC_EXTRAS_MANUAL
, true
);
693 bundle
.putBoolean(ContentResolver
.SYNC_EXTRAS_EXPEDITED
, true
);
694 Log_OC
.d(TAG
, "Requesting sync for " + getAccount().name
+ " at " +
695 MainApp
.getAuthority());
696 ContentResolver
.requestSync(
698 MainApp
.getAuthority(), bundle
);
700 Log_OC
.d(TAG
, "Requesting sync for " + getAccount().name
+ " at " +
701 MainApp
.getAuthority() + " with new API");
702 SyncRequest
.Builder builder
= new SyncRequest
.Builder();
703 builder
.setSyncAdapter(getAccount(), MainApp
.getAuthority());
704 builder
.setExpedited(true
);
705 builder
.setManual(true
);
708 // Fix bug in Android Lollipop when you click on refresh the whole account
709 Bundle extras
= new Bundle();
710 builder
.setExtras(extras
);
712 SyncRequest request
= builder
.build();
713 ContentResolver
.requestSync(request
);
719 public boolean onNavigationItemSelected(int itemPosition
, long itemId
) {
720 if (itemPosition
!= 0) {
721 String targetPath
= "";
722 for (int i
=itemPosition
; i
< mDirectories
.getCount() - 1; i
++) {
723 targetPath
= mDirectories
.getItem(i
) + OCFile
.PATH_SEPARATOR
+ targetPath
;
725 targetPath
= OCFile
.PATH_SEPARATOR
+ targetPath
;
726 OCFile targetFolder
= getStorageManager().getFileByPath(targetPath
);
727 if (targetFolder
!= null
) {
728 browseTo(targetFolder
);
731 // the next operation triggers a new call to this method, but it's necessary to
732 // ensure that the name exposed in the action bar is the current directory when the
733 // user selected it in the navigation list
734 if (getSupportActionBar().getNavigationMode() == ActionBar
.NAVIGATION_MODE_LIST
&&
736 getSupportActionBar().setSelectedNavigationItem(0);
742 * Called, when the user selected something for uploading
745 @TargetApi(Build
.VERSION_CODES
.JELLY_BEAN
)
747 protected void onActivityResult(int requestCode
, int resultCode
, Intent data
) {
749 if (requestCode
== ACTION_SELECT_CONTENT_FROM_APPS
&& (resultCode
== RESULT_OK
||
750 resultCode
== UploadFilesActivity
.RESULT_OK_AND_MOVE
)) {
751 //getClipData is only supported on api level 16+, Jelly Bean
752 if (data
.getData() == null
&& Build
.VERSION
.SDK_INT
>= Build
.VERSION_CODES
.JELLY_BEAN
){
753 for( int i
= 0; i
< data
.getClipData().getItemCount(); i
++){
754 Intent intent
= new Intent();
755 intent
.setData(data
.getClipData().getItemAt(i
).getUri());
756 requestSimpleUpload(intent
, resultCode
);
759 requestSimpleUpload(data
, resultCode
);
761 } else if (requestCode
== ACTION_SELECT_MULTIPLE_FILES
&& (resultCode
== RESULT_OK
||
762 resultCode
== UploadFilesActivity
.RESULT_OK_AND_MOVE
)) {
763 requestMultipleUpload(data
, resultCode
);
765 } else if (requestCode
== ACTION_MOVE_FILES
&& resultCode
== RESULT_OK
){
767 final Intent fData
= data
;
768 final int fResultCode
= resultCode
;
769 getHandler().postDelayed(
773 requestMoveOperation(fData
, fResultCode
);
776 DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
780 super.onActivityResult(requestCode
, resultCode
, data
);
785 private void requestMultipleUpload(Intent data
, int resultCode
) {
786 String
[] filePaths
= data
.getStringArrayExtra(UploadFilesActivity
.EXTRA_CHOSEN_FILES
);
787 if (filePaths
!= null
) {
788 String
[] remotePaths
= new String
[filePaths
.length
];
789 String remotePathBase
= "";
791 for (int j
= mDirectories
.getCount() - 2; j
>= 0; --j
) {
792 remotePathBase
+= OCFile
.PATH_SEPARATOR
+ mDirectories
.getItem(j
);
794 if (!remotePathBase
.endsWith(OCFile
.PATH_SEPARATOR
))
795 remotePathBase
+= OCFile
.PATH_SEPARATOR
;
796 for (int j
= 0; j
< remotePaths
.length
; j
++) {
797 remotePaths
[j
] = remotePathBase
+ (new File(filePaths
[j
])).getName();
800 Intent i
= new Intent(this, FileUploader
.class);
801 i
.putExtra(FileUploader
.KEY_ACCOUNT
, getAccount());
802 i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, filePaths
);
803 i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, remotePaths
);
804 i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_MULTIPLE_FILES
);
805 if (resultCode
== UploadFilesActivity
.RESULT_OK_AND_MOVE
)
806 i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_MOVE
);
810 Log_OC
.d(TAG
, "User clicked on 'Update' with no selection");
811 Toast t
= Toast
.makeText(this, getString(R
.string
.filedisplay_no_file_selected
),
819 private void requestSimpleUpload(Intent data
, int resultCode
) {
820 String filePath
= null
;
821 String mimeType
= null
;
823 Uri selectedImageUri
= data
.getData();
826 mimeType
= getContentResolver().getType(selectedImageUri
);
828 String fileManagerString
= selectedImageUri
.getPath();
829 String selectedImagePath
= UriUtils
.getLocalPath(selectedImageUri
, this);
831 if (selectedImagePath
!= null
)
832 filePath
= selectedImagePath
;
834 filePath
= fileManagerString
;
836 } catch (Exception e
) {
837 Log_OC
.e(TAG
, "Unexpected exception when trying to read the result of " +
838 "Intent.ACTION_GET_CONTENT", e
);
841 if (filePath
== null
) {
842 Log_OC
.e(TAG
, "Couldn't resolve path to file");
843 Toast t
= Toast
.makeText(
844 this, getString(R
.string
.filedisplay_unexpected_bad_get_content
),
852 Intent i
= new Intent(this, FileUploader
.class);
853 i
.putExtra(FileUploader
.KEY_ACCOUNT
, getAccount());
854 OCFile currentDir
= getCurrentDir();
855 String remotePath
= (currentDir
!= null
) ? currentDir
.getRemotePath() : OCFile
.ROOT_PATH
;
857 if (filePath
.startsWith(UriUtils
.URI_CONTENT_SCHEME
)) {
858 Cursor cursor
= getContentResolver().query(Uri
.parse(filePath
), null
, null
, null
, null
);
860 if (cursor
!= null
&& cursor
.moveToFirst()) {
861 String displayName
= cursor
.getString(cursor
.getColumnIndex(
862 OpenableColumns
.DISPLAY_NAME
));
863 Log_OC
.v(TAG
, "Display Name: " + displayName
);
865 displayName
.replace(File
.separatorChar
, '_');
866 displayName
.replace(File
.pathSeparatorChar
, '_');
867 remotePath
+= displayName
+ DisplayUtils
.getComposedFileExtension(filePath
);
870 // and what happens in case of error?; wrong target name for the upload
876 remotePath
+= new File(filePath
).getName();
879 i
.putExtra(FileUploader
.KEY_LOCAL_FILE
, filePath
);
880 i
.putExtra(FileUploader
.KEY_REMOTE_FILE
, remotePath
);
881 i
.putExtra(FileUploader
.KEY_MIME_TYPE
, mimeType
);
882 i
.putExtra(FileUploader
.KEY_UPLOAD_TYPE
, FileUploader
.UPLOAD_SINGLE_FILE
);
883 if (resultCode
== UploadFilesActivity
.RESULT_OK_AND_MOVE
)
884 i
.putExtra(FileUploader
.KEY_LOCAL_BEHAVIOUR
, FileUploader
.LOCAL_BEHAVIOUR_MOVE
);
889 * Request the operation for moving the file/folder from one path to another
891 * @param data Intent received
892 * @param resultCode Result code received
894 private void requestMoveOperation(Intent data
, int resultCode
) {
895 OCFile folderToMoveAt
= (OCFile
) data
.getParcelableExtra(FolderPickerActivity
.EXTRA_FOLDER
);
896 OCFile targetFile
= (OCFile
) data
.getParcelableExtra(FolderPickerActivity
.EXTRA_FILE
);
897 getFileOperationsHelper().moveFile(folderToMoveAt
, targetFile
);
901 public void onBackPressed() {
902 OCFileListFragment listOfFiles
= getListOfFilesFragment();
903 if (mDualPane
|| getSecondFragment() == null
) {
904 if (listOfFiles
!= null
) { // should never be null, indeed
905 if (mDirectories
.getCount() <= 1) {
909 int levelsUp
= listOfFiles
.onBrowseUp();
910 for (int i
=0; i
< levelsUp
&& mDirectories
.getCount() > 1 ; i
++) {
915 if (listOfFiles
!= null
) { // should never be null, indeed
916 setFile(listOfFiles
.getCurrentFile());
918 cleanSecondFragment();
923 protected void onSaveInstanceState(Bundle outState
) {
924 // responsibility of restore is preferred in onCreate() before than in
925 // onRestoreInstanceState when there are Fragments involved
926 Log_OC
.v(TAG
, "onSaveInstanceState() start");
927 super.onSaveInstanceState(outState
);
928 outState
.putParcelable(FileDisplayActivity
.KEY_WAITING_TO_PREVIEW
, mWaitingToPreview
);
929 outState
.putBoolean(FileDisplayActivity
.KEY_SYNC_IN_PROGRESS
, mSyncInProgress
);
930 //outState.putBoolean(FileDisplayActivity.KEY_REFRESH_SHARES_IN_PROGRESS,
931 // mRefreshSharesInProgress);
932 outState
.putParcelable(FileDisplayActivity
.KEY_WAITING_TO_SEND
, mWaitingToSend
);
934 Log_OC
.v(TAG
, "onSaveInstanceState() end");
940 protected void onResume() {
941 Log_OC
.v(TAG
, "onResume() start");
944 // refresh Navigation Drawer account list
945 mNavigationDrawerAdapter
.updateAccountList();
947 // refresh list of files
948 refreshListOfFilesFragment();
950 // Listen for sync messages
951 IntentFilter syncIntentFilter
= new IntentFilter(FileSyncAdapter
.EVENT_FULL_SYNC_START
);
952 syncIntentFilter
.addAction(FileSyncAdapter
.EVENT_FULL_SYNC_END
);
953 syncIntentFilter
.addAction(FileSyncAdapter
.EVENT_FULL_SYNC_FOLDER_CONTENTS_SYNCED
);
954 syncIntentFilter
.addAction(RefreshFolderOperation
.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED
);
955 syncIntentFilter
.addAction(RefreshFolderOperation
.EVENT_SINGLE_FOLDER_SHARES_SYNCED
);
956 mSyncBroadcastReceiver
= new SyncBroadcastReceiver();
957 registerReceiver(mSyncBroadcastReceiver
, syncIntentFilter
);
958 //LocalBroadcastManager.getInstance(this).registerReceiver(mSyncBroadcastReceiver,
959 // syncIntentFilter);
961 // Listen for upload messages
962 IntentFilter uploadIntentFilter
= new IntentFilter(FileUploader
.getUploadFinishMessage());
963 mUploadFinishReceiver
= new UploadFinishReceiver();
964 registerReceiver(mUploadFinishReceiver
, uploadIntentFilter
);
966 // Listen for download messages
967 IntentFilter downloadIntentFilter
= new IntentFilter(FileDownloader
.getDownloadAddedMessage());
968 downloadIntentFilter
.addAction(FileDownloader
.getDownloadFinishMessage());
969 mDownloadFinishReceiver
= new DownloadFinishReceiver();
970 registerReceiver(mDownloadFinishReceiver
, downloadIntentFilter
);
972 Log_OC
.v(TAG
, "onResume() end");
977 protected void onPause() {
978 Log_OC
.v(TAG
, "onPause() start");
979 if (mSyncBroadcastReceiver
!= null
) {
980 unregisterReceiver(mSyncBroadcastReceiver
);
981 //LocalBroadcastManager.getInstance(this).unregisterReceiver(mSyncBroadcastReceiver);
982 mSyncBroadcastReceiver
= null
;
984 if (mUploadFinishReceiver
!= null
) {
985 unregisterReceiver(mUploadFinishReceiver
);
986 mUploadFinishReceiver
= null
;
988 if (mDownloadFinishReceiver
!= null
) {
989 unregisterReceiver(mDownloadFinishReceiver
);
990 mDownloadFinishReceiver
= null
;
994 Log_OC
.v(TAG
, "onPause() end");
998 * Pushes a directory to the drop down list
999 * @param directory to push
1000 * @throws IllegalArgumentException If the {@link OCFile#isFolder()} returns false.
1002 public void pushDirname(OCFile directory
) {
1003 if(!directory
.isFolder()){
1004 throw new IllegalArgumentException("Only directories may be pushed!");
1006 mDirectories
.insert(directory
.getFileName(), 0);
1011 * Pops a directory name from the drop down list
1012 * @return True, unless the stack is empty
1014 public boolean popDirname() {
1015 mDirectories
.remove(mDirectories
.getItem(0));
1016 return !mDirectories
.isEmpty();
1019 // Custom array adapter to override text colors
1020 private class CustomArrayAdapter
<T
> extends ArrayAdapter
<T
> {
1022 public CustomArrayAdapter(FileDisplayActivity ctx
, int view
) {
1026 public View
getView(int position
, View convertView
, ViewGroup parent
) {
1027 View v
= super.getView(position
, convertView
, parent
);
1029 ((TextView
) v
).setTextColor(getResources().getColorStateList(
1030 android
.R
.color
.white
));
1032 fixRoot((TextView
) v
);
1036 public View
getDropDownView(int position
, View convertView
,
1038 View v
= super.getDropDownView(position
, convertView
, parent
);
1040 ((TextView
) v
).setTextColor(getResources().getColorStateList(
1041 android
.R
.color
.white
));
1043 fixRoot((TextView
) v
);
1047 private void fixRoot(TextView v
) {
1048 if (v
.getText().equals(OCFile
.PATH_SEPARATOR
)) {
1049 v
.setText(R
.string
.default_display_name_for_root_folder
);
1055 private class SyncBroadcastReceiver
extends BroadcastReceiver
{
1058 * {@link BroadcastReceiver} to enable syncing feedback in UI
1061 public void onReceive(Context context
, Intent intent
) {
1063 String event
= intent
.getAction();
1064 Log_OC
.d(TAG
, "Received broadcast " + event
);
1065 String accountName
= intent
.getStringExtra(FileSyncAdapter
.EXTRA_ACCOUNT_NAME
);
1066 String synchFolderRemotePath
=
1067 intent
.getStringExtra(FileSyncAdapter
.EXTRA_FOLDER_PATH
);
1068 RemoteOperationResult synchResult
=
1069 (RemoteOperationResult
)intent
.getSerializableExtra(
1070 FileSyncAdapter
.EXTRA_RESULT
);
1071 boolean sameAccount
= (getAccount() != null
&&
1072 accountName
.equals(getAccount().name
) && getStorageManager() != null
);
1076 if (FileSyncAdapter
.EVENT_FULL_SYNC_START
.equals(event
)) {
1077 mSyncInProgress
= true
;
1080 OCFile currentFile
= (getFile() == null
) ? null
:
1081 getStorageManager().getFileByPath(getFile().getRemotePath());
1082 OCFile currentDir
= (getCurrentDir() == null
) ? null
:
1083 getStorageManager().getFileByPath(getCurrentDir().getRemotePath());
1085 if (currentDir
== null
) {
1086 // current folder was removed from the server
1087 Toast
.makeText( FileDisplayActivity
.this,
1089 getString(R
.string
.sync_current_folder_was_removed
),
1090 mDirectories
.getItem(0)),
1096 if (currentFile
== null
&& !getFile().isFolder()) {
1097 // currently selected file was removed in the server, and now we
1099 cleanSecondFragment();
1100 currentFile
= currentDir
;
1103 if (synchFolderRemotePath
!= null
&&
1104 currentDir
.getRemotePath().equals(synchFolderRemotePath
)) {
1105 OCFileListFragment fileListFragment
= getListOfFilesFragment();
1106 if (fileListFragment
!= null
) {
1107 fileListFragment
.listDirectory();
1108 // TODO Enable when "On Device" is recovered ?
1109 // fileListFragment.listDirectory(currentDir,
1110 // MainApp.getOnlyOnDevice());
1113 setFile(currentFile
);
1116 mSyncInProgress
= (!FileSyncAdapter
.EVENT_FULL_SYNC_END
.equals(event
) &&
1117 !RefreshFolderOperation
.EVENT_SINGLE_FOLDER_SHARES_SYNCED
1120 if (RefreshFolderOperation
.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED
.
1122 /// TODO refactor and make common
1123 synchResult
!= null
&& !synchResult
.isSuccess() &&
1124 (synchResult
.getCode() == ResultCode
.UNAUTHORIZED
||
1125 synchResult
.isIdPRedirection() ||
1126 (synchResult
.isException() && synchResult
.getException()
1127 instanceof AuthenticatorException
))) {
1131 OwnCloudClient client
;
1132 OwnCloudAccount ocAccount
=
1133 new OwnCloudAccount(getAccount(), context
);
1134 client
= (OwnCloudClientManagerFactory
.getDefaultSingleton().
1135 removeClientFor(ocAccount
));
1137 if (client
!= null
) {
1138 OwnCloudCredentials cred
= client
.getCredentials();
1140 AccountManager am
= AccountManager
.get(context
);
1141 if (cred
.authTokenExpires()) {
1142 am
.invalidateAuthToken(
1147 am
.clearPassword(getAccount());
1151 requestCredentialsUpdate();
1153 } catch (AccountNotFoundException e
) {
1154 Log_OC
.e(TAG
, "Account " + getAccount() + " was removed!", e
);
1159 removeStickyBroadcast(intent
);
1160 Log_OC
.d(TAG
, "Setting progress visibility to " + mSyncInProgress
);
1161 setSupportProgressBarIndeterminateVisibility(mSyncInProgress
1162 /*|| mRefreshSharesInProgress*/);
1164 setBackgroundText();
1168 if (synchResult
!= null
) {
1169 if (synchResult
.getCode().equals(
1170 RemoteOperationResult
.ResultCode
.SSL_RECOVERABLE_PEER_UNVERIFIED
)) {
1171 mLastSslUntrustedServerResult
= synchResult
;
1174 } catch (RuntimeException e
) {
1175 // avoid app crashes after changing the serial id of RemoteOperationResult
1176 // in owncloud library with broadcast notifications pending to process
1177 removeStickyBroadcast(intent
);
1183 * Show a text message on screen view for notifying user if content is
1184 * loading or folder is empty
1186 private void setBackgroundText() {
1187 OCFileListFragment ocFileListFragment
= getListOfFilesFragment();
1188 if (ocFileListFragment
!= null
) {
1189 int message
= R
.string
.file_list_loading
;
1190 if (!mSyncInProgress
) {
1191 // In case file list is empty
1192 message
= R
.string
.file_list_empty
;
1194 ocFileListFragment
.setMessageForEmptyList(getString(message
));
1196 Log_OC
.e(TAG
, "OCFileListFragment is null");
1201 * Once the file upload has finished -> update view
1203 private class UploadFinishReceiver
extends BroadcastReceiver
{
1205 * Once the file upload has finished -> update view
1206 * @author David A. Velasco
1207 * {@link BroadcastReceiver} to enable upload feedback in UI
1210 public void onReceive(Context context
, Intent intent
) {
1212 String uploadedRemotePath
= intent
.getStringExtra(FileDownloader
.EXTRA_REMOTE_PATH
);
1213 String accountName
= intent
.getStringExtra(FileUploader
.ACCOUNT_NAME
);
1214 boolean sameAccount
= getAccount() != null
&& accountName
.equals(getAccount().name
);
1215 OCFile currentDir
= getCurrentDir();
1216 boolean isDescendant
= (currentDir
!= null
) && (uploadedRemotePath
!= null
) &&
1217 (uploadedRemotePath
.startsWith(currentDir
.getRemotePath()));
1219 if (sameAccount
&& isDescendant
) {
1220 refreshListOfFilesFragment();
1223 boolean uploadWasFine
= intent
.getBooleanExtra(FileUploader
.EXTRA_UPLOAD_RESULT
,
1225 boolean renamedInUpload
= getFile().getRemotePath().
1226 equals(intent
.getStringExtra(FileUploader
.EXTRA_OLD_REMOTE_PATH
));
1227 boolean sameFile
= getFile().getRemotePath().equals(uploadedRemotePath
) ||
1229 FileFragment details
= getSecondFragment();
1230 boolean detailFragmentIsShown
= (details
!= null
&&
1231 details
instanceof FileDetailFragment
);
1233 if (sameAccount
&& sameFile
&& detailFragmentIsShown
) {
1234 if (uploadWasFine
) {
1235 setFile(getStorageManager().getFileByPath(uploadedRemotePath
));
1237 if (renamedInUpload
) {
1238 String newName
= (new File(uploadedRemotePath
)).getName();
1239 Toast msg
= Toast
.makeText(
1242 getString(R
.string
.filedetails_renamed_in_upload_msg
),
1247 if (uploadWasFine
|| getFile().fileExists()) {
1248 ((FileDetailFragment
)details
).updateFileDetails(false
, true
);
1250 cleanSecondFragment();
1253 // Force the preview if the file is an image
1254 if (uploadWasFine
&& PreviewImageFragment
.canBePreviewed(getFile())) {
1255 startImagePreview(getFile());
1256 } // TODO what about other kind of previews?
1260 if (intent
!= null
) {
1261 removeStickyBroadcast(intent
);
1271 * Class waiting for broadcast events from the {@link FileDownloader} service.
1273 * Updates the UI when a download is started or finished, provided that it is relevant for the
1276 private class DownloadFinishReceiver
extends BroadcastReceiver
{
1278 //int refreshCounter = 0;
1280 public void onReceive(Context context
, Intent intent
) {
1282 boolean sameAccount
= isSameAccount(context
, intent
);
1283 String downloadedRemotePath
=
1284 intent
.getStringExtra(FileDownloader
.EXTRA_REMOTE_PATH
);
1285 boolean isDescendant
= isDescendant(downloadedRemotePath
);
1287 if (sameAccount
&& isDescendant
) {
1288 String linkedToRemotePath
=
1289 intent
.getStringExtra(FileDownloader
.EXTRA_LINKED_TO_PATH
);
1290 if (linkedToRemotePath
== null
|| isAscendant(linkedToRemotePath
)) {
1291 //Log_OC.v(TAG, "refresh #" + ++refreshCounter);
1292 refreshListOfFilesFragment();
1294 refreshSecondFragment(
1296 downloadedRemotePath
,
1297 intent
.getBooleanExtra(FileDownloader
.EXTRA_DOWNLOAD_RESULT
, false
)
1301 if (mWaitingToSend
!= null
) {
1303 getStorageManager().getFileByPath(mWaitingToSend
.getRemotePath());
1304 if (mWaitingToSend
.isDown()) {
1305 sendDownloadedFile();
1310 if (intent
!= null
) {
1311 removeStickyBroadcast(intent
);
1316 private boolean isDescendant(String downloadedRemotePath
) {
1317 OCFile currentDir
= getCurrentDir();
1319 currentDir
!= null
&&
1320 downloadedRemotePath
!= null
&&
1321 downloadedRemotePath
.startsWith(currentDir
.getRemotePath())
1325 private boolean isAscendant(String linkedToRemotePath
) {
1326 OCFile currentDir
= getCurrentDir();
1328 currentDir
!= null
&&
1329 currentDir
.getRemotePath().startsWith(linkedToRemotePath
)
1333 private boolean isSameAccount(Context context
, Intent intent
) {
1334 String accountName
= intent
.getStringExtra(FileDownloader
.ACCOUNT_NAME
);
1335 return (accountName
!= null
&& getAccount() != null
&&
1336 accountName
.equals(getAccount().name
));
1341 public void browseToRoot() {
1342 OCFileListFragment listOfFiles
= getListOfFilesFragment();
1343 if (listOfFiles
!= null
) { // should never be null, indeed
1344 while (mDirectories
.getCount() > 1) {
1347 OCFile root
= getStorageManager().getFileByPath(OCFile
.ROOT_PATH
);
1348 listOfFiles
.listDirectory(root
);
1349 // TODO Enable when "On Device" is recovered ?
1350 // listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice());
1351 setFile(listOfFiles
.getCurrentFile());
1352 startSyncFolderOperation(root
, false
);
1354 cleanSecondFragment();
1358 public void browseTo(OCFile folder
) {
1359 if (folder
== null
|| !folder
.isFolder()) {
1360 throw new IllegalArgumentException("Trying to browse to invalid folder " + folder
);
1362 OCFileListFragment listOfFiles
= getListOfFilesFragment();
1363 if (listOfFiles
!= null
) {
1364 setNavigationListWithFolder(folder
);
1365 listOfFiles
.listDirectory(folder
);
1366 // TODO Enable when "On Device" is recovered ?
1367 // listOfFiles.listDirectory(folder, MainApp.getOnlyOnDevice());
1368 setFile(listOfFiles
.getCurrentFile());
1369 startSyncFolderOperation(folder
, false
);
1371 Log_OC
.e(TAG
, "Unexpected null when accessing list fragment");
1373 cleanSecondFragment();
1380 * Updates action bar and second fragment, if in dual pane mode.
1383 public void onBrowsedDownTo(OCFile directory
) {
1384 pushDirname(directory
);
1385 cleanSecondFragment();
1388 startSyncFolderOperation(directory
, false
);
1393 * Shows the information of the {@link OCFile} received as a
1394 * parameter in the second fragment.
1396 * @param file {@link OCFile} whose details will be shown
1399 public void showDetails(OCFile file
) {
1400 Fragment detailFragment
= new FileDetailFragment(file
, getAccount());
1401 setSecondFragment(detailFragment
);
1402 updateFragmentsVisibility(true
);
1403 updateNavigationElementsInActionBar(file
);
1411 private void updateNavigationElementsInActionBar(OCFile chosenFile
) {
1412 ActionBar actionBar
= getSupportActionBar();
1414 // For adding content description tag to a title field in the action bar
1415 int actionBarTitleId
= getResources().getIdentifier("action_bar_title", "id", "android");
1417 if (chosenFile
== null
|| mDualPane
) {
1418 // only list of files - set for browsing through folders
1419 OCFile currentDir
= getCurrentDir();
1420 boolean noRoot
= (currentDir
!= null
&& currentDir
.getParentId() != 0);
1421 // actionBar.setDisplayHomeAsUpEnabled(noRoot);
1422 // actionBar.setDisplayShowTitleEnabled(!noRoot);
1423 actionBar
.setDisplayHomeAsUpEnabled(true
);
1424 actionBar
.setDisplayShowTitleEnabled(true
);
1426 actionBar
.setTitle(getString(R
.string
.default_display_name_for_root_folder
));
1427 View actionBarTitleView
= getWindow().getDecorView().findViewById(actionBarTitleId
);
1428 if (actionBarTitleView
!= null
) { // it's null in Android 2.x
1429 actionBarTitleView
.setContentDescription(
1430 getString(R
.string
.default_display_name_for_root_folder
));
1433 actionBar
.setNavigationMode(!noRoot ? ActionBar
.NAVIGATION_MODE_STANDARD
:
1434 ActionBar
.NAVIGATION_MODE_LIST
);
1435 actionBar
.setListNavigationCallbacks(mDirectories
, this);
1436 // assuming mDirectories is updated
1439 actionBar
.setDisplayHomeAsUpEnabled(true
);
1440 actionBar
.setDisplayShowTitleEnabled(true
);
1441 actionBar
.setTitle(chosenFile
.getFileName());
1442 actionBar
.setNavigationMode(ActionBar
.NAVIGATION_MODE_STANDARD
);
1443 View actionBarTitleView
= getWindow().getDecorView().findViewById(actionBarTitleId
);
1444 if (actionBarTitleView
!= null
) { // it's null in Android 2.x
1445 getWindow().getDecorView().findViewById(actionBarTitleId
).
1446 setContentDescription(chosenFile
.getFileName());
1453 protected ServiceConnection
newTransferenceServiceConnection() {
1454 return new ListServiceConnection();
1457 /** Defines callbacks for service binding, passed to bindService() */
1458 private class ListServiceConnection
implements ServiceConnection
{
1461 public void onServiceConnected(ComponentName component
, IBinder service
) {
1462 if (component
.equals(new ComponentName(
1463 FileDisplayActivity
.this, FileDownloader
.class))) {
1464 Log_OC
.d(TAG
, "Download service connected");
1465 mDownloaderBinder
= (FileDownloaderBinder
) service
;
1466 if (mWaitingToPreview
!= null
)
1467 if (getStorageManager() != null
) {
1470 getStorageManager().getFileById(mWaitingToPreview
.getFileId());
1471 if (!mWaitingToPreview
.isDown()) {
1472 requestForDownload();
1476 } else if (component
.equals(new ComponentName(FileDisplayActivity
.this,
1477 FileUploader
.class))) {
1478 Log_OC
.d(TAG
, "Upload service connected");
1479 mUploaderBinder
= (FileUploaderBinder
) service
;
1483 // a new chance to get the mDownloadBinder through
1484 // getFileDownloadBinder() - THIS IS A MESS
1485 OCFileListFragment listOfFiles
= getListOfFilesFragment();
1486 if (listOfFiles
!= null
) {
1487 listOfFiles
.listDirectory();
1488 // TODO Enable when "On Device" is recovered ?
1489 // listOfFiles.listDirectory(MainApp.getOnlyOnDevice());
1491 FileFragment secondFragment
= getSecondFragment();
1492 if (secondFragment
!= null
&& secondFragment
instanceof FileDetailFragment
) {
1493 FileDetailFragment detailFragment
= (FileDetailFragment
)secondFragment
;
1494 detailFragment
.listenForTransferProgress();
1495 detailFragment
.updateFileDetails(false
, false
);
1500 public void onServiceDisconnected(ComponentName component
) {
1501 if (component
.equals(new ComponentName(FileDisplayActivity
.this,
1502 FileDownloader
.class))) {
1503 Log_OC
.d(TAG
, "Download service disconnected");
1504 mDownloaderBinder
= null
;
1505 } else if (component
.equals(new ComponentName(FileDisplayActivity
.this,
1506 FileUploader
.class))) {
1507 Log_OC
.d(TAG
, "Upload service disconnected");
1508 mUploaderBinder
= null
;
1514 public void onSavedCertificate() {
1515 startSyncFolderOperation(getCurrentDir(), false
);
1520 public void onFailedSavingCertificate() {
1521 ConfirmationDialogFragment dialog
= ConfirmationDialogFragment
.newInstance(
1522 R
.string
.ssl_validator_not_saved
, new String
[]{}, R
.string
.common_ok
, -1, -1
1524 dialog
.show(getSupportFragmentManager(), DIALOG_CERT_NOT_SAVED
);
1528 public void onCancelCertificate() {
1533 * Updates the view associated to the activity after the finish of some operation over files
1534 * in the current account.
1536 * @param operation Removal operation performed.
1537 * @param result Result of the removal.
1540 public void onRemoteOperationFinish(RemoteOperation operation
, RemoteOperationResult result
) {
1541 super.onRemoteOperationFinish(operation
, result
);
1543 if (operation
instanceof RemoveFileOperation
) {
1544 onRemoveFileOperationFinish((RemoveFileOperation
)operation
, result
);
1546 } else if (operation
instanceof RenameFileOperation
) {
1547 onRenameFileOperationFinish((RenameFileOperation
)operation
, result
);
1549 } else if (operation
instanceof SynchronizeFileOperation
) {
1550 onSynchronizeFileOperationFinish((SynchronizeFileOperation
)operation
, result
);
1552 } else if (operation
instanceof CreateFolderOperation
) {
1553 onCreateFolderOperationFinish((CreateFolderOperation
)operation
, result
);
1555 } else if (operation
instanceof CreateShareOperation
) {
1556 onCreateShareOperationFinish((CreateShareOperation
) operation
, result
);
1558 } else if (operation
instanceof UnshareLinkOperation
) {
1559 onUnshareLinkOperationFinish((UnshareLinkOperation
)operation
, result
);
1561 } else if (operation
instanceof MoveFileOperation
) {
1562 onMoveFileOperationFinish((MoveFileOperation
)operation
, result
);
1568 private void onCreateShareOperationFinish(CreateShareOperation operation
,
1569 RemoteOperationResult result
) {
1570 if (result
.isSuccess()) {
1571 refreshShowDetails();
1572 refreshListOfFilesFragment();
1577 private void onUnshareLinkOperationFinish(UnshareLinkOperation operation
,
1578 RemoteOperationResult result
) {
1579 if (result
.isSuccess()) {
1580 refreshShowDetails();
1581 refreshListOfFilesFragment();
1583 } else if (result
.getCode() == ResultCode
.SHARE_NOT_FOUND
) {
1584 cleanSecondFragment();
1585 refreshListOfFilesFragment();
1589 private void refreshShowDetails() {
1590 FileFragment details
= getSecondFragment();
1591 if (details
!= null
) {
1592 OCFile file
= details
.getFile();
1594 file
= getStorageManager().getFileByPath(file
.getRemotePath());
1595 if (details
instanceof PreviewMediaFragment
) {
1596 // Refresh OCFile of the fragment
1597 ((PreviewMediaFragment
) details
).updateFile(file
);
1602 invalidateOptionsMenu();
1607 * Updates the view associated to the activity after the finish of an operation trying to
1610 * @param operation Removal operation performed.
1611 * @param result Result of the removal.
1613 private void onRemoveFileOperationFinish(RemoveFileOperation operation
,
1614 RemoteOperationResult result
) {
1615 dismissLoadingDialog();
1617 Toast msg
= Toast
.makeText(this,
1618 ErrorMessageAdapter
.getErrorCauseMessage(result
, operation
, getResources()),
1622 if (result
.isSuccess()) {
1623 OCFile removedFile
= operation
.getFile();
1624 FileFragment second
= getSecondFragment();
1625 if (second
!= null
&& removedFile
.equals(second
.getFile())) {
1626 if (second
instanceof PreviewMediaFragment
) {
1627 ((PreviewMediaFragment
)second
).stopPreview(true
);
1629 setFile(getStorageManager().getFileById(removedFile
.getParentId()));
1630 cleanSecondFragment();
1632 if (getStorageManager().getFileById(removedFile
.getParentId()).equals(getCurrentDir())) {
1633 refreshListOfFilesFragment();
1635 invalidateOptionsMenu();
1637 if (result
.isSslRecoverableException()) {
1638 mLastSslUntrustedServerResult
= result
;
1639 showUntrustedCertDialog(mLastSslUntrustedServerResult
);
1646 * Updates the view associated to the activity after the finish of an operation trying to move a
1649 * @param operation Move operation performed.
1650 * @param result Result of the move operation.
1652 private void onMoveFileOperationFinish(MoveFileOperation operation
,
1653 RemoteOperationResult result
) {
1654 if (result
.isSuccess()) {
1655 dismissLoadingDialog();
1656 refreshListOfFilesFragment();
1658 dismissLoadingDialog();
1660 Toast msg
= Toast
.makeText(FileDisplayActivity
.this,
1661 ErrorMessageAdapter
.getErrorCauseMessage(result
, operation
, getResources()),
1665 } catch (NotFoundException e
) {
1666 Log_OC
.e(TAG
, "Error while trying to show fail message " , e
);
1673 * Updates the view associated to the activity after the finish of an operation trying to rename
1676 * @param operation Renaming operation performed.
1677 * @param result Result of the renaming.
1679 private void onRenameFileOperationFinish(RenameFileOperation operation
,
1680 RemoteOperationResult result
) {
1681 dismissLoadingDialog();
1682 OCFile renamedFile
= operation
.getFile();
1683 if (result
.isSuccess()) {
1684 FileFragment details
= getSecondFragment();
1685 if (details
!= null
) {
1686 if (details
instanceof FileDetailFragment
&&
1687 renamedFile
.equals(details
.getFile()) ) {
1688 ((FileDetailFragment
) details
).updateFileDetails(renamedFile
, getAccount());
1689 showDetails(renamedFile
);
1691 } else if (details
instanceof PreviewMediaFragment
&&
1692 renamedFile
.equals(details
.getFile())) {
1693 ((PreviewMediaFragment
) details
).updateFile(renamedFile
);
1694 if (PreviewMediaFragment
.canBePreviewed(renamedFile
)) {
1695 int position
= ((PreviewMediaFragment
)details
).getPosition();
1696 startMediaPreview(renamedFile
, position
, true
);
1698 getFileOperationsHelper().openFile(renamedFile
);
1703 if (getStorageManager().getFileById(renamedFile
.getParentId()).equals(getCurrentDir())){
1704 refreshListOfFilesFragment();
1708 Toast msg
= Toast
.makeText(this,
1709 ErrorMessageAdapter
.getErrorCauseMessage(result
, operation
, getResources()),
1713 if (result
.isSslRecoverableException()) {
1714 mLastSslUntrustedServerResult
= result
;
1715 showUntrustedCertDialog(mLastSslUntrustedServerResult
);
1720 private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation
,
1721 RemoteOperationResult result
) {
1722 dismissLoadingDialog();
1723 OCFile syncedFile
= operation
.getLocalFile();
1724 if (!result
.isSuccess()) {
1725 if (result
.getCode() == ResultCode
.SYNC_CONFLICT
) {
1726 Intent i
= new Intent(this, ConflictsResolveActivity
.class);
1727 i
.putExtra(ConflictsResolveActivity
.EXTRA_FILE
, syncedFile
);
1728 i
.putExtra(ConflictsResolveActivity
.EXTRA_ACCOUNT
, getAccount());
1734 if (operation
.transferWasRequested()) {
1735 onTransferStateChanged(syncedFile
, true
, true
);
1738 Toast msg
= Toast
.makeText(this, ErrorMessageAdapter
.getErrorCauseMessage(result
,
1739 operation
, getResources()), Toast
.LENGTH_LONG
);
1746 * Updates the view associated to the activity after the finish of an operation trying create a
1749 * @param operation Creation operation performed.
1750 * @param result Result of the creation.
1752 private void onCreateFolderOperationFinish(CreateFolderOperation operation
,
1753 RemoteOperationResult result
) {
1754 if (result
.isSuccess()) {
1755 dismissLoadingDialog();
1756 refreshListOfFilesFragment();
1758 dismissLoadingDialog();
1760 Toast msg
= Toast
.makeText(FileDisplayActivity
.this,
1761 ErrorMessageAdapter
.getErrorCauseMessage(result
, operation
, getResources()),
1765 } catch (NotFoundException e
) {
1766 Log_OC
.e(TAG
, "Error while trying to show fail message " , e
);
1776 public void onTransferStateChanged(OCFile file
, boolean downloading
, boolean uploading
) {
1777 refreshListOfFilesFragment();
1778 FileFragment details
= getSecondFragment();
1779 if (details
!= null
&& details
instanceof FileDetailFragment
&&
1780 file
.equals(details
.getFile()) ) {
1781 if (downloading
|| uploading
) {
1782 ((FileDetailFragment
)details
).updateFileDetails(file
, getAccount());
1784 if (!file
.fileExists()) {
1785 cleanSecondFragment();
1787 ((FileDetailFragment
)details
).updateFileDetails(false
, true
);
1795 private void requestForDownload() {
1796 Account account
= getAccount();
1797 //if (!mWaitingToPreview.isDownloading()) {
1798 if (!mDownloaderBinder
.isDownloading(account
, mWaitingToPreview
)) {
1799 Intent i
= new Intent(this, FileDownloader
.class);
1800 i
.putExtra(FileDownloader
.EXTRA_ACCOUNT
, account
);
1801 i
.putExtra(FileDownloader
.EXTRA_FILE
, mWaitingToPreview
);
1807 private OCFile
getCurrentDir() {
1808 OCFile file
= getFile();
1810 if (file
.isFolder()) {
1812 } else if (getStorageManager() != null
) {
1813 String parentPath
= file
.getRemotePath().substring(0,
1814 file
.getRemotePath().lastIndexOf(file
.getFileName()));
1815 return getStorageManager().getFileByPath(parentPath
);
1821 public void startSyncFolderOperation(OCFile folder
, boolean ignoreETag
) {
1822 long currentSyncTime
= System
.currentTimeMillis();
1824 mSyncInProgress
= true
;
1826 // perform folder synchronization
1827 RemoteOperation synchFolderOp
= new RefreshFolderOperation( folder
,
1830 getFileOperationsHelper().isSharedSupported(),
1832 getStorageManager(),
1834 getApplicationContext()
1836 synchFolderOp
.execute(getAccount(), MainApp
.getAppContext(), this, null
, null
);
1838 setSupportProgressBarIndeterminateVisibility(true
);
1840 setBackgroundText();
1844 * Show untrusted cert dialog
1846 public void showUntrustedCertDialog(RemoteOperationResult result
) {
1847 // Show a dialog with the certificate info
1848 SslUntrustedCertDialog dialog
= SslUntrustedCertDialog
.newInstanceForFullSslError(
1849 (CertificateCombinedException
) result
.getException());
1850 FragmentManager fm
= getSupportFragmentManager();
1851 FragmentTransaction ft
= fm
.beginTransaction();
1852 dialog
.show(ft
, DIALOG_UNTRUSTED_CERT
);
1855 private void requestForDownload(OCFile file
) {
1856 Account account
= getAccount();
1857 if (!mDownloaderBinder
.isDownloading(account
, mWaitingToPreview
)) {
1858 Intent i
= new Intent(this, FileDownloader
.class);
1859 i
.putExtra(FileDownloader
.EXTRA_ACCOUNT
, account
);
1860 i
.putExtra(FileDownloader
.EXTRA_FILE
, file
);
1865 private void sendDownloadedFile(){
1866 getFileOperationsHelper().sendDownloadedFile(mWaitingToSend
);
1867 mWaitingToSend
= null
;
1872 * Requests the download of the received {@link OCFile} , updates the UI
1873 * to monitor the download progress and prepares the activity to send the file
1874 * when the download finishes.
1876 * @param file {@link OCFile} to download and preview.
1878 public void startDownloadForSending(OCFile file
) {
1879 mWaitingToSend
= file
;
1880 requestForDownload(mWaitingToSend
);
1881 boolean hasSecondFragment
= (getSecondFragment()!= null
);
1882 updateFragmentsVisibility(hasSecondFragment
);
1886 * Opens the image gallery showing the image {@link OCFile} received as parameter.
1888 * @param file Image {@link OCFile} to show.
1890 public void startImagePreview(OCFile file
) {
1891 Intent showDetailsIntent
= new Intent(this, PreviewImageActivity
.class);
1892 showDetailsIntent
.putExtra(EXTRA_FILE
, file
);
1893 showDetailsIntent
.putExtra(EXTRA_ACCOUNT
, getAccount());
1894 startActivity(showDetailsIntent
);
1899 * Stars the preview of an already down media {@link OCFile}.
1901 * @param file Media {@link OCFile} to preview.
1902 * @param startPlaybackPosition Media position where the playback will be started,
1904 * @param autoplay When 'true', the playback will start without user
1907 public void startMediaPreview(OCFile file
, int startPlaybackPosition
, boolean autoplay
) {
1908 Fragment mediaFragment
= new PreviewMediaFragment(file
, getAccount(), startPlaybackPosition
,
1910 setSecondFragment(mediaFragment
);
1911 updateFragmentsVisibility(true
);
1912 updateNavigationElementsInActionBar(file
);
1917 * Requests the download of the received {@link OCFile} , updates the UI
1918 * to monitor the download progress and prepares the activity to preview
1919 * or open the file when the download finishes.
1921 * @param file {@link OCFile} to download and preview.
1923 public void startDownloadForPreview(OCFile file
) {
1924 Fragment detailFragment
= new FileDetailFragment(file
, getAccount());
1925 setSecondFragment(detailFragment
);
1926 mWaitingToPreview
= file
;
1927 requestForDownload();
1928 updateFragmentsVisibility(true
);
1929 updateNavigationElementsInActionBar(file
);
1934 public void cancelTransference(OCFile file
) {
1935 getFileOperationsHelper().cancelTransference(file
);
1936 if (mWaitingToPreview
!= null
&&
1937 mWaitingToPreview
.getRemotePath().equals(file
.getRemotePath())) {
1938 mWaitingToPreview
= null
;
1940 if (mWaitingToSend
!= null
&&
1941 mWaitingToSend
.getRemotePath().equals(file
.getRemotePath())) {
1942 mWaitingToSend
= null
;
1944 onTransferStateChanged(file
, false
, false
);
1948 public void onRefresh(boolean ignoreETag
) {
1949 refreshList(ignoreETag
);
1953 public void onRefresh() {
1957 private void refreshList(boolean ignoreETag
) {
1958 OCFileListFragment listOfFiles
= getListOfFilesFragment();
1959 if (listOfFiles
!= null
) {
1960 OCFile folder
= listOfFiles
.getCurrentFile();
1961 if (folder
!= null
) {
1962 /*mFile = mContainerActivity.getStorageManager().getFileById(mFile.getFileId());
1963 listDirectory(mFile);*/
1964 startSyncFolderOperation(folder
, ignoreETag
);
1969 private void sortByDate(boolean ascending
){
1970 getListOfFilesFragment().sortByDate(ascending
);
1973 private void sortBySize(boolean ascending
){
1974 getListOfFilesFragment().sortBySize(ascending
);
1977 private void sortByName(boolean ascending
){
1978 getListOfFilesFragment().sortByName(ascending
);
1981 public void restart(){
1982 Intent i
= new Intent(this, FileDisplayActivity
.class);
1983 i
.addFlags(Intent
.FLAG_ACTIVITY_CLEAR_TOP
);
1987 public void closeDrawer() {
1988 mDrawerLayout
.closeDrawers();
1991 private class DrawerItemClickListener
implements ListView
.OnItemClickListener
{
1993 public void onItemClick(AdapterView
<?
> parent
, View view
, int position
, long id
) {
1994 if (mShowAccounts
&& position
> 0){
1995 position
= position
- 1;
1999 mShowAccounts
= !mShowAccounts
;
2000 mNavigationDrawerAdapter
.setShowAccounts(mShowAccounts
);
2001 mNavigationDrawerAdapter
.notifyDataSetChanged();
2004 case 1: // All Files
2005 // TODO Enable when "On Device" is recovered ?
2006 //MainApp.showOnlyFilesOnDevice(false);
2007 mDrawerLayout
.closeDrawers();
2010 // TODO Enable when "On Device" is recovered ?
2012 // MainApp.showOnlyFilesOnDevice(true);
2013 // mDrawerLayout.closeDrawers();
2017 Intent settingsIntent
= new Intent(getApplicationContext(),
2019 startActivity(settingsIntent
);
2023 Intent loggerIntent
= new Intent(getApplicationContext(),
2024 LogHistoryActivity
.class);
2025 startActivity(loggerIntent
);