Merge remote-tracking branch 'origin/master' into text_file_preview_pr_707_with_develop
authormasensio <masensio@solidgear.es>
Wed, 2 Sep 2015 11:21:17 +0000 (13:21 +0200)
committermasensio <masensio@solidgear.es>
Wed, 2 Sep 2015 11:23:42 +0000 (13:23 +0200)
Conflicts:
res/layout/file_preview.xml
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

1  2 
res/layout/file_preview.xml
src/com/owncloud/android/datamodel/OCFile.java
src/com/owncloud/android/ui/activity/FileDisplayActivity.java
src/com/owncloud/android/ui/fragment/OCFileListFragment.java

@@@ -1,4 -1,5 +1,5 @@@
- <?xml version="1.0" encoding="utf-8"?><!--
+ <?xml version="1.0" encoding="utf-8"?>
+ <!--
    ownCloud Android client application
  
    Copyright (C) 2015 ownCloud Inc.
      android:layout_height="match_parent"
      android:background="@color/background_color"
      android:gravity="center"
 -    tools:context=".ui.fragment.FilePreviewFragment" >
 +    tools:context=".ui.fragment.FilePreviewFragment">
  
 -    <FrameLayout 
 +    <FrameLayout
          android:id="@+id/visual_area"
-         android:layout_width="match_parent"
-         android:layout_height="0dp"
-         android:layout_alignParentTop="true"
-         android:layout_above="@+id/media_controller">
-         <ImageView
-             android:id="@+id/image_preview"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             android:layout_margin="16dp"
-             android:layout_gravity="center"
-             android:contentDescription="@string/preview_image_description"
-             android:src="@drawable/logo" />
-         <VideoView
-             android:id="@+id/video_preview"
-             android:layout_width="match_parent"
-             android:layout_height="match_parent"
-             android:layout_gravity="center"
-             android:visibility="gone" />
-     </FrameLayout>
-     <com.owncloud.android.media.MediaControlView
-         android:id="@id/media_controller"
-         android:layout_width="match_parent"
-         android:layout_height="wrap_content"
-         android:layout_alignParentBottom="true" />
+           android:layout_width="match_parent"
+           android:layout_height="0dp"
+           android:layout_alignParentTop="true"
+           android:layout_above="@+id/media_controller"
+         >
+     
+           <ImageView
+               android:id="@+id/image_preview"
+               android:layout_width="match_parent"
+               android:layout_height="match_parent"
+               android:layout_margin="16dp"
+               android:layout_gravity="center"
+               android:contentDescription="@string/preview_image_description"
+               android:src="@drawable/logo" />
+           
+               <VideoView  
+                   android:id="@+id/video_preview"
+                       android:layout_width="match_parent"
+                       android:layout_height="match_parent"  
+                       android:layout_gravity="center" 
+                       android:visibility="gone"
+                       />
+               
+       </FrameLayout>
+       
+       <com.owncloud.android.media.MediaControlView 
+           android:id="@id/media_controller"
+           android:layout_width="match_parent"
+           android:layout_height="wrap_content"
+           android:layout_alignParentBottom="true"
+               android:layout_margin="16dp"
+           />
  
  </RelativeLayout>
@@@ -22,9 -22,9 +22,9 @@@ package com.owncloud.android.datamodel
  
  import android.os.Parcel;
  import android.os.Parcelable;
 +import android.webkit.MimeTypeMap;
  
  import com.owncloud.android.lib.common.utils.Log_OC;
 -import com.owncloud.android.utils.FileStorageUtils;
  
  import java.io.File;
  
@@@ -289,13 -289,11 +289,13 @@@ public class OCFile implements Parcelab
      /**
       * Sets the name of the file
       * <p/>
 -     * Does nothing if the new name is null, empty or includes "/" ; or if the file is the root directory
 +     * Does nothing if the new name is null, empty or includes "/" ; or if the file is the root
 +     * directory
       */
      public void setFileName(String name) {
          Log_OC.d(TAG, "OCFile name changin from " + mRemotePath);
 -        if (name != null && name.length() > 0 && !name.contains(PATH_SEPARATOR) && !mRemotePath.equals(ROOT_PATH)) {
 +        if (name != null && name.length() > 0 && !name.contains(PATH_SEPARATOR) &&
 +                !mRemotePath.equals(ROOT_PATH)) {
              String parent = (new File(getRemotePath())).getParent();
              parent = (parent.endsWith(PATH_SEPARATOR)) ? parent : parent + PATH_SEPARATOR;
              mRemotePath = parent + name;
  
      @Override
      public int describeContents() {
 -        return ((Object) this).hashCode();
 +        return super.hashCode();
      }
  
      @Override
  
      @Override
      public String toString() {
 -        String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, parentId=%s, favorite=%s etag=%s]";
 -        asString = String.format(asString, Long.valueOf(mId), getFileName(), mMimeType, isDown(), mLocalPath, mRemotePath, Long.valueOf(mParentId), Boolean.valueOf(mFavorite), mEtag);
 +        String asString = "[id=%s, name=%s, mime=%s, downloaded=%s, local=%s, remote=%s, " +
 +                "parentId=%s, favorite=%s etag=%s]";
 +        asString = String.format(asString, Long.valueOf(mId), getFileName(), mMimeType, isDown(),
 +                mLocalPath, mRemotePath, Long.valueOf(mParentId), Boolean.valueOf(mFavorite),
 +                mEtag);
          return asString;
      }
  
       */
      public boolean isImage() {
          return ((mMimeType != null && mMimeType.startsWith("image/")) ||
 -                FileStorageUtils.getMimeTypeFromName(mRemotePath).startsWith("image/"));
 +                getMimeTypeFromName().startsWith("image/"));
 +    }
 +
 +    /**
 +     * @return 'True' if the file is simple text (e.g. not application-dependent, like .doc or .docx)
 +     */
 +    public boolean isText() {
 +        return ((mMimeType != null && mMimeType.startsWith("text/")) ||
 +                getMimeTypeFromName().startsWith("text/"));
 +    }
 +
 +    public String getMimeTypeFromName() {
 +        String extension = "";
 +        int pos = mRemotePath.lastIndexOf('.');
 +        if (pos >= 0) {
 +            extension = mRemotePath.substring(pos + 1);
 +        }
 +        String result = MimeTypeMap.getSingleton().
 +                getMimeTypeFromExtension(extension.toLowerCase());
 +        return (result != null) ? result : "";
      }
  
+     /**
+      * @return 'True' if the file is hidden
+      */
+     public boolean isHidden() {
+         return getFileName().startsWith(".");
+     }
      public String getPermissions() {
          return mPermissions;
      }
@@@ -26,7 -26,7 +26,7 @@@ import android.accounts.Account
  import android.accounts.AccountManager;
  import android.accounts.AuthenticatorException;
  import android.annotation.TargetApi;
- import android.app.AlertDialog;
+ import android.support.v7.app.AlertDialog;
  import android.content.BroadcastReceiver;
  import android.content.ComponentName;
  import android.content.ContentResolver;
@@@ -48,12 -48,15 +48,15 @@@ import android.provider.OpenableColumns
  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentManager;
  import android.support.v4.app.FragmentTransaction;
+ 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.Window;
+ import android.widget.ProgressBar;
+ import android.widget.RelativeLayout;
+ import android.widget.TextView;
  import android.widget.Toast;
  
  import com.owncloud.android.MainApp;
@@@ -95,7 -98,6 +98,7 @@@ import com.owncloud.android.ui.fragment
  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;
@@@ -104,10 -106,7 +107,6 @@@ import com.owncloud.android.utils.UriUt
  
  import java.io.File;
  
- import java.io.IOException;
--
  /**
   * Displays, what files the user has available in his ownCloud.
   */
@@@ -116,8 -115,6 +115,8 @@@ public class FileDisplayActivity extend
          implements FileFragment.ContainerActivity,
          OnSslUntrustedCertListener, OnEnforceableRefreshListener {
  
 +
 +
      private SyncBroadcastReceiver mSyncBroadcastReceiver;
      private UploadFinishReceiver mUploadFinishReceiver;
      private DownloadFinishReceiver mDownloadFinishReceiver;
      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 TAG_SECOND_FRAGMENT = "SECOND_FRAGMENT";
  
      private OCFile mWaitingToPreview;
 -    
 +
      private boolean mSyncInProgress = false;
  
      private static String DIALOG_UNTRUSTED_CERT = "DIALOG_UNTRUSTED_CERT";
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          Log_OC.v(TAG, "onCreate() start");
-         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
  
          super.onCreate(savedInstanceState); // this calls onAccountChanged() when ownCloud Account
                                              // is valid
              Intent initObserversIntent = FileObserverService.makeInitIntent(this);
              startService(initObserversIntent);
          }
 -        
 +
          /// Load of saved instance state
          if(savedInstanceState != null) {
              mWaitingToPreview = (OCFile) savedInstanceState.getParcelable(
              mSyncInProgress = savedInstanceState.getBoolean(KEY_SYNC_IN_PROGRESS);
              mWaitingToSend = (OCFile) savedInstanceState.getParcelable(
                      FileDisplayActivity.KEY_WAITING_TO_SEND);
 -           
          } else {
              mWaitingToPreview = null;
              mSyncInProgress = false;
              mWaitingToSend = null;
 -        }        
 +        }
  
          /// USER INTERFACE
  
          
          // 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);
                                                                  // according to the official
                                                                  // documentation
  
-         setSupportProgressBarIndeterminateVisibility(mSyncInProgress
-         /*|| mRefreshSharesInProgress*/);
+         // 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.v(TAG, "onCreate() end");
      protected void onStart() {
          Log_OC.v(TAG, "onStart() start");
          super.onStart();
-         getSupportActionBar().setIcon(DisplayUtils.getSeasonalIconId());
          Log_OC.v(TAG, "onStart() 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);
              }
              setFile(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());
                  updateActionBarTitleAndHomeButton(file.isFolder() ? null : file);
          }
      }
  
 -
      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());
                  // 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);
                  updateActionBarTitleAndHomeButton(file);
 -                
 +
              } else {
                  cleanSecondFragment();
 +                if (file.isDown() && PreviewTextFragment.canBePreviewed(file))
 +                    startTextPreview(file);
              }
  
          } else {
      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 =
                  secondFragment = new PreviewMediaFragment(file, getAccount(),
                          startPlaybackPosition, autoplay);
  
 +            } else if (file.isDown() && PreviewTextFragment.canBePreviewed(file)) {
 +                secondFragment = null;
              } else {
 -                secondFragment = FileDetailFragment.newInstance(file, getAccount());
 -            }
 +            secondFragment = FileDetailFragment.newInstance(file, getAccount());
 +        }
          }
          return secondFragment;
      }
      /**
       * 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();
          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;
          Fragment second = getSupportFragmentManager().findFragmentByTag(
                  FileDisplayActivity.TAG_SECOND_FRAGMENT);
          if (second != null) {
 -            return (FileFragment)second;
 +            return (FileFragment) second;
          }
          return null;
      }
                          if (PreviewMediaFragment.canBePreviewed(mWaitingToPreview)) {
                              startMediaPreview(mWaitingToPreview, 0, true);
                              detailsFragmentChanged = true;
 +                        } else if (PreviewTextFragment.canBePreviewed(mWaitingToPreview)) {
 +                            startTextPreview(mWaitingToPreview);
 +                            detailsFragmentChanged = true;
                          } else {
                              getFileOperationsHelper().openFile(mWaitingToPreview);
                          }
                  dialog.show(getSupportFragmentManager(), DIALOG_CREATE_FOLDER);
                  break;
              }
 +
              case R.id.action_sync_account: {
                  startSynchronization();
                  break;
                  UploadSourceDialogFragment dialog =
                          UploadSourceDialogFragment.newInstance(getAccount());
                  dialog.show(getSupportFragmentManager(), DIALOG_UPLOAD_SOURCE);
 -
                  break;
              }
              case android.R.id.home: {
                  resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)) {
              requestMultipleUpload(data, resultCode);
  
 -        } else if (requestCode == ACTION_MOVE_FILES && resultCode == RESULT_OK){
 +        } else if (requestCode == ACTION_MOVE_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() {
 +                            requestMoveOperation(fData, fResultCode);
 +                        }
 +                    },
 +                    DELAY_TO_REQUEST_OPERATION_ON_ACTIVITY_RESULTS
              );
  
          } else {
  
      /**
       * 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);
  
      @Override
      public void onBackPressed() {
-         OCFileListFragment listOfFiles = getListOfFilesFragment();
-         if (mDualPane || getSecondFragment() == null) {
-             OCFile currentDir = getCurrentDir();
-             if (currentDir == null || currentDir.getParentId() == FileDataStorageManager.ROOT_PARENT_ID) {
-                 finish();
-                 return;
+         if (!isDrawerOpen()){
+             OCFileListFragment listOfFiles = getListOfFilesFragment();
+             if (mDualPane || getSecondFragment() == null) {
+                 OCFile currentDir = getCurrentDir();
+                 if (currentDir == null || currentDir.getParentId() == FileDataStorageManager.ROOT_PARENT_ID) {
+                     finish();
+                     return;
+                 }
+                 if (listOfFiles != null) {  // should never be null, indeed
+                     listOfFiles.onBrowseUp();
+                 }
              }
              if (listOfFiles != null) {  // should never be null, indeed
-                 listOfFiles.onBrowseUp();
+                 setFile(listOfFiles.getCurrentFile());
              }
+             cleanSecondFragment();
+         } else {
+             super.onBackPressed();
          }
-         if (listOfFiles != null) {  // should never be null, indeed
-             setFile(listOfFiles.getCurrentFile());
-         }
-         cleanSecondFragment();
      }
  
      @Override
  
          Log_OC.v(TAG, "onSaveInstanceState() end");
      }
 -    
  
  
      @Override
      protected void onResume() {
          Log_OC.v(TAG, "onResume() start");
          super.onResume();
 -
          // refresh Navigation Drawer account list
          mNavigationDrawerAdapter.updateAccountList();
  
 -
          // refresh list of files
          refreshListOfFilesFragment();
  
          downloadIntentFilter.addAction(FileDownloader.getDownloadFinishMessage());
          mDownloadFinishReceiver = new DownloadFinishReceiver();
          registerReceiver(mDownloadFinishReceiver, downloadIntentFilter);
 -        
          Log_OC.v(TAG, "onResume() end");
 +
      }
  
  
              unregisterReceiver(mDownloadFinishReceiver);
              mDownloadFinishReceiver = null;
          }
 -        
 +
          super.onPause();
          Log_OC.v(TAG, "onPause() end");
      }
                                  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());
                                                     synchFolderRemotePath),
                                              Toast.LENGTH_LONG)
                                  .show();
 +
                              browseToRoot();
 -                            
 +
                          } else {
                              if (currentFile == null && !getFile().isFolder()) {
                                  // currently selected file was removed in the server, and now we
                              }
                              setFile(currentFile);
                          }
 -                        
 +
                          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 {
                                          new OwnCloudAccount(getAccount(), context);
                                  client = (OwnCloudClientManagerFactory.getDefaultSingleton().
                                          removeClientFor(ocAccount));
 -
                                  if (client != null) {
                                      OwnCloudCredentials cred = client.getCredentials();
                                      if (cred != null) {
                      }
                      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)) {
              }
          }
      }
 -    
 +
      /**
       * Show a text message on screen view for notifying user if content is
       * loading or folder is empty
      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
                  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 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));
                      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.
       */
                              intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false)
                      );
                  }
 -    
 +
                  if (mWaitingToSend != null) {
                      mWaitingToSend =
                              getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
 -                    if (mWaitingToSend.isDown()) { 
 +                    if (mWaitingToSend.isDown()) {
                          sendDownloadedFile();
                      }
                  }
 -            
 +
              } finally {
                  if (intent != null) {
                      removeStickyBroadcast(intent);
                      accountName.equals(getAccount().name));
          }
      }
 -    
 -    
 +
 +
      public void browseToRoot() {
 -        OCFileListFragment listOfFiles = getListOfFilesFragment(); 
 +        OCFileListFragment listOfFiles = getListOfFilesFragment();
          if (listOfFiles != null) {  // should never be null, indeed
              OCFile root = getStorageManager().getFileByPath(OCFile.ROOT_PATH);
              listOfFiles.listDirectory(root);
              startSyncFolderOperation(root, false);
          }
          cleanSecondFragment();
 -
      }
  
  
      /**
       * {@inheritDoc}
 -     * 
 +     * <p/>
       * Updates action bar and second fragment, if in dual pane mode.
       */
      @Override
      }
  
      /**
 -     * 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) {
  
      }
  
      @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
                          if (!mWaitingToPreview.isDown()) {
                              requestForDownload();
                          }
 -                }
 +                    }
  
              } else if (component.equals(new ComponentName(FileDisplayActivity.this,
                      FileUploader.class))) {
              }
              // a new chance to get the mDownloadBinder through
              // getFileDownloadBinder() - THIS IS A MESS
 -            OCFileListFragment listOfFiles = getListOfFilesFragment(); 
 +            OCFileListFragment listOfFiles = getListOfFilesFragment();
              if (listOfFiles != null) {
                  listOfFiles.listDirectory();
                  // TODO Enable when "On Device" is recovered ?
              }
              FileFragment secondFragment = getSecondFragment();
              if (secondFragment != null && secondFragment instanceof FileDetailFragment) {
 -                FileDetailFragment detailFragment = (FileDetailFragment)secondFragment;
 +                FileDetailFragment detailFragment = (FileDetailFragment) secondFragment;
                  detailFragment.listenForTransferProgress();
                  detailFragment.updateFileDetails(false, false);
              }
                  mUploaderBinder = null;
              }
          }
 -    };    
 +    }
  
      @Override
      public void onSavedCertificate() {
      /**
       * 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);
  
          } 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);
          }
 -        
 -    }
  
 +    }
      
      private void onCreateShareOperationFinish(CreateShareOperation 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 {
 +                } 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.
      private void onRemoveFileOperationFinish(RemoveFileOperation operation,
                                               RemoteOperationResult result) {
          dismissLoadingDialog();
 -        
          Toast msg = Toast.makeText(this,
                  ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
 -                Toast.LENGTH_LONG); 
 +                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();
              }
          }
      }
 -    
 -    
 +
 +
      /**
 -     * 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) {
          } 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);
              }
          }
      }
                          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);
 +                    }
                  }
              }
              
          } else {
              Toast msg = Toast.makeText(this,
                      ErrorMessageAdapter.getErrorCauseMessage(result, operation, getResources()),
 -                    Toast.LENGTH_LONG); 
 +                    Toast.LENGTH_LONG);
              msg.show();
 -            
 +
              if (result.isSslRecoverableException()) {
                  mLastSslUntrustedServerResult = result;
                  showUntrustedCertDialog(mLastSslUntrustedServerResult);
          } 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}
       */
          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);
                  }
              }
          }
 -            
 +
      }
  
  
          }
          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,
                  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
          FragmentTransaction ft = fm.beginTransaction();
          dialog.show(ft, DIALOG_UNTRUSTED_CERT);
      }
 -    
 +
      private void requestForDownload(OCFile file) {
          Account account = getAccount();
          if (!mDownloaderBinder.isDownloading(account, mWaitingToPreview)) {
              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 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);
 +    }
 +
 +    /**
       * 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 = FileDetailFragment.newInstance(file, getAccount());
  
      public void cancelTransference(OCFile file) {
          getFileOperationsHelper().cancelTransference(file);
 -        if (mWaitingToPreview != null && 
 +        if (mWaitingToPreview != null &&
                  mWaitingToPreview.getRemotePath().equals(file.getRemotePath())) {
              mWaitingToPreview = null;
          }
          }
      }
  
 -    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);
      }
  
@@@ -29,11 -29,13 +29,13 @@@ import android.content.Intent
  import android.os.Bundle;
  import android.support.v4.widget.SwipeRefreshLayout;
  import android.view.ContextMenu;
+ import android.view.Menu;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.AdapterView.AdapterContextMenuInfo;
+ import android.widget.PopupMenu;
  
  import com.owncloud.android.R;
  import com.owncloud.android.authentication.AccountUtils;
@@@ -48,19 -50,20 +50,21 @@@ import com.owncloud.android.ui.activity
  import com.owncloud.android.ui.activity.OnEnforceableRefreshListener;
  import com.owncloud.android.ui.adapter.FileListListAdapter;
  import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
+ import com.owncloud.android.ui.dialog.FileActionsDialogFragment;
  import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
  import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
  import com.owncloud.android.ui.preview.PreviewImageFragment;
  import com.owncloud.android.ui.preview.PreviewMediaFragment;
+ import com.owncloud.android.utils.DialogMenuItem;
  import com.owncloud.android.utils.FileStorageUtils;
 +import com.owncloud.android.ui.preview.PreviewTextFragment;
  
  /**
   * A Fragment that lists all files and folders in a given path.
   * 
   * TODO refactor to get rid of direct dependency on FileDisplayActivity
   */
- public class OCFileListFragment extends ExtendedListFragment {
+ public class OCFileListFragment extends ExtendedListFragment implements FileActionsDialogFragment.FileActionsDialogFragmentListener {
      
      private static final String TAG = OCFileListFragment.class.getSimpleName();
  
                  );
          setListAdapter(mAdapter);
  
-         registerForContextMenu();
+         registerLongClickListener();
    }
  
+     private void registerLongClickListener() {
+         getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+             public boolean onItemLongClick(AdapterView<?> arg0, View v,
+                                            int index, long arg3) {
+                 showFileAction(index);
+                 return true;
+             }
+         });
+     }
+     private void showFileAction(int fileIndex) {
+         Bundle args = getArguments();
+         PopupMenu pm = new PopupMenu(getActivity(),null);
+         Menu menu = pm.getMenu();
+         boolean allowContextualActions =
+                 (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true);
+         if (allowContextualActions) {
+             MenuInflater inflater = getActivity().getMenuInflater();
+             inflater.inflate(R.menu.file_actions_menu, menu);
+             OCFile targetFile = (OCFile) mAdapter.getItem(fileIndex);
+             if (mContainerActivity.getStorageManager() != null) {
+                 FileMenuFilter mf = new FileMenuFilter(
+                         targetFile,
+                         mContainerActivity.getStorageManager().getAccount(),
+                         mContainerActivity,
+                         getActivity()
+                 );
+                 mf.filter(menu);
+             }
+             /// TODO break this direct dependency on FileDisplayActivity... if possible
+             MenuItem item = menu.findItem(R.id.action_open_file_with);
+             FileFragment frag = ((FileDisplayActivity)getActivity()).getSecondFragment();
+             if (frag != null && frag instanceof FileDetailFragment &&
+                     frag.getFile().getFileId() == targetFile.getFileId()) {
+                 item = menu.findItem(R.id.action_see_details);
+                 if (item != null) {
+                     item.setVisible(false);
+                     item.setEnabled(false);
+                 }
+             }
+             FileActionsDialogFragment dialog = FileActionsDialogFragment.newInstance(menu, fileIndex);
+             dialog.setTargetFragment(this, 0);
+             dialog.show(getFragmentManager(), FileActionsDialogFragment.FTAG_FILE_ACTIONS);
+         }
+     }
      /**
       * Saves the current listed folder.
       */
      /**
       * Call this, when the user presses the up button.
       * 
-      * Tries to move up the current folder one level. If the parent folder was removed from the 
+      * Tries to move up the current folder one level. If the parent folder was removed from the
       * database, it continues browsing up until finding an existing folders.
       * 
       * return       Count of folder levels browsed up.
                  if (PreviewImageFragment.canBePreviewed(file)) {
                      // preview image - it handles the download, if needed
                      ((FileDisplayActivity)mContainerActivity).startImagePreview(file);
 -                    
 +                } else if (PreviewTextFragment.canBePreviewed(file)){
 +                    ((FileDisplayActivity)mContainerActivity).startTextPreview(file);
                  } else if (file.isDown()) {
                      if (PreviewMediaFragment.canBePreviewed(file)) {
                          // media preview
      @Override
      public void onCreateContextMenu (
              ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-         super.onCreateContextMenu(menu, v, menuInfo);
          Bundle args = getArguments();
          boolean allowContextualActions = 
                  (args == null) ? true : args.getBoolean(ARG_ALLOW_CONTEXTUAL_ACTIONS, true); 
              }
          }
      }
-     
-     
      /**
-      * {@inhericDoc}
+      * {@inheritDoc}
       */
      @Override
-     public boolean onContextItemSelected (MenuItem item) {
-         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();        
-         mTargetFile = (OCFile) mAdapter.getItem(info.position);
-         switch (item.getItemId()) {                
+     public boolean onFileActionChosen(int menuId, int filePosition) {
+         mTargetFile = (OCFile) mAdapter.getItem(filePosition);
+         switch (menuId) {
              case R.id.action_share_file: {
                  mContainerActivity.getFileOperationsHelper().shareFileWithLink(mTargetFile);
                  return true;
                  dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
                  return true;
              }
-             case R.id.action_download_file: 
+             case R.id.action_download_file:
              case R.id.action_sync_file: {
                  mContainerActivity.getFileOperationsHelper().syncFile(mTargetFile);
                  return true;
              }
              case R.id.action_cancel_download:
              case R.id.action_cancel_upload: {
-                 ((FileDisplayActivity)mContainerActivity).cancelTransference(mTargetFile);
+                 ((FileDisplayActivity) mContainerActivity).cancelTransference(mTargetFile);
                  return true;
              }
              case R.id.action_see_details: {
                  // Obtain the file
                  if (!mTargetFile.isDown()) {  // Download the file
                      Log_OC.d(TAG, mTargetFile.getRemotePath() + " : File must be downloaded");
-                     ((FileDisplayActivity)mContainerActivity).startDownloadForSending(mTargetFile);
-                     
+                     ((FileDisplayActivity) mContainerActivity).startDownloadForSending(mTargetFile);
                  } else {
                      mContainerActivity.getFileOperationsHelper().sendDownloadedFile(mTargetFile);
                  }
                  getActivity().startActivityForResult(action, FileDisplayActivity.ACTION_MOVE_FILES);
                  return true;
              }
-             case R.id.action_favorite_file:{
+             case R.id.action_favorite_file: {
                  mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, true);
                  return true;
              }
-             case R.id.action_unfavorite_file:{
+             case R.id.action_unfavorite_file: {
                  mContainerActivity.getFileOperationsHelper().toggleFavorite(mTargetFile, false);
                  return true;
              }
              default:
-                 return super.onContextItemSelected(item); 
+                 return false;
+         }
+     }
+     
+     /**
+      * {@inhericDoc}
+      */
+     @Override
+     public boolean onContextItemSelected (MenuItem item) {
+         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+         boolean matched = onFileActionChosen(item.getItemId(), ((AdapterContextMenuInfo) item.getMenuInfo()).position);
+         if(!matched) {
+             return super.onContextItemSelected(item);
+         } else {
+             return matched;
          }
      }
  
                  if (file.isFolder()) {
                      foldersCount++;
                  } else {
-                     filesCount++;
-                     if (file.isImage()){
-                         imagesCount++;
+                     if (!file.isHidden()) {
+                         filesCount++;
+                         if (file.isImage()) {
+                             imagesCount++;
+                         }
                      }
                  }
              }
              if (version != null && version.supportsRemoteThumbnails() &&
                  imagesCount > 0 && imagesCount == filesCount) {
                  switchToGridView();
+                 registerLongClickListener();
              } else {
                  switchToListView();
              }
          return output;
      }
  
      public void sortByName(boolean descending) {
          mAdapter.setSortOrder(FileStorageUtils.SORT_NAME, descending);
      }
      public void sortBySize(boolean descending) {
          mAdapter.setSortOrder(FileStorageUtils.SORT_SIZE, descending);
      }
-     
  }