Merge branch 'zmatsuo-detailThumbnail' into develop
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / FileDisplayActivity.java
index 2c0a740..20bcdce 100644 (file)
 
 package com.owncloud.android.ui.activity;
 
-import java.io.File;
-
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AuthenticatorException;
 import android.annotation.TargetApi;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.ProgressDialog;
+import android.support.v7.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
-import android.content.ContentUris;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -47,31 +42,26 @@ import android.database.Cursor;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Environment;
 import android.os.IBinder;
 import android.preference.PreferenceManager;
-import android.provider.DocumentsContract;
-import android.provider.MediaStore;
 import android.provider.OpenableColumns;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentTransaction;
-import android.util.Log;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.view.GravityCompat;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.actionbarsherlock.app.ActionBar;
-import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
-import com.actionbarsherlock.view.Menu;
-import com.actionbarsherlock.view.MenuInflater;
-import com.actionbarsherlock.view.MenuItem;
-import com.actionbarsherlock.view.Window;
-import com.owncloud.android.BuildConfig;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
+import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
@@ -87,41 +77,46 @@ import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.operations.CopyFileOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
 import com.owncloud.android.operations.CreateShareOperation;
 import com.owncloud.android.operations.MoveFileOperation;
+import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.RemoveFileOperation;
 import com.owncloud.android.operations.RenameFileOperation;
 import com.owncloud.android.operations.SynchronizeFileOperation;
-import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.UnshareLinkOperation;
 import com.owncloud.android.services.observer.FileObserverService;
 import com.owncloud.android.syncadapter.FileSyncAdapter;
+import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
 import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
 import com.owncloud.android.ui.dialog.SslUntrustedCertDialog.OnSslUntrustedCertListener;
+import com.owncloud.android.ui.dialog.UploadSourceDialogFragment;
 import com.owncloud.android.ui.fragment.FileDetailFragment;
 import com.owncloud.android.ui.fragment.FileFragment;
 import com.owncloud.android.ui.fragment.OCFileListFragment;
 import com.owncloud.android.ui.preview.PreviewImageActivity;
 import com.owncloud.android.ui.preview.PreviewImageFragment;
 import com.owncloud.android.ui.preview.PreviewMediaFragment;
+import com.owncloud.android.ui.preview.PreviewTextFragment;
 import com.owncloud.android.ui.preview.PreviewVideoActivity;
 import com.owncloud.android.utils.DisplayUtils;
 import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.UriUtils;
 
+import java.io.File;
 
 /**
  * Displays, what files the user has available in his ownCloud.
  */
 
-public class FileDisplayActivity extends HookActivity implements
-FileFragment.ContainerActivity, OnNavigationListener, 
-OnSslUntrustedCertListener, OnEnforceableRefreshListener {
-    
-    private ArrayAdapter<String> mDirectories;
+public class FileDisplayActivity extends HookActivity
+        implements FileFragment.ContainerActivity,
+        OnSslUntrustedCertListener, OnEnforceableRefreshListener {
+
+
 
     private SyncBroadcastReceiver mSyncBroadcastReceiver;
     private UploadFinishReceiver mUploadFinishReceiver;
@@ -131,20 +126,18 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     private boolean mDualPane;
     private View mLeftFragmentContainer;
     private View mRightFragmentContainer;
+    private ProgressBar mProgressBar;
 
     private static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
     private static final String KEY_SYNC_IN_PROGRESS = "SYNC_IN_PROGRESS";
     private static final String KEY_WAITING_TO_SEND = "WAITING_TO_SEND";
 
-    public static final int DIALOG_SHORT_WAIT = 0;
-    private static final int DIALOG_CHOOSE_UPLOAD_SOURCE = 1;
-    private static final int DIALOG_CERT_NOT_SAVED = 2;
-    
     public static final String ACTION_DETAILS = "com.owncloud.android.ui.activity.action.DETAILS";
 
-    private static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
-    private static final int ACTION_SELECT_MULTIPLE_FILES = 2;
+    public static final int ACTION_SELECT_CONTENT_FROM_APPS = 1;
+    public static final int ACTION_SELECT_MULTIPLE_FILES = 2;
     public static final int ACTION_MOVE_FILES = 3;
+    public static final int ACTION_COPY_FILES = 4;
 
     private static final String TAG = FileDisplayActivity.class.getSimpleName();
 
@@ -152,49 +145,56 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     private static final String TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT";
 
     private OCFile mWaitingToPreview;
-    
+
     private boolean mSyncInProgress = false;
 
-    private String DIALOG_UNTRUSTED_CERT;
-    
+    private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT";
+    private static String DIALOG_CREATE_FOLDER = "DIALOG_CREATE_FOLDER";
+    private static String DIALOG_UPLOAD_SOURCE = "DIALOG_UPLOAD_SOURCE";
+    private static String DIALOG_CERT_NOT_SAVED = "DIALOG_CERT_NOT_SAVED";
+
     private OCFile mWaitingToSend;
 
+    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        Log_OC.d(TAG, "onCreate() start");
-        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
-
-        super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account is valid
+        Log_OC.v(TAG, "onCreate() start");
 
-        // PIN CODE request ;  best location is to decide, let's try this first
-        if (getIntent().getAction() != null && getIntent().getAction().equals(Intent.ACTION_MAIN) && savedInstanceState == null) {
-            requestPinCode();
-        } else if (getIntent().getAction() == null && savedInstanceState == null) {
-            requestPinCode();
-        }
+        super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account
+                                            // is valid
 
-        /// grant that FileObserverService is watching favourite files
+        /// grant that FileObserverService is watching favorite files
         if (savedInstanceState == null) {
             Intent initObserversIntent = FileObserverService.makeInitIntent(this);
             startService(initObserversIntent);
         }
-        
+
         /// Load of saved instance state
         if(savedInstanceState != null) {
-            mWaitingToPreview = (OCFile) savedInstanceState.getParcelable(FileDisplayActivity.KEY_WAITING_TO_PREVIEW);
+            mWaitingToPreview = (OCFile) savedInstanceState.getParcelable(
+                    FileDisplayActivity.KEY_WAITING_TO_PREVIEW);
             mSyncInProgress = savedInstanceState.getBoolean(KEY_SYNC_IN_PROGRESS);
-            mWaitingToSend = (OCFile) savedInstanceState.getParcelable(FileDisplayActivity.KEY_WAITING_TO_SEND);
-           
+            mWaitingToSend = (OCFile) savedInstanceState.getParcelable(
+                    FileDisplayActivity.KEY_WAITING_TO_SEND);
         } else {
             mWaitingToPreview = null;
             mSyncInProgress = false;
             mWaitingToSend = null;
-        }        
+        }
 
         /// USER INTERFACE
 
         // Inflate and set the layout view
-        setContentView(R.layout.files);    
+        setContentView(R.layout.files);
+
+        // Navigation Drawer
+        initDrawer();
+
+        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
+        mProgressBar.setIndeterminateDrawable(
+                ContextCompat.getDrawable(this,
+                        R.drawable.actionbar_progress_indeterminate_horizontal));
+
         mDualPane = getResources().getBoolean(R.bool.large_land_layout);
         mLeftFragmentContainer = findViewById(R.id.left_fragment_container);
         mRightFragmentContainer = findViewById(R.id.right_fragment_container);
@@ -203,46 +203,59 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         }
 
         // Action bar setup
-        mDirectories = new CustomArrayAdapter<String>(this, R.layout.sherlock_spinner_dropdown_item);
-        getSupportActionBar().setHomeButtonEnabled(true);       // mandatory since Android ICS, according to the official documentation
-        setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/);    // always AFTER setContentView(...) ; to work around bug in its implementation
-        
+        getSupportActionBar().setHomeButtonEnabled(true);       // mandatory since Android ICS,
+                                                                // according to the official
+                                                                // documentation
+
+        // enable ActionBar app icon to behave as action to toggle nav drawer
+        //getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+        getSupportActionBar().setHomeButtonEnabled(true);
+
+        mProgressBar.setIndeterminate(mSyncInProgress);
+        // always AFTER setContentView(...) ; to work around bug in its implementation
+
         setBackgroundText();
 
-        Log_OC.d(TAG, "onCreate() end");
+        Log_OC.v(TAG, "onCreate() end");
     }
-    
+
     @Override
     protected void onStart() {
+        Log_OC.v(TAG, "onStart() start");
         super.onStart();
-        getSupportActionBar().setIcon(DisplayUtils.getSeasonalIconId());
+        Log_OC.v(TAG, "onStart() end");
     }
 
     @Override
     protected void onDestroy() {
+        Log_OC.v(TAG, "onDestroy() start");
         super.onDestroy();
+        Log_OC.v(TAG, "onDestroy() end");
     }
 
     /**
-     *  Called when the ownCloud {@link Account} associated to the Activity was just updated.
-     */ 
+     * Called when the ownCloud {@link Account} associated to the Activity was just updated.
+     */
     @Override
     protected void onAccountSet(boolean stateWasRecovered) {
         super.onAccountSet(stateWasRecovered);
         if (getAccount() != null) {
-            /// Check whether the 'main' OCFile handled by the Activity is contained in the current Account
+            /// Check whether the 'main' OCFile handled by the Activity is contained in the
+            // current Account
             OCFile file = getFile();
             // get parent from path
             String parentPath = "";
             if (file != null) {
                 if (file.isDown() && file.getLastSyncDateForProperties() == 0) {
-                    // upload in progress - right now, files are not inserted in the local cache until the upload is successful
-                    // get parent from path
-                    parentPath = file.getRemotePath().substring(0, file.getRemotePath().lastIndexOf(file.getFileName()));
+                    // upload in progress - right now, files are not inserted in the local
+                    // cache until the upload is successful get parent from path
+                    parentPath = file.getRemotePath().substring(0,
+                            file.getRemotePath().lastIndexOf(file.getFileName()));
                     if (getStorageManager().getFileByPath(parentPath) ==  null)
                         file = null; // not able to know the directory where the file is uploading
                 } else {
-                    file = getStorageManager().getFileByPath(file.getRemotePath());   // currentDir = null if not in the current Account
+                    file = getStorageManager().getFileByPath(file.getRemotePath());
+                    // currentDir = null if not in the current Account
                 }
             }
             if (file == null) {
@@ -250,66 +263,62 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                 file = getStorageManager().getFileByPath(OCFile.ROOT_PATH);  // never returns null
             }
             setFile(file);
-            setNavigationListWithFolder(file);
-            
+
+            if (mAccountWasSet) {
+                RelativeLayout navigationDrawerLayout = (RelativeLayout) findViewById(R.id.left_drawer);
+                if (navigationDrawerLayout != null && getAccount() != null) {
+                    TextView username = (TextView) navigationDrawerLayout.findViewById(R.id.drawer_username);
+                    int lastAtPos = getAccount().name.lastIndexOf("@");
+                    username.setText(getAccount().name.substring(0, lastAtPos));
+                }
+            }
+
             if (!stateWasRecovered) {
                 Log_OC.d(TAG, "Initializing Fragments in onAccountChanged..");
                 initFragmentsWithFile();
                 if (file.isFolder()) {
                     startSyncFolderOperation(file, false);
                 }
-                
+
             } else {
                 updateFragmentsVisibility(!file.isFolder());
-                updateNavigationElementsInActionBar(file.isFolder() ? null : file);
+                updateActionBarTitleAndHomeButton(file.isFolder() ? null : file);
             }
         }
     }
 
-
-    private void setNavigationListWithFolder(OCFile file) {
-        mDirectories.clear();
-        OCFile fileIt = file;
-        String parentPath;
-        while(fileIt != null && !OCFile.ROOT_PATH.equals(fileIt.getFileName())) {
-            if (fileIt.isFolder()) {
-                mDirectories.add(fileIt.getFileName());
-            }
-            // get parent from path
-            parentPath = fileIt.getRemotePath().substring(0, fileIt.getRemotePath().lastIndexOf(fileIt.getFileName()));
-            fileIt = getStorageManager().getFileByPath(parentPath);
-        }
-        mDirectories.add(OCFile.PATH_SEPARATOR);
-    }
-
-
     private void createMinFragments() {
         OCFileListFragment listOfFiles = new OCFileListFragment();
         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
         transaction.add(R.id.left_fragment_container, listOfFiles, TAG_LIST_OF_FILES);
         transaction.commit();
     }
-    
+
     private void initFragmentsWithFile() {
         if (getAccount() != null && getFile() != null) {
             /// First fragment
-            OCFileListFragment listOfFiles = getListOfFilesFragment(); 
+            OCFileListFragment listOfFiles = getListOfFilesFragment();
             if (listOfFiles != null) {
-                listOfFiles.listDirectory(getCurrentDir());   
+                listOfFiles.listDirectory(getCurrentDir());
+                // TODO Enable when "On Device" is recovered
+                // listOfFiles.listDirectory(getCurrentDir(), MainApp.getOnlyOnDevice());
+
             } else {
                 Log_OC.e(TAG, "Still have a chance to lose the initializacion of list fragment >(");
             }
-            
+
             /// Second fragment
-            OCFile file = getFile(); 
+            OCFile file = getFile();
             Fragment secondFragment = chooseInitialSecondFragment(file);
             if (secondFragment != null) {
                 setSecondFragment(secondFragment);
                 updateFragmentsVisibility(true);
-                updateNavigationElementsInActionBar(file);
-                
+                updateActionBarTitleAndHomeButton(file);
+
             } else {
                 cleanSecondFragment();
+                if (file.isDown() && PreviewTextFragment.canBePreviewed(file))
+                    startTextPreview(file);
             }
 
         } else {
@@ -326,16 +335,21 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     private Fragment chooseInitialSecondFragment(OCFile file) {
         Fragment secondFragment = null;
         if (file != null && !file.isFolder()) {
-            if (file.isDown() && PreviewMediaFragment.canBePreviewed(file) 
+            if (file.isDown() && PreviewMediaFragment.canBePreviewed(file)
                     && file.getLastSyncDateForProperties() > 0  // temporal fix
                     ) {
-                int startPlaybackPosition = getIntent().getIntExtra(PreviewVideoActivity.EXTRA_START_POSITION, 0);
-                boolean autoplay = getIntent().getBooleanExtra(PreviewVideoActivity.EXTRA_AUTOPLAY, true);
-                secondFragment = new PreviewMediaFragment(file, getAccount(), startPlaybackPosition, autoplay);
-
+                int startPlaybackPosition =
+                        getIntent().getIntExtra(PreviewVideoActivity.EXTRA_START_POSITION, 0);
+                boolean autoplay =
+                        getIntent().getBooleanExtra(PreviewVideoActivity.EXTRA_AUTOPLAY, true);
+                secondFragment = new PreviewMediaFragment(file, getAccount(),
+                        startPlaybackPosition, autoplay);
+
+            } else if (file.isDown() && PreviewTextFragment.canBePreviewed(file)) {
+                secondFragment = null;
             } else {
-                secondFragment = new FileDetailFragment(file, getAccount());
-            }
+            secondFragment = FileDetailFragment.newInstance(file, getAccount());
+        }
         }
         return secondFragment;
     }
@@ -344,10 +358,10 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     /**
      * Replaces the second fragment managed by the activity with the received as
      * a parameter.
-     * 
-     * Assumes never will be more than two fragments managed at the same time. 
-     * 
-     * @param fragment      New second Fragment to set.
+     * <p/>
+     * Assumes never will be more than two fragments managed at the same time.
+     *
+     * @param fragment New second Fragment to set.
      */
     private void setSecondFragment(Fragment fragment) {
         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
@@ -385,18 +399,20 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
 
     private OCFileListFragment getListOfFilesFragment() {
-        Fragment listOfFiles = getSupportFragmentManager().findFragmentByTag(FileDisplayActivity.TAG_LIST_OF_FILES);
+        Fragment listOfFiles = getSupportFragmentManager().findFragmentByTag(
+                FileDisplayActivity.TAG_LIST_OF_FILES);
         if (listOfFiles != null) {
-            return (OCFileListFragment)listOfFiles;
+            return (OCFileListFragment) listOfFiles;
         }
         Log_OC.wtf(TAG, "Access to unexisting list of files fragment!!");
         return null;
     }
 
     public FileFragment getSecondFragment() {
-        Fragment second = getSupportFragmentManager().findFragmentByTag(FileDisplayActivity.TAG_SECOND_FRAGMENT);
+        Fragment second = getSupportFragmentManager().findFragmentByTag(
+                FileDisplayActivity.TAG_SECOND_FRAGMENT);
         if (second != null) {
-            return (FileFragment)second;
+            return (FileFragment) second;
         }
         return null;
     }
@@ -409,23 +425,28 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             tr.commit();
         }
         updateFragmentsVisibility(false);
-        updateNavigationElementsInActionBar(null);
+        updateActionBarTitleAndHomeButton(null);
     }
 
     protected void refreshListOfFilesFragment() {
         OCFileListFragment fileListFragment = getListOfFilesFragment();
-        if (fileListFragment != null) { 
+        if (fileListFragment != null) {
             fileListFragment.listDirectory();
+            // TODO Enable when "On Device" is recovered ?
+            // fileListFragment.listDirectory(MainApp.getOnlyOnDevice());
         }
     }
 
-    protected void refreshSecondFragment(String downloadEvent, String downloadedRemotePath, boolean success) {
+    protected void refreshSecondFragment(String downloadEvent, String downloadedRemotePath,
+                                         boolean success) {
         FileFragment secondFragment = getSecondFragment();
-        boolean waitedPreview = (mWaitingToPreview != null && mWaitingToPreview.getRemotePath().equals(downloadedRemotePath));
+        boolean waitedPreview = (mWaitingToPreview != null &&
+                mWaitingToPreview.getRemotePath().equals(downloadedRemotePath));
         if (secondFragment != null && secondFragment instanceof FileDetailFragment) {
             FileDetailFragment detailsFragment = (FileDetailFragment) secondFragment;
             OCFile fileInFragment = detailsFragment.getFile();
-            if (fileInFragment != null && !downloadedRemotePath.equals(fileInFragment.getRemotePath())) {
+            if (fileInFragment != null &&
+                    !downloadedRemotePath.equals(fileInFragment.getRemotePath())) {
                 // the user browsed to other file ; forget the automatic preview 
                 mWaitingToPreview = null;
 
@@ -439,10 +460,15 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                 boolean detailsFragmentChanged = false;
                 if (waitedPreview) {
                     if (success) {
-                        mWaitingToPreview = getStorageManager().getFileById(mWaitingToPreview.getFileId());   // update the file from database, for the local storage path
+                        mWaitingToPreview = getStorageManager().getFileById(
+                                mWaitingToPreview.getFileId());   // update the file from database,
+                                                                  // for the local storage path
                         if (PreviewMediaFragment.canBePreviewed(mWaitingToPreview)) {
                             startMediaPreview(mWaitingToPreview, 0, true);
                             detailsFragmentChanged = true;
+                        } else if (PreviewTextFragment.canBePreviewed(mWaitingToPreview)) {
+                            startTextPreview(mWaitingToPreview);
+                            detailsFragmentChanged = true;
                         } else {
                             getFileOperationsHelper().openFile(mWaitingToPreview);
                         }
@@ -458,93 +484,86 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
-        if (BuildConfig.DEBUG) {
-            menu.findItem(R.id.action_logger).setVisible(true);
-        } else {
-            menu.findItem(R.id.action_logger).setVisible(false);
-        }
+        boolean drawerOpen = mDrawerLayout.isDrawerOpen(GravityCompat.START);
+        menu.findItem(R.id.action_upload).setVisible(!drawerOpen);
+        menu.findItem(R.id.action_create_dir).setVisible(!drawerOpen);
+        menu.findItem(R.id.action_sort).setVisible(!drawerOpen);
+        menu.findItem(R.id.action_sync_account).setVisible(!drawerOpen);
+        
         return super.onPrepareOptionsMenu(menu);
     }
 
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getSherlock().getMenuInflater();
+        MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.main_menu, menu);
         return true;
     }
+    
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         boolean retval = true;
         switch (item.getItemId()) {
-        case R.id.action_create_dir: {
-            CreateFolderDialogFragment dialog = 
-                    CreateFolderDialogFragment.newInstance(getCurrentDir());
-            dialog.show(getSupportFragmentManager(), "createdirdialog");
-            break;
-        }
-        case R.id.action_sync_account: {
-            startSynchronization();
-            break;
-        }
-        case R.id.action_upload: {
-            showDialog(DIALOG_CHOOSE_UPLOAD_SOURCE);
-            break;
-        }
-        case R.id.action_settings: {
-            Intent settingsIntent = new Intent(this, Preferences.class);
-            startActivity(settingsIntent);
-            break;
-        }
-        case R.id.action_logger: {
-            Intent loggerIntent = new Intent(getApplicationContext(),LogHistoryActivity.class);
-            startActivity(loggerIntent);
-            break;
-        }
-        case android.R.id.home: {
-            FileFragment second = getSecondFragment();
-            OCFile currentDir = getCurrentDir();
-            if((currentDir != null && currentDir.getParentId() != 0) || 
-                    (second != null && second.getFile() != null)) {                
-                onBackPressed(); 
-                
+            case R.id.action_create_dir: {
+                CreateFolderDialogFragment dialog =
+                        CreateFolderDialogFragment.newInstance(getCurrentDir());
+                dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
+                break;
             }
-            break;
-        }
-        case R.id.action_sort: {
-            SharedPreferences appPreferences = PreferenceManager
-                    .getDefaultSharedPreferences(this);
-            
-            // Read sorting order, default to sort by name ascending
-            Integer sortOrder = appPreferences
-                    .getInt("sortOrder", FileStorageUtils.SORT_NAME);
-            
-            AlertDialog.Builder builder = new AlertDialog.Builder(this);
-            builder.setTitle(R.string.actionbar_sort_title)
-            .setSingleChoiceItems(R.array.actionbar_sortby, sortOrder , new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int which) {
-                    
-                    switch (which){
-                    case 0:
-                        sortByName(true);
-                        break;
-                    case 1:
-                        sortByDate(false);
-                        break;
-                        
-// TODO re-enable when server-side folder size calculation is available                       
-//                    case 2:
-//                        sortBySize(false);
-//                        break;
-                    }
-                    
-                    dialog.dismiss();
-                    
+
+            case R.id.action_sync_account: {
+                startSynchronization();
+                break;
+            }
+            case R.id.action_upload: {
+                UploadSourceDialogFragment dialog =
+                        UploadSourceDialogFragment.newInstance(getAccount());
+                dialog.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE);
+                break;
+            }
+            case android.R.id.home: {
+                FileFragment second = getSecondFragment();
+                OCFile currentDir = getCurrentDir();
+                if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
+                    mDrawerLayout.closeDrawer(GravityCompat.START);
+                } else if((currentDir != null && currentDir.getParentId() != 0) ||
+                        (second != null && second.getFile() != null)) {
+                    onBackPressed();
+
+                } else {
+                    mDrawerLayout.openDrawer(GravityCompat.START);
                 }
-            });
-            builder.create().show();
-            break;
-        }
+                break;
+            }
+            case R.id.action_sort: {
+                SharedPreferences appPreferences = PreferenceManager
+                        .getDefaultSharedPreferences(this);
+
+                // Read sorting order, default to sort by name ascending
+                Integer sortOrder = appPreferences
+                        .getInt("sortOrder", FileStorageUtils.SORT_NAME);
+
+                AlertDialog.Builder builder = new AlertDialog.Builder(this);
+                builder.setTitle(R.string.actionbar_sort_title)
+                        .setSingleChoiceItems(R.array.actionbar_sortby, sortOrder ,
+                                new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int which) {
+                                switch (which){
+                                    case 0:
+                                        sortByName(true);
+                                        break;
+                                    case 1:
+                                        sortByDate(false);
+                                        break;
+                                }
+
+                                dialog.dismiss();
+                            }
+                        });
+                builder.create().show();
+                break;
+            }
         default:
             retval = super.onOptionsItemSelected(item);
         }
@@ -555,16 +574,19 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         Log_OC.d(TAG, "Got to start sync");
         if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
             Log_OC.d(TAG, "Canceling all syncs for " + MainApp.getAuthority());
-            ContentResolver.cancelSync(null, MainApp.getAuthority());   // cancel the current synchronizations of any ownCloud account
+            ContentResolver.cancelSync(null, MainApp.getAuthority());
+            // cancel the current synchronizations of any ownCloud account
             Bundle bundle = new Bundle();
             bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
             bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
-            Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority());
+            Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " +
+                    MainApp.getAuthority());
             ContentResolver.requestSync(
                     getAccount(),
                     MainApp.getAuthority(), bundle);
         } else {
-            Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " + MainApp.getAuthority() + " with new API");
+            Log_OC.d(TAG, "Requesting sync for " + getAccount().name + " at " +
+                    MainApp.getAuthority() + " with new API");
             SyncRequest.Builder builder = new SyncRequest.Builder();
             builder.setSyncAdapter(getAccount(), MainApp.getAuthority());
             builder.setExpedited(true);
@@ -580,38 +602,16 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         }
     }
 
-
-    @Override
-    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
-        if (itemPosition != 0) {
-            String targetPath = "";
-            for (int i=itemPosition; i < mDirectories.getCount() - 1; i++) {
-                targetPath = mDirectories.getItem(i) + OCFile.PATH_SEPARATOR + targetPath; 
-            }
-            targetPath = OCFile.PATH_SEPARATOR + targetPath;
-            OCFile targetFolder = getStorageManager().getFileByPath(targetPath);
-            if (targetFolder != null) {
-                browseTo(targetFolder);
-            }
-            
-            // the next operation triggers a new call to this method, but it's necessary to 
-            // ensure that the name exposed in the action bar is the current directory when the 
-            // user selected it in the navigation list
-            if (getSupportActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_LIST  && itemPosition != 0) 
-                getSupportActionBar().setSelectedNavigationItem(0);
-        }
-        return true;
-    }
-
     /**
      * Called, when the user selected something for uploading
      *
      */
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        super.onActivityResult(requestCode, resultCode, data);
 
-        if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
+        if (requestCode == ACTION_SELECT_CONTENT_FROM_APPS && (resultCode == RESULT_OK ||
+                resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
             //getClipData is only supported on api level 16+, Jelly Bean
             if (data.getData() == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
                 for( int i = 0; i < data.getClipData().getItemCount(); i++){
@@ -622,36 +622,48 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             }else {
                 requestSimpleUpload(data, resultCode);
             }
-        } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && (resultCode == RESULT_OK || resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
+        } else if (requestCode == ACTION_SELECT_MULTIPLE_FILES && (resultCode == RESULT_OK ||
+                resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
             requestMultipleUpload(data, resultCode);
 
         } else if (requestCode == ACTION_MOVE_FILES && resultCode == RESULT_OK){
+            final Intent fData = data;
+            final int fResultCode = resultCode;
+            getHandler().postDelayed(
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            requestMoveOperation(fData, fResultCode);
+                        }
+                    },
+                    DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
+            );
+
+        } else if (requestCode == ACTION_COPY_FILES && resultCode == RESULT_OK) {
 
             final Intent fData = data;
-            final int fResultCode = resultCode; 
+            final int fResultCode = resultCode;
             getHandler().postDelayed(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        requestMoveOperation(fData, fResultCode);
-                    }
-                }, 
-                DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
+                    new Runnable() {
+                        @Override
+                        public void run() {
+                            requestCopyOperation(fData, fResultCode);
+                        }
+                    },
+                    DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
             );
+
+        } else {
+            super.onActivityResult(requestCode, resultCode, data);
         }
+
     }
 
     private void requestMultipleUpload(Intent data, int resultCode) {
         String[] filePaths = data.getStringArrayExtra(UploadFilesActivity.EXTRA_CHOSEN_FILES);
         if (filePaths != null) {
             String[] remotePaths = new String[filePaths.length];
-            String remotePathBase = "";
-
-            for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
-                remotePathBase += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
-            }
-            if (!remotePathBase.endsWith(OCFile.PATH_SEPARATOR))
-                remotePathBase += OCFile.PATH_SEPARATOR;
+            String remotePathBase = getCurrentDir().getRemotePath();
             for (int j = 0; j< remotePaths.length; j++) {
                 remotePaths[j] = remotePathBase + (new File(filePaths[j])).getName();
             }
@@ -667,7 +679,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
         } else {
             Log_OC.d(TAG, "User clicked on 'Update' with no selection");
-            Toast t = Toast.makeText(this, getString(R.string.filedisplay_no_file_selected), Toast.LENGTH_LONG);
+            Toast t = Toast.makeText(this, getString(R.string.filedisplay_no_file_selected),
+                    Toast.LENGTH_LONG);
             t.show();
             return;
         }
@@ -675,7 +688,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
 
     private void requestSimpleUpload(Intent data, int resultCode) {
-        String filepath = null;
+        String filePath = null;
         String mimeType = null;
 
         Uri selectedImageUri = data.getData();
@@ -683,75 +696,71 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         try {
             mimeType = getContentResolver().getType(selectedImageUri);
 
-            String filemanagerstring = selectedImageUri.getPath();
-            String selectedImagePath = getPath(selectedImageUri);
+            String fileManagerString = selectedImageUri.getPath();
+            String selectedImagePath = UriUtils.getLocalPath(selectedImageUri, this);
 
             if (selectedImagePath != null)
-                filepath = selectedImagePath;
+                filePath = selectedImagePath;
             else
-                filepath = filemanagerstring;
+                filePath = fileManagerString;
 
         } catch (Exception e) {
-            Log_OC.e(TAG, "Unexpected exception when trying to read the result of Intent.ACTION_GET_CONTENT", e);
-            e.printStackTrace();
+            Log_OC.e(TAG, "Unexpected exception when trying to read the result of " +
+                    "Intent.ACTION_GET_CONTENT", e);
 
         } finally {
-            if (filepath == null) {
+            if (filePath == null) {
                 Log_OC.e(TAG, "Couldn't resolve path to file");
-                Toast t = Toast.makeText(this, getString(R.string.filedisplay_unexpected_bad_get_content), Toast.LENGTH_LONG);
+                Toast t = Toast.makeText(
+                        this, getString(R.string.filedisplay_unexpected_bad_get_content),
+                        Toast.LENGTH_LONG
+                );
                 t.show();
                 return;
             }
         }
 
         Intent i = new Intent(this, FileUploader.class);
-        i.putExtra(FileUploader.KEY_ACCOUNT,
-                getAccount());
-        String remotepath = new String();
-        for (int j = mDirectories.getCount() - 2; j >= 0; --j) {
-            remotepath += OCFile.PATH_SEPARATOR + mDirectories.getItem(j);
-        }
-        if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
-            remotepath += OCFile.PATH_SEPARATOR;
-
-        if (filepath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
-
-            Cursor cursor = MainApp.getAppContext().getContentResolver()
-                    .query(Uri.parse(filepath), null, null, null, null, null);
+        i.putExtra(FileUploader.KEY_ACCOUNT, getAccount());
+        OCFile currentDir = getCurrentDir();
+        String remotePath =  (currentDir != null) ? currentDir.getRemotePath() : OCFile.ROOT_PATH;
 
+        if (filePath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
+            Cursor cursor = getContentResolver().query(Uri.parse(filePath), null, null, null, null);
             try {
                 if (cursor != null && cursor.moveToFirst()) {
-                    String displayName = cursor.getString(
-                            cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
-                    Log.i(TAG, "Display Name: " + displayName + "; mimeType: " + mimeType);
+                    String displayName = cursor.getString(cursor.getColumnIndex(
+                            OpenableColumns.DISPLAY_NAME));
+                    Log_OC.v(TAG, "Display Name: " + displayName );
 
                     displayName.replace(File.separatorChar, '_');
                     displayName.replace(File.pathSeparatorChar, '_');
-                    remotepath += displayName + DisplayUtils.getComposedFileExtension(filepath);
+                    remotePath += displayName + DisplayUtils.getComposedFileExtension(filePath);
 
                 }
+                // and what happens in case of error?; wrong target name for the upload
             } finally {
                 cursor.close();
             }
 
         } else {
-            remotepath += new File(filepath).getName();
+            remotePath += new File(filePath).getName();
         }
 
-        i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
-        i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
+        i.putExtra(FileUploader.KEY_LOCAL_FILE, filePath);
+        i.putExtra(FileUploader.KEY_REMOTE_FILE, remotePath);
         i.putExtra(FileUploader.KEY_MIME_TYPE, mimeType);
         i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
         if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
-            i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
+        i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
         startService(i);
     }
 
     /**
      * Request the operation for moving the file/folder from one path to another
-     * 
-     * @param data              Intent received
-     * @param resultCode        Result code received
+     *
+     * @param data       Intent received
+     * @param resultCode Result code received
      */
     private void requestMoveOperation(Intent data, int resultCode) {
         OCFile folderToMoveAt = (OCFile) data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
@@ -759,48 +768,64 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         getFileOperationsHelper().moveFile(folderToMoveAt, targetFile);
     }
 
+    /**
+     * Request the operation for copying the file/folder from one path to another
+     *
+     * @param data       Intent received
+     * @param resultCode Result code received
+     */
+    private void requestCopyOperation(Intent data, int resultCode) {
+        OCFile folderToMoveAt = data.getParcelableExtra(FolderPickerActivity.EXTRA_FOLDER);
+        OCFile targetFile = data.getParcelableExtra(FolderPickerActivity.EXTRA_FILE);
+        getFileOperationsHelper().copyFile(folderToMoveAt, targetFile);
+    }
+
     @Override
     public void onBackPressed() {
-        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
-        if (mDualPane || getSecondFragment() == null) {
-            if (listOfFiles != null) {  // should never be null, indeed
-                if (mDirectories.getCount() <= 1) {
+        if (!isDrawerOpen()){
+            OCFileListFragment listOfFiles = getListOfFilesFragment();
+            if (mDualPane || getSecondFragment() == null) {
+                OCFile currentDir = getCurrentDir();
+                if (currentDir == null || currentDir.getParentId() == FileDataStorageManager.ROOT_PARENT_ID) {
                     finish();
                     return;
                 }
-                int levelsUp = listOfFiles.onBrowseUp();
-                for (int i=0; i < levelsUp && mDirectories.getCount() > 1 ; i++) {
-                    popDirname();
+                if (listOfFiles != null) {  // should never be null, indeed
+                    listOfFiles.onBrowseUp();
                 }
             }
+            if (listOfFiles != null) {  // should never be null, indeed
+                setFile(listOfFiles.getCurrentFile());
+            }
+            cleanSecondFragment();
+        } else {
+            super.onBackPressed();
         }
-        if (listOfFiles != null) {  // should never be null, indeed
-            setFile(listOfFiles.getCurrentFile());
-        }
-        cleanSecondFragment();
-
     }
 
     @Override
     protected void onSaveInstanceState(Bundle outState) {
-        // responsibility of restore is preferred in onCreate() before than in onRestoreInstanceState when there are Fragments involved
-        Log_OC.d(TAG, "onSaveInstanceState() start");
+        // responsibility of restore is preferred in onCreate() before than in
+        // onRestoreInstanceState when there are Fragments involved
+        Log_OC.v(TAG, "onSaveInstanceState() start");
         super.onSaveInstanceState(outState);
         outState.putParcelable(FileDisplayActivity.KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
         outState.putBoolean(FileDisplayActivity.KEY_SYNC_IN_PROGRESS, mSyncInProgress);
-        //outState.putBoolean(FileDisplayActivity.KEY_REFRESH_SHARES_IN_PROGRESS, mRefreshSharesInProgress);
+        //outState.putBoolean(FileDisplayActivity.KEY_REFRESH_SHARES_IN_PROGRESS,
+        // mRefreshSharesInProgress);
         outState.putParcelable(FileDisplayActivity.KEY_WAITING_TO_SEND, mWaitingToSend);
 
-        Log_OC.d(TAG, "onSaveInstanceState() end");
+        Log_OC.v(TAG, "onSaveInstanceState() end");
     }
-    
 
 
     @Override
     protected void onResume() {
+        Log_OC.v(TAG, "onResume() start");
         super.onResume();
-        Log_OC.d(TAG, "onResume() start");
-        
+        // refresh Navigation Drawer account list
+        mNavigationDrawerAdapter.updateAccountList();
+
         // refresh list of files
         refreshListOfFilesFragment();
 
@@ -812,7 +837,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         syncIntentFilter.addAction(RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED);
         mSyncBroadcastReceiver = new SyncBroadcastReceiver();
         registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
-        //LocalBroadcastManager.getInstance(this).registerReceiver(mSyncBroadcastReceiver, syncIntentFilter);
+        //LocalBroadcastManager.getInstance(this).registerReceiver(mSyncBroadcastReceiver,
+        // syncIntentFilter);
 
         // Listen for upload messages
         IntentFilter uploadIntentFilter = new IntentFilter(FileUploader.getUploadFinishMessage());
@@ -820,18 +846,20 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         registerReceiver(mUploadFinishReceiver, uploadIntentFilter);
 
         // Listen for download messages
-        IntentFilter downloadIntentFilter = new IntentFilter(FileDownloader.getDownloadAddedMessage());
+        IntentFilter downloadIntentFilter = new IntentFilter(
+                FileDownloader.getDownloadAddedMessage());
         downloadIntentFilter.addAction(FileDownloader.getDownloadFinishMessage());
         mDownloadFinishReceiver = new DownloadFinishReceiver();
         registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
-        
-        Log_OC.d(TAG, "onResume() end");
+
+        Log_OC.v(TAG, "onResume() end");
+
     }
 
 
     @Override
     protected void onPause() {
-        Log_OC.d(TAG, "onPause() start");
+        Log_OC.v(TAG, "onPause() start");
         if (mSyncBroadcastReceiver != null) {
             unregisterReceiver(mSyncBroadcastReceiver);
             //LocalBroadcastManager.getInstance(this).unregisterReceiver(mSyncBroadcastReceiver);
@@ -845,209 +873,11 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             unregisterReceiver(mDownloadFinishReceiver);
             mDownloadFinishReceiver = null;
         }
-        
-        
-        Log_OC.d(TAG, "onPause() end");
-        super.onPause();
-    }
-
 
-    @Override
-    protected Dialog onCreateDialog(int id) {
-        Dialog dialog = null;
-        AlertDialog.Builder builder;
-        switch (id) {
-        case DIALOG_SHORT_WAIT: {
-            ProgressDialog working_dialog = new ProgressDialog(this);
-            working_dialog.setMessage(getResources().getString(
-                    R.string.wait_a_moment));
-            working_dialog.setIndeterminate(true);
-            working_dialog.setCancelable(false);
-            dialog = working_dialog;
-            break;
-        }
-        case DIALOG_CHOOSE_UPLOAD_SOURCE: {
-
-
-            String[] allTheItems = { getString(R.string.actionbar_upload_files),
-                    getString(R.string.actionbar_upload_from_apps) };
-
-            builder = new AlertDialog.Builder(this);
-            builder.setTitle(R.string.actionbar_upload);
-            builder.setItems(allTheItems, new DialogInterface.OnClickListener() {
-                public void onClick(DialogInterface dialog, int item) {
-                    if (item == 0) {
-                        // if (!mDualPane) {
-                            Intent action = new Intent(FileDisplayActivity.this, UploadFilesActivity.class);
-                            action.putExtra(UploadFilesActivity.EXTRA_ACCOUNT, FileDisplayActivity.this.getAccount());
-                            startActivityForResult(action, ACTION_SELECT_MULTIPLE_FILES);
-                            // } else {
-                            // TODO create and handle new fragment
-                            // LocalFileListFragment
-                            // }
-                    } else if (item == 1) {
-                        Intent action = new Intent(Intent.ACTION_GET_CONTENT);
-                        action = action.setType("*/*").addCategory(Intent.CATEGORY_OPENABLE);
-                        //Intent.EXTRA_ALLOW_MULTIPLE is only supported on api level 18+, Jelly Bean
-                        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
-                            action.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
-                        }
-                        startActivityForResult(Intent.createChooser(action, getString(R.string.upload_chooser_title)),
-                                ACTION_SELECT_CONTENT_FROM_APPS);
-                    }
-                }
-            });
-            dialog = builder.create();
-            break;
-        }
-        case DIALOG_CERT_NOT_SAVED: {
-            builder = new AlertDialog.Builder(this);
-            builder.setMessage(getResources().getString(R.string.ssl_validator_not_saved));
-            builder.setCancelable(false);
-            builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() {
-                @Override
-                public void onClick(DialogInterface dialog, int which) {
-                    dialog.dismiss();
-                };
-            });
-            dialog = builder.create();
-            break;
-        }
-        default:
-            dialog = null;
-        }
-
-        return dialog;
-    }
-
-    /**
-     * Translates a content URI of an content to a physical path on the disk
-     * 
-     * @param uri The URI to resolve
-     * @return The path to the content or null if it could not be found
-     */
-    public String getPath(Uri uri) {
-        final boolean isKitKatOrLater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
-
-        // DocumentProvider
-        if (isKitKatOrLater && DocumentsContract.isDocumentUri(getApplicationContext(), uri)) {
-            // ExternalStorageProvider
-            if (UriUtils.isExternalStorageDocument(uri)) {
-                final String docId = DocumentsContract.getDocumentId(uri);
-                final String[] split = docId.split(":");
-                final String type = split[0];
-
-                if ("primary".equalsIgnoreCase(type)) {
-                    return Environment.getExternalStorageDirectory() + "/" + split[1];
-                }
-            }
-            // DownloadsProvider
-            else if (UriUtils.isDownloadsDocument(uri)) {
-
-                final String id = DocumentsContract.getDocumentId(uri);
-                final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
-                        Long.valueOf(id));
-
-                return UriUtils.getDataColumn(getApplicationContext(), contentUri, null, null);
-            }
-            // MediaProvider
-            else if (UriUtils.isMediaDocument(uri)) {
-                final String docId = DocumentsContract.getDocumentId(uri);
-                final String[] split = docId.split(":");
-                final String type = split[0];
-
-                Uri contentUri = null;
-                if ("image".equals(type)) {
-                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-                } else if ("video".equals(type)) {
-                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
-                } else if ("audio".equals(type)) {
-                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
-                }
-
-                final String selection = "_id=?";
-                final String[] selectionArgs = new String[] { split[1] };
-
-                return UriUtils.getDataColumn(getApplicationContext(), contentUri, selection, selectionArgs);
-            }
-            // Documents providers returned as content://...
-            else if (UriUtils.isContentDocument(uri)) {
-                return uri.toString();
-            }
-        }
-        // MediaStore (and general)
-        else if ("content".equalsIgnoreCase(uri.getScheme())) {
-
-            // Return the remote address
-            if (UriUtils.isGooglePhotosUri(uri))
-                return uri.getLastPathSegment();
-
-            return UriUtils.getDataColumn(getApplicationContext(), uri, null, null);
-        }
-        // File
-        else if ("file".equalsIgnoreCase(uri.getScheme())) {
-            return uri.getPath();
-        }
-        return null;
-    }
-
-    /**
-     * Pushes a directory to the drop down list
-     * @param directory to push
-     * @throws IllegalArgumentException If the {@link OCFile#isFolder()} returns false.
-     */
-    public void pushDirname(OCFile directory) {
-        if(!directory.isFolder()){
-            throw new IllegalArgumentException("Only directories may be pushed!");
-        }
-        mDirectories.insert(directory.getFileName(), 0);
-        setFile(directory);
-    }
-
-    /**
-     * Pops a directory name from the drop down list
-     * @return True, unless the stack is empty
-     */
-    public boolean popDirname() {
-        mDirectories.remove(mDirectories.getItem(0));
-        return !mDirectories.isEmpty();
+        super.onPause();
+        Log_OC.v(TAG, "onPause() end");
     }
 
-    // Custom array adapter to override text colors
-    private class CustomArrayAdapter<T> extends ArrayAdapter<T> {
-
-        public CustomArrayAdapter(FileDisplayActivity ctx, int view) {
-            super(ctx, view);
-        }
-
-        public View getView(int position, View convertView, ViewGroup parent) {
-            View v = super.getView(position, convertView, parent);
-
-            ((TextView) v).setTextColor(getResources().getColorStateList(
-                    android.R.color.white));
-            
-            fixRoot((TextView) v );
-            return v;
-        }
-
-        public View getDropDownView(int position, View convertView,
-                ViewGroup parent) {
-            View v = super.getDropDownView(position, convertView, parent);
-
-            ((TextView) v).setTextColor(getResources().getColorStateList(
-                    android.R.color.white));
-
-            fixRoot((TextView) v );
-            return v;
-        }
-
-        private void fixRoot(TextView v) {
-            if (v.getText().equals(OCFile.PATH_SEPARATOR)) {
-                v.setText(R.string.default_display_name_for_root_folder);
-            }
-        }
-
-    }
 
     private class SyncBroadcastReceiver extends BroadcastReceiver {
 
@@ -1060,53 +890,70 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                 String event = intent.getAction();
                 Log_OC.d(TAG, "Received broadcast " + event);
                 String accountName = intent.getStringExtra(FileSyncAdapter.EXTRA_ACCOUNT_NAME);
-                String synchFolderRemotePath = intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH); 
-                RemoteOperationResult synchResult = (RemoteOperationResult)intent.getSerializableExtra(FileSyncAdapter.EXTRA_RESULT);
-                boolean sameAccount = (getAccount() != null && accountName.equals(getAccount().name) && getStorageManager() != null); 
-    
+                String synchFolderRemotePath =
+                        intent.getStringExtra(FileSyncAdapter.EXTRA_FOLDER_PATH);
+                RemoteOperationResult synchResult =
+                        (RemoteOperationResult)intent.getSerializableExtra(
+                                FileSyncAdapter.EXTRA_RESULT);
+                boolean sameAccount = (getAccount() != null &&
+                        accountName.equals(getAccount().name) && getStorageManager() != null);
+
                 if (sameAccount) {
-                    
+
                     if (FileSyncAdapter.EVENT_FULL_SYNC_START.equals(event)) {
                         mSyncInProgress = true;
-                        
+
                     } else {
-                        OCFile currentFile = (getFile() == null) ? null : getStorageManager().getFileByPath(getFile().getRemotePath());
-                        OCFile currentDir = (getCurrentDir() == null) ? null : getStorageManager().getFileByPath(getCurrentDir().getRemotePath());
+                        OCFile currentFile = (getFile() == null) ? null :
+                                getStorageManager().getFileByPath(getFile().getRemotePath());
+                        OCFile currentDir = (getCurrentDir() == null) ? null :
+                                getStorageManager().getFileByPath(getCurrentDir().getRemotePath());
     
                         if (currentDir == null) {
                             // current folder was removed from the server 
                             Toast.makeText( FileDisplayActivity.this, 
-                                            String.format(getString(R.string.sync_current_folder_was_removed), mDirectories.getItem(0)), 
+                                            String.format(
+                                                    getString(R.string.
+                                                            sync_current_folder_was_removed),
+                                                   synchFolderRemotePath),
                                             Toast.LENGTH_LONG)
                                 .show();
+
                             browseToRoot();
-                            
+
                         } else {
                             if (currentFile == null && !getFile().isFolder()) {
-                                // currently selected file was removed in the server, and now we know it
+                                // currently selected file was removed in the server, and now we
+                                // know it
                                 cleanSecondFragment();
                                 currentFile = currentDir;
                             }
 
-                            if (synchFolderRemotePath != null && currentDir.getRemotePath().equals(synchFolderRemotePath)) {
+                            if (synchFolderRemotePath != null &&
+                                    currentDir.getRemotePath().equals(synchFolderRemotePath)) {
                                 OCFileListFragment fileListFragment = getListOfFilesFragment();
                                 if (fileListFragment != null) {
-                                    fileListFragment.listDirectory(currentDir);
+                                    fileListFragment.listDirectory();
+                                    // TODO Enable when "On Device" is recovered ?
+                                    // fileListFragment.listDirectory(currentDir,
+                                    // MainApp.getOnlyOnDevice());
                                 }
                             }
                             setFile(currentFile);
                         }
-                        
-                        mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) && !RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED.equals(event));
+
+                        mSyncInProgress = (!FileSyncAdapter.EVENT_FULL_SYNC_END.equals(event) &&
+                                !RefreshFolderOperation.EVENT_SINGLE_FOLDER_SHARES_SYNCED
+                                        .equals(event));
                                 
                         if (RefreshFolderOperation.EVENT_SINGLE_FOLDER_CONTENTS_SYNCED.
-                                    equals(event) &&
-                                /// TODO refactor and make common
-                                synchResult != null && !synchResult.isSuccess() &&  
-                                (synchResult.getCode() == ResultCode.UNAUTHORIZED   || 
-                                    synchResult.isIdPRedirection()                  ||
-                                    (synchResult.isException() && synchResult.getException() 
-                                            instanceof AuthenticatorException))) {
+                                    equals(event) &&/// TODO refactor and make common
+
+                                synchResult != null && !synchResult.isSuccess() &&
+                                (synchResult.getCode() == ResultCode.UNAUTHORIZED ||
+                                        synchResult.isIdPRedirection() ||
+                                        (synchResult.isException() && synchResult.getException()
+                                                instanceof AuthenticatorException))) {
 
 
                             try {
@@ -1115,7 +962,6 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                                         new OwnCloudAccount(getAccount(), context);
                                 client = (OwnCloudClientManagerFactory.getDefaultSingleton().
                                         removeClientFor(ocAccount));
-
                                 if (client != null) {
                                     OwnCloudCredentials cred = client.getCredentials();
                                     if (cred != null) {
@@ -1140,14 +986,18 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                     }
                     removeStickyBroadcast(intent);
                     Log_OC.d(TAG, "Setting progress visibility to " + mSyncInProgress);
-                    setSupportProgressBarIndeterminateVisibility(mSyncInProgress /*|| mRefreshSharesInProgress*/);
+                    mProgressBar.setIndeterminate(mSyncInProgress);
+                    //mProgressBar.setVisibility((mSyncInProgress) ? View.VISIBLE : View.INVISIBLE);
+                    //setSupportProgressBarIndeterminateVisibility(mSyncInProgress
+                    /*|| mRefreshSharesInProgress*/ //);
 
                     setBackgroundText();
-                        
+
                 }
-                
+
                 if (synchResult != null) {
-                    if (synchResult.getCode().equals(RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) {
+                    if (synchResult.getCode().equals(
+                            RemoteOperationResult.ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED)) {
                         mLastSslUntrustedServerResult = synchResult;
                     }
                 }
@@ -1158,7 +1008,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             }
         }
     }
-    
+
     /**
      * Show a text message on screen view for notifying user if content is
      * loading or folder is empty
@@ -1183,7 +1033,8 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     private class UploadFinishReceiver extends BroadcastReceiver {
         /**
          * Once the file upload has finished -> update view
-         *  @author David A. Velasco
+         *
+         * @author David A. Velasco
          * {@link BroadcastReceiver} to enable upload feedback in UI
          */
         @Override
@@ -1193,22 +1044,23 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                 String accountName = intent.getStringExtra(FileUploader.ACCOUNT_NAME);
                 boolean sameAccount = getAccount() != null && accountName.equals(getAccount().name);
                 OCFile currentDir = getCurrentDir();
-                boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) && 
+                boolean isDescendant = (currentDir != null) && (uploadedRemotePath != null) &&
                         (uploadedRemotePath.startsWith(currentDir.getRemotePath()));
-                
+
                 if (sameAccount && isDescendant) {
                     refreshListOfFilesFragment();
                 }
-                
-                boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false);
+
+                boolean uploadWasFine = intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT,
+                        false);
                 boolean renamedInUpload = getFile().getRemotePath().
                         equals(intent.getStringExtra(FileUploader.EXTRA_OLD_REMOTE_PATH));
-                boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) || 
+                boolean sameFile = getFile().getRemotePath().equals(uploadedRemotePath) ||
                         renamedInUpload;
                 FileFragment details = getSecondFragment();
-                boolean detailFragmentIsShown = (details != null && 
+                boolean detailFragmentIsShown = (details != null &&
                         details instanceof FileDetailFragment);
-                
+
                 if (sameAccount && sameFile && detailFragmentIsShown) {
                     if (uploadWasFine) {
                         setFile(getStorageManager().getFileByPath(uploadedRemotePath));
@@ -1216,39 +1068,45 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                     if (renamedInUpload) {
                         String newName = (new File(uploadedRemotePath)).getName();
                         Toast msg = Toast.makeText(
-                                context, 
+                                context,
                                 String.format(
-                                        getString(R.string.filedetails_renamed_in_upload_msg), 
-                                        newName), 
+                                        getString(R.string.filedetails_renamed_in_upload_msg),
+                                        newName),
                                 Toast.LENGTH_LONG);
                         msg.show();
                     }
                     if (uploadWasFine || getFile().fileExists()) {
-                        ((FileDetailFragment)details).updateFileDetails(false, true);
+                        ((FileDetailFragment) details).updateFileDetails(false, true);
                     } else {
                         cleanSecondFragment();
                     }
-                    
-                    // Force the preview if the file is an image
-                    if (uploadWasFine && PreviewImageFragment.canBePreviewed(getFile())) {
-                        startImagePreview(getFile());
-                    } // TODO what about other kind of previews?
+
+                    // Force the preview if the file is an image or text file
+                    if (uploadWasFine) {
+                        OCFile ocFile = getFile();
+                        if (PreviewImageFragment.canBePreviewed(ocFile))
+                            startImagePreview(getFile());
+                        else if (PreviewTextFragment.canBePreviewed(ocFile))
+                            startTextPreview(ocFile);
+                        // TODO what about other kind of previews?
+                    }
                 }
-                
+
+                mProgressBar.setIndeterminate(false);
             } finally {
                 if (intent != null) {
                     removeStickyBroadcast(intent);
                 }
             }
-            
+
         }
-        
+
     }
 
 
     /**
      * Class waiting for broadcast events from the {@link FileDownloader} service.
-     * 
+     *
      * Updates the UI when a download is started or finished, provided that it is relevant for the
      * current folder.
      */
@@ -1259,11 +1117,13 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         public void onReceive(Context context, Intent intent) {
             try {
                 boolean sameAccount = isSameAccount(context, intent);
-                String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
+                String downloadedRemotePath =
+                        intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
                 boolean isDescendant = isDescendant(downloadedRemotePath);
 
                 if (sameAccount && isDescendant) {
-                    String linkedToRemotePath = intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
+                    String linkedToRemotePath =
+                            intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
                     if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
                         //Log_OC.v(TAG, "refresh #" + ++refreshCounter);
                         refreshListOfFilesFragment();
@@ -1274,14 +1134,15 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
                             intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false)
                     );
                 }
-    
+
                 if (mWaitingToSend != null) {
-                    mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
-                    if (mWaitingToSend.isDown()) { 
+                    mWaitingToSend =
+                            getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
+                    if (mWaitingToSend.isDown()) {
                         sendDownloadedFile();
                     }
                 }
-            
+
             } finally {
                 if (intent != null) {
                     removeStickyBroadcast(intent);
@@ -1308,148 +1169,110 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
         private boolean isSameAccount(Context context, Intent intent) {
             String accountName = intent.getStringExtra(FileDownloader.ACCOUNT_NAME);
-            return (accountName != null && getAccount() != null && accountName.equals(getAccount().name));
+            return (accountName != null && getAccount() != null &&
+                    accountName.equals(getAccount().name));
         }
     }
-    
-    
+
+
     public void browseToRoot() {
-        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
+        OCFileListFragment listOfFiles = getListOfFilesFragment();
         if (listOfFiles != null) {  // should never be null, indeed
-            while (mDirectories.getCount() > 1) {
-                popDirname();
-            }
             OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
             listOfFiles.listDirectory(root);
+            // TODO Enable when "On Device" is recovered ?
+            // listOfFiles.listDirectory(root, MainApp.getOnlyOnDevice());
             setFile(listOfFiles.getCurrentFile());
             startSyncFolderOperation(root, false);
         }
         cleanSecondFragment();
     }
-    
-    
-    public void browseTo(OCFile folder) {
-        if (folder == null || !folder.isFolder()) {
-            throw new IllegalArgumentException("Trying to browse to invalid folder " + folder);
-        }
-        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
-        if (listOfFiles != null) {
-            setNavigationListWithFolder(folder);
-            listOfFiles.listDirectory(folder);
-            setFile(listOfFiles.getCurrentFile());
-            startSyncFolderOperation(folder, false);
-        } else {
-            Log_OC.e(TAG, "Unexpected null when accessing list fragment");
-        }
-        cleanSecondFragment();
-    }
 
 
     /**
      * {@inheritDoc}
-     * 
+     * <p/>
      * Updates action bar and second fragment, if in dual pane mode.
      */
     @Override
     public void onBrowsedDownTo(OCFile directory) {
-        pushDirname(directory);
+        setFile(directory);
         cleanSecondFragment();
-        
         // Sync Folder
         startSyncFolderOperation(directory, false);
-        
     }
 
     /**
-     * Shows the information of the {@link OCFile} received as a 
+     * Shows the information of the {@link OCFile} received as a
      * parameter in the second fragment.
-     * 
-     * @param file          {@link OCFile} whose details will be shown
+     *
+     * @param file {@link OCFile} whose details will be shown
      */
     @Override
     public void showDetails(OCFile file) {
-        Fragment detailFragment = new FileDetailFragment(file, getAccount());
+        Fragment detailFragment = FileDetailFragment.newInstance(file, getAccount());
         setSecondFragment(detailFragment);
         updateFragmentsVisibility(true);
-        updateNavigationElementsInActionBar(file);
+        updateActionBarTitleAndHomeButton(file);
         setFile(file);
     }
 
-
-    /**
-     * TODO
-     */
-    private void updateNavigationElementsInActionBar(OCFile chosenFile) {
-        ActionBar actionBar = getSupportActionBar();
-
-        // For adding content description tag to a title field in the action bar
-        int actionBarTitleId = getResources().getIdentifier("action_bar_title", "id", "android");
-
-        if (chosenFile == null || mDualPane) {
-            // only list of files - set for browsing through folders
-            OCFile currentDir = getCurrentDir();
-            boolean noRoot = (currentDir != null && currentDir.getParentId() != 0);
-            actionBar.setDisplayHomeAsUpEnabled(noRoot);
-            actionBar.setDisplayShowTitleEnabled(!noRoot); 
-            if (!noRoot) {
-                actionBar.setTitle(getString(R.string.default_display_name_for_root_folder));
-                View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
-                if (actionBarTitleView != null) {    // it's null in Android 2.x
-                    actionBarTitleView.setContentDescription(getString(R.string.default_display_name_for_root_folder));
-                }
-            }
-            actionBar.setNavigationMode(!noRoot ? ActionBar.NAVIGATION_MODE_STANDARD : ActionBar.NAVIGATION_MODE_LIST);
-            actionBar.setListNavigationCallbacks(mDirectories, this);   // assuming mDirectories is updated
+    @Override
+    protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) {
+        if (mDualPane) {
+            // in dual pane mode, keep the focus of title an action bar in the current folder
+            super.updateActionBarTitleAndHomeButton(getCurrentDir());
 
         } else {
-            actionBar.setDisplayHomeAsUpEnabled(true);
-            actionBar.setDisplayShowTitleEnabled(true);
-            actionBar.setTitle(chosenFile.getFileName());
-            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-            View actionBarTitleView = getWindow().getDecorView().findViewById(actionBarTitleId);
-            if (actionBarTitleView != null) {    // it's null in Android 2.x
-                getWindow().getDecorView().findViewById(actionBarTitleId).
-                        setContentDescription(chosenFile.getFileName());
-            }
+            super.updateActionBarTitleAndHomeButton(chosenFile);
         }
-    }
 
+    }
 
     @Override
     protected ServiceConnection newTransferenceServiceConnection() {
         return new ListServiceConnection();
     }
 
-    /** Defines callbacks for service binding, passed to bindService() */
+    /**
+     * Defines callbacks for service binding, passed to bindService()
+     */
     private class ListServiceConnection implements ServiceConnection {
 
         @Override
         public void onServiceConnected(ComponentName component, IBinder service) {
-            if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
+            if (component.equals(new ComponentName(
+                    FileDisplayActivity.this, FileDownloader.class))) {
                 Log_OC.d(TAG, "Download service connected");
                 mDownloaderBinder = (FileDownloaderBinder) service;
                 if (mWaitingToPreview != null)
                     if (getStorageManager() != null) {
-                        mWaitingToPreview = getStorageManager().getFileById(mWaitingToPreview.getFileId()); // update the file
+                         // update the file
+                        mWaitingToPreview =
+                                getStorageManager().getFileById(mWaitingToPreview.getFileId());
                         if (!mWaitingToPreview.isDown()) {
                             requestForDownload();
                         }
-                }
+                    }
 
-            } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
+            } else if (component.equals(new ComponentName(FileDisplayActivity.this,
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service connected");
                 mUploaderBinder = (FileUploaderBinder) service;
             } else {
                 return;
             }
-            // a new chance to get the mDownloadBinder through getFileDownloadBinder() - THIS IS A MESS
-            OCFileListFragment listOfFiles = getListOfFilesFragment(); 
+            // a new chance to get the mDownloadBinder through
+            // getFileDownloadBinder() - THIS IS A MESS
+            OCFileListFragment listOfFiles = getListOfFilesFragment();
             if (listOfFiles != null) {
                 listOfFiles.listDirectory();
+                // TODO Enable when "On Device" is recovered ?
+                // listOfFiles.listDirectory(MainApp.getOnlyOnDevice());
             }
             FileFragment secondFragment = getSecondFragment();
             if (secondFragment != null && secondFragment instanceof FileDetailFragment) {
-                FileDetailFragment detailFragment = (FileDetailFragment)secondFragment;
+                FileDetailFragment detailFragment = (FileDetailFragment) secondFragment;
                 detailFragment.listenForTransferProgress();
                 detailFragment.updateFileDetails(false, false);
             }
@@ -1457,33 +1280,18 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
         @Override
         public void onServiceDisconnected(ComponentName component) {
-            if (component.equals(new ComponentName(FileDisplayActivity.this, FileDownloader.class))) {
+            if (component.equals(new ComponentName(FileDisplayActivity.this,
+                    FileDownloader.class))) {
                 Log_OC.d(TAG, "Download service disconnected");
                 mDownloaderBinder = null;
-            } else if (component.equals(new ComponentName(FileDisplayActivity.this, FileUploader.class))) {
+            } else if (component.equals(new ComponentName(FileDisplayActivity.this,
+                    FileUploader.class))) {
                 Log_OC.d(TAG, "Upload service disconnected");
                 mUploaderBinder = null;
             }
         }
-    };    
-
-
-
-    /**
-     * Launch an intent to request the PIN code to the user before letting him use the app
-     */
-    private void requestPinCode() {
-        boolean pinStart = false;
-        SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
-        pinStart = appPrefs.getBoolean("set_pincode", false);
-        if (pinStart) {
-            Intent i = new Intent(getApplicationContext(), PinCodeActivity.class);
-            i.putExtra(PinCodeActivity.EXTRA_ACTIVITY, "FileDisplayActivity");
-            startActivity(i);
-        }
     }
 
-
     @Override
     public void onSavedCertificate() {
         startSyncFolderOperation(getCurrentDir(), false);
@@ -1492,7 +1300,10 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
     @Override
     public void onFailedSavingCertificate() {
-        showDialog(DIALOG_CERT_NOT_SAVED);
+        ConfirmationDialogFragment dialog = ConfirmationDialogFragment.newInstance(
+                R.string.ssl_validator_not_saved, new String[]{}, R.string.common_ok, -1, -1
+        );
+        dialog.show(getSupportFragmentManager(), DIALOG_CERT_NOT_SAVED);
     }
 
     @Override
@@ -1503,100 +1314,107 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     /**
      * Updates the view associated to the activity after the finish of some operation over files
      * in the current account.
-     * 
-     * @param operation     Removal operation performed.
-     * @param result        Result of the removal.
+     *
+     * @param operation Removal operation performed.
+     * @param result    Result of the removal.
      */
     @Override
     public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
         super.onRemoteOperationFinish(operation, result);
-        
+
         if (operation instanceof RemoveFileOperation) {
-            onRemoveFileOperationFinish((RemoveFileOperation)operation, result);
+            onRemoveFileOperationFinish((RemoveFileOperation) operation, result);
 
         } else if (operation instanceof RenameFileOperation) {
-            onRenameFileOperationFinish((RenameFileOperation)operation, result);
+            onRenameFileOperationFinish((RenameFileOperation) operation, result);
 
         } else if (operation instanceof SynchronizeFileOperation) {
-            onSynchronizeFileOperationFinish((SynchronizeFileOperation)operation, result);
+            onSynchronizeFileOperationFinish((SynchronizeFileOperation) operation, result);
 
         } else if (operation instanceof CreateFolderOperation) {
-            onCreateFolderOperationFinish((CreateFolderOperation)operation, result);
-            
+            onCreateFolderOperationFinish((CreateFolderOperation) operation, result);
+
         } else if (operation instanceof CreateShareOperation) {
             onCreateShareOperationFinish((CreateShareOperation) operation, result);
-            
+
         } else if (operation instanceof UnshareLinkOperation) {
-            onUnshareLinkOperationFinish((UnshareLinkOperation)operation, result);
-        
+            onUnshareLinkOperationFinish((UnshareLinkOperation) operation, result);
+
         } else if (operation instanceof MoveFileOperation) {
-            onMoveFileOperationFinish((MoveFileOperation)operation, result);
+            onMoveFileOperationFinish((MoveFileOperation) operation, result);
+
+        } else if (operation instanceof CopyFileOperation) {
+            onCopyFileOperationFinish((CopyFileOperation) operation, result);
         }
-        
-    }
 
-    
-    private void onCreateShareOperationFinish(CreateShareOperation operation, RemoteOperationResult result) {
+    }
+    private void onCreateShareOperationFinish(CreateShareOperation operation,
+                                              RemoteOperationResult result) {
         if (result.isSuccess()) {
             refreshShowDetails();
             refreshListOfFilesFragment();
         }
     }
 
-    
-    private void onUnshareLinkOperationFinish(UnshareLinkOperation operation, RemoteOperationResult result) {
+    private void onUnshareLinkOperationFinish(UnshareLinkOperation operation,
+                                              RemoteOperationResult result) {
         if (result.isSuccess()) {
             refreshShowDetails();
             refreshListOfFilesFragment();
-            
+
         } else if (result.getCode() == ResultCode.SHARE_NOT_FOUND) {
             cleanSecondFragment();
             refreshListOfFilesFragment();
         }
     }
-    
+
     private void refreshShowDetails() {
         FileFragment details = getSecondFragment();
         if (details != null) {
             OCFile file = details.getFile();
             if (file != null) {
-                file = getStorageManager().getFileByPath(file.getRemotePath()); 
+                file = getStorageManager().getFileByPath(file.getRemotePath());
                 if (details instanceof PreviewMediaFragment) {
                     // Refresh  OCFile of the fragment
                     ((PreviewMediaFragment) details).updateFile(file);
+                } else if (details instanceof PreviewTextFragment) {
+                    // Refresh  OCFile of the fragment
+                    ((PreviewTextFragment) details).updateFile(file);
                 } else {
                     showDetails(file);
-                } 
+                }
             }
             invalidateOptionsMenu();
-        } 
+        }
     }
-    
+
     /**
-     * Updates the view associated to the activity after the finish of an operation trying to remove a 
-     * file. 
+     * Updates the view associated to the activity after the finish of an operation trying to
+     * remove a file.
      * 
      * @param operation     Removal operation performed.
      * @param result        Result of the removal.
      */
-    private void onRemoveFileOperationFinish(RemoveFileOperation operation, RemoteOperationResult result) {
+    private void onRemoveFileOperationFinish(RemoveFileOperation operation,
+                                             RemoteOperationResult result) {
         dismissLoadingDialog();
-        
-        Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                Toast.LENGTH_LONG); 
+
+        Toast msg = Toast.makeText(this,
+                ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+                Toast.LENGTH_LONG);
         msg.show();
-        
+
         if (result.isSuccess()) {
             OCFile removedFile = operation.getFile();
             FileFragment second = getSecondFragment();
             if (second != null && removedFile.equals(second.getFile())) {
                 if (second instanceof PreviewMediaFragment) {
-                    ((PreviewMediaFragment)second).stopPreview(true);
+                    ((PreviewMediaFragment) second).stopPreview(true);
                 }
                 setFile(getStorageManager().getFileById(removedFile.getParentId()));
                 cleanSecondFragment();
             }
-            if (getStorageManager().getFileById(removedFile.getParentId()).equals(getCurrentDir())) {
+            if (getStorageManager().getFileById(removedFile.getParentId()).equals(getCurrentDir())){
                 refreshListOfFilesFragment();
             }
             invalidateOptionsMenu();
@@ -1607,71 +1425,108 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             }
         }
     }
-    
-    
+
+
     /**
-     * Updates the view associated to the activity after the finish of an operation trying to move a 
+     * Updates the view associated to the activity after the finish of an operation trying to move a
      * file.
-     * 
-     * @param operation     Move operation performed.
-     * @param result        Result of the move operation.
+     *
+     * @param operation Move operation performed.
+     * @param result    Result of the move operation.
      */
-    private void onMoveFileOperationFinish(MoveFileOperation operation, RemoteOperationResult result) {
+    private void onMoveFileOperationFinish(MoveFileOperation operation,
+                                           RemoteOperationResult result) {
         if (result.isSuccess()) {
             dismissLoadingDialog();
             refreshListOfFilesFragment();
         } else {
             dismissLoadingDialog();
             try {
-                Toast msg = Toast.makeText(FileDisplayActivity.this, 
-                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                        Toast.LENGTH_LONG); 
+                Toast msg = Toast.makeText(FileDisplayActivity.this,
+                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+                        Toast.LENGTH_LONG);
                 msg.show();
 
             } catch (NotFoundException e) {
-                Log_OC.e(TAG, "Error while trying to show fail message " , e);
+                Log_OC.e(TAG, "Error while trying to show fail message ", e);
             }
         }
     }
 
+    /**
+     * Updates the view associated to the activity after the finish of an operation trying to copy a
+     * file.
+     *
+     * @param operation Copy operation performed.
+     * @param result    Result of the copy operation.
+     */
+    private void onCopyFileOperationFinish(CopyFileOperation operation, RemoteOperationResult result) {
+        if (result.isSuccess()) {
+            dismissLoadingDialog();
+            refreshListOfFilesFragment();
+        } else {
+            dismissLoadingDialog();
+            try {
+                Toast msg = Toast.makeText(FileDisplayActivity.this,
+                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+                        Toast.LENGTH_LONG);
+                msg.show();
+
+            } catch (NotFoundException e) {
+                Log_OC.e(TAG, "Error while trying to show fail message ", e);
+            }
+        }
+    }
 
     /**
-     * Updates the view associated to the activity after the finish of an operation trying to rename a 
-     * file. 
+     * Updates the view associated to the activity after the finish of an operation trying to rename
+     * a file.
      * 
      * @param operation     Renaming operation performed.
      * @param result        Result of the renaming.
      */
-    private void onRenameFileOperationFinish(RenameFileOperation operation, RemoteOperationResult result) {
+    private void onRenameFileOperationFinish(RenameFileOperation operation,
+                                             RemoteOperationResult result) {
         dismissLoadingDialog();
         OCFile renamedFile = operation.getFile();
         if (result.isSuccess()) {
             FileFragment details = getSecondFragment();
             if (details != null) {
-                if (details instanceof FileDetailFragment && renamedFile.equals(details.getFile()) ) {
+                if (details instanceof FileDetailFragment &&
+                        renamedFile.equals(details.getFile()) ) {
                     ((FileDetailFragment) details).updateFileDetails(renamedFile, getAccount());
                     showDetails(renamedFile);
 
-                } else if (details instanceof PreviewMediaFragment && renamedFile.equals(details.getFile())) {
+                } else if (details instanceof PreviewMediaFragment &&
+                        renamedFile.equals(details.getFile())) {
                     ((PreviewMediaFragment) details).updateFile(renamedFile);
                     if (PreviewMediaFragment.canBePreviewed(renamedFile)) {
-                        int position = ((PreviewMediaFragment)details).getPosition();
+                        int position = ((PreviewMediaFragment) details).getPosition();
                         startMediaPreview(renamedFile, position, true);
                     } else {
                         getFileOperationsHelper().openFile(renamedFile);
                     }
+                } else if (details instanceof PreviewTextFragment &&
+                        renamedFile.equals(details.getFile())) {
+                    ((PreviewTextFragment) details).updateFile(renamedFile);
+                    if (PreviewTextFragment.canBePreviewed(renamedFile)) {
+                        startTextPreview(renamedFile);
+                    } else {
+                        getFileOperationsHelper().openFile(renamedFile);
+                    }
                 }
             }
-            
-            if (getStorageManager().getFileById(renamedFile.getParentId()).equals(getCurrentDir())) {
+
+            if (getStorageManager().getFileById(renamedFile.getParentId()).equals(getCurrentDir())){
                 refreshListOfFilesFragment();
             }
 
         } else {
-            Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                    Toast.LENGTH_LONG); 
+            Toast msg = Toast.makeText(this,
+                    ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+                    Toast.LENGTH_LONG);
             msg.show();
-            
+
             if (result.isSslRecoverableException()) {
                 mLastSslUntrustedServerResult = result;
                 showUntrustedCertDialog(mLastSslUntrustedServerResult);
@@ -1679,55 +1534,44 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         }
     }
 
-    private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation, RemoteOperationResult result) {
-        dismissLoadingDialog();
-        OCFile syncedFile = operation.getLocalFile();
-        if (!result.isSuccess()) {
-            if (result.getCode() == ResultCode.SYNC_CONFLICT) {
-                Intent i = new Intent(this, ConflictsResolveActivity.class);
-                i.putExtra(ConflictsResolveActivity.EXTRA_FILE, syncedFile);
-                i.putExtra(ConflictsResolveActivity.EXTRA_ACCOUNT, getAccount());
-                startActivity(i);
-
-            } 
-            
-        } else {
+    private void onSynchronizeFileOperationFinish(SynchronizeFileOperation operation,
+                                                  RemoteOperationResult result) {
+        if (result.isSuccess()) {
             if (operation.transferWasRequested()) {
+                OCFile syncedFile = operation.getLocalFile();
                 onTransferStateChanged(syncedFile, true, true);
-                
-            } else {
-                Toast msg = Toast.makeText(this, ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                        Toast.LENGTH_LONG); 
-                msg.show();
+                invalidateOptionsMenu();
             }
         }
     }
 
     /**
-     * Updates the view associated to the activity after the finish of an operation trying create a new folder
+     * Updates the view associated to the activity after the finish of an operation trying create a
+     * new folder
      * 
      * @param operation     Creation operation performed.
      * @param result        Result of the creation.
      */
-    private void onCreateFolderOperationFinish(CreateFolderOperation operation, RemoteOperationResult result) {
+    private void onCreateFolderOperationFinish(CreateFolderOperation operation,
+                                               RemoteOperationResult result) {
         if (result.isSuccess()) {
             dismissLoadingDialog();
             refreshListOfFilesFragment();
         } else {
             dismissLoadingDialog();
             try {
-                Toast msg = Toast.makeText(FileDisplayActivity.this, 
-                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()), 
-                        Toast.LENGTH_LONG); 
+                Toast msg = Toast.makeText(FileDisplayActivity.this,
+                        ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
+                        Toast.LENGTH_LONG);
                 msg.show();
 
             } catch (NotFoundException e) {
-                Log_OC.e(TAG, "Error while trying to show fail message " , e);
+                Log_OC.e(TAG, "Error while trying to show fail message ", e);
             }
         }
     }
 
-    
+
     /**
      * {@inheritDoc}
      */
@@ -1735,18 +1579,19 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
     public void onTransferStateChanged(OCFile file, boolean downloading, boolean uploading) {
         refreshListOfFilesFragment();
         FileFragment details = getSecondFragment();
-        if (details != null && details instanceof FileDetailFragment && file.equals(details.getFile()) ) {
+        if (details != null && details instanceof FileDetailFragment &&
+                file.equals(details.getFile()) ) {
             if (downloading || uploading) {
-                ((FileDetailFragment)details).updateFileDetails(file, getAccount());
+                ((FileDetailFragment) details).updateFileDetails(file, getAccount());
             } else {
                 if (!file.fileExists()) {
                     cleanSecondFragment();
                 } else {
-                    ((FileDetailFragment)details).updateFileDetails(false, true);
+                    ((FileDetailFragment) details).updateFileDetails(false, true);
                 }
             }
         }
-            
+
     }
 
 
@@ -1775,41 +1620,41 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         }
         return null;
     }
-    
+
     public void startSyncFolderOperation(OCFile folder, boolean ignoreETag) {
-        long currentSyncTime = System.currentTimeMillis(); 
-        
+        long currentSyncTime = System.currentTimeMillis();
+
         mSyncInProgress = true;
-                
+
         // perform folder synchronization
         RemoteOperation synchFolderOp = new RefreshFolderOperation( folder,
-                                                                        currentSyncTime, 
-                                                                        false,
-                                                                        getFileOperationsHelper().isSharedSupported(),
-                                                                        ignoreETag,
-                                                                        getStorageManager(), 
-                                                                        getAccount(), 
-                                                                        getApplicationContext()
-                                                                      );
+                currentSyncTime,
+                false,
+                getFileOperationsHelper().isSharedSupported(),
+                ignoreETag,
+                getStorageManager(),
+                getAccount(),
+                getApplicationContext()
+        );
         synchFolderOp.execute(getAccount(), MainApp.getAppContext(), this, null, null);
-        
-        setSupportProgressBarIndeterminateVisibility(true);
+
+        mProgressBar.setIndeterminate(true);
 
         setBackgroundText();
     }
 
     /**
-     * Show untrusted cert dialog 
+     * Show untrusted cert dialog
      */
     public void showUntrustedCertDialog(RemoteOperationResult result) {
         // Show a dialog with the certificate info
         SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError(
-                (CertificateCombinedException)result.getException());
+                (CertificateCombinedException) result.getException());
         FragmentManager fm = getSupportFragmentManager();
         FragmentTransaction ft = fm.beginTransaction();
         dialog.show(ft, DIALOG_UNTRUSTED_CERT);
     }
-    
+
     private void requestForDownload(OCFile file) {
         Account account = getAccount();
         if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
@@ -1819,52 +1664,71 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
             startService(i);
         }
     }
-    
-    private void sendDownloadedFile(){
+
+    private void sendDownloadedFile() {
         getFileOperationsHelper().sendDownloadedFile(mWaitingToSend);
         mWaitingToSend = null;
     }
 
-    
+
     /**
      * Requests the download of the received {@link OCFile} , updates the UI
      * to monitor the download progress and prepares the activity to send the file
      * when the download finishes.
-     * 
-     * @param file          {@link OCFile} to download and preview.
+     *
+     * @param file {@link OCFile} to download and preview.
      */
     public void startDownloadForSending(OCFile file) {
         mWaitingToSend = file;
         requestForDownload(mWaitingToSend);
-        boolean hasSecondFragment = (getSecondFragment()!= null);
+        boolean hasSecondFragment = (getSecondFragment() != null);
         updateFragmentsVisibility(hasSecondFragment);
     }
-    
+
     /**
      * Opens the image gallery showing the image {@link OCFile} received as parameter.
-     * 
-     * @param file                      Image {@link OCFile} to show.
+     *
+     * @param file Image {@link OCFile} to show.
      */
     public void startImagePreview(OCFile file) {
         Intent showDetailsIntent = new Intent(this, PreviewImageActivity.class);
         showDetailsIntent.putExtra(EXTRA_FILE, file);
         showDetailsIntent.putExtra(EXTRA_ACCOUNT, getAccount());
         startActivity(showDetailsIntent);
-        
     }
 
     /**
      * Stars the preview of an already down media {@link OCFile}.
-     * 
+     *
      * @param file                      Media {@link OCFile} to preview.
-     * @param startPlaybackPosition     Media position where the playback will be started, in milliseconds.
-     * @param autoplay                  When 'true', the playback will start without user interactions.
+     * @param startPlaybackPosition     Media position where the playback will be started,
+     *                                  in milliseconds.
+     * @param autoplay                  When 'true', the playback will start without user
+     *                                  interactions.
      */
     public void startMediaPreview(OCFile file, int startPlaybackPosition, boolean autoplay) {
-        Fragment mediaFragment = new PreviewMediaFragment(file, getAccount(), startPlaybackPosition, autoplay);
+        Fragment mediaFragment = new PreviewMediaFragment(file, getAccount(), startPlaybackPosition,
+                autoplay);
         setSecondFragment(mediaFragment);
         updateFragmentsVisibility(true);
-        updateNavigationElementsInActionBar(file);
+        updateActionBarTitleAndHomeButton(file);
+        setFile(file);
+    }
+
+    /**
+     * Stars the preview of a text file {@link OCFile}.
+     *
+     * @param file Text {@link OCFile} to preview.
+     */
+    public void startTextPreview(OCFile file) {
+        Bundle args = new Bundle();
+        args.putParcelable(EXTRA_FILE, file);
+        args.putParcelable(EXTRA_ACCOUNT, getAccount());
+        Fragment textPreviewFragment = Fragment.instantiate(getApplicationContext(),
+                PreviewTextFragment.class.getName(), args);
+        setSecondFragment(textPreviewFragment);
+        updateFragmentsVisibility(true);
+        //updateNavigationElementsInActionBar(file);
         setFile(file);
     }
 
@@ -1872,23 +1736,23 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
      * Requests the download of the received {@link OCFile} , updates the UI
      * to monitor the download progress and prepares the activity to preview
      * or open the file when the download finishes.
-     * 
-     * @param file          {@link OCFile} to download and preview.
+     *
+     * @param file {@link OCFile} to download and preview.
      */
     public void startDownloadForPreview(OCFile file) {
-        Fragment detailFragment = new FileDetailFragment(file, getAccount());
+        Fragment detailFragment = FileDetailFragment.newInstance(file, getAccount());
         setSecondFragment(detailFragment);
         mWaitingToPreview = file;
         requestForDownload();
         updateFragmentsVisibility(true);
-        updateNavigationElementsInActionBar(file);
+        updateActionBarTitleAndHomeButton(file);
         setFile(file);
     }
 
 
     public void cancelTransference(OCFile file) {
         getFileOperationsHelper().cancelTransference(file);
-        if (mWaitingToPreview != null && 
+        if (mWaitingToPreview != null &&
                 mWaitingToPreview.getRemotePath().equals(file.getRemotePath())) {
             mWaitingToPreview = null;
         }
@@ -1921,15 +1785,19 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
         }
     }
 
-    private void sortByDate(boolean ascending){
+    private void sortByDate(boolean ascending) {
         getListOfFilesFragment().sortByDate(ascending);
     }
 
-    private void sortBySize(boolean ascending){
+    private void sortBySize(boolean ascending) {
         getListOfFilesFragment().sortBySize(ascending);
     }
 
-    private void sortByName(boolean ascending){
+    private void sortByName(boolean ascending) {
         getListOfFilesFragment().sortByName(ascending);
     }
+
+   public void allFilesOption() {
+       browseToRoot();
+   }
 }