OSDN Git Service

Use System Resolver
[android-x86/packages-apps-CMFileManager.git] / src / com / cyanogenmod / filemanager / ui / widgets / NavigationView.java
old mode 100644 (file)
new mode 100755 (executable)
index 1563d92..6d8ba67
@@ -38,7 +38,9 @@ import com.cyanogenmod.filemanager.FileManagerApplication;
 import com.cyanogenmod.filemanager.R;
 import com.cyanogenmod.filemanager.adapters.FileSystemObjectAdapter;
 import com.cyanogenmod.filemanager.adapters.FileSystemObjectAdapter.OnSelectionChangedListener;
+import com.cyanogenmod.filemanager.console.CancelledOperationException;
 import com.cyanogenmod.filemanager.console.ConsoleAllocException;
+import com.cyanogenmod.filemanager.console.VirtualMountPointConsole;
 import com.cyanogenmod.filemanager.listeners.OnHistoryListener;
 import com.cyanogenmod.filemanager.listeners.OnRequestRefreshListener;
 import com.cyanogenmod.filemanager.listeners.OnSelectionListener;
@@ -79,8 +81,8 @@ import java.util.Map;
  * navigate, ...).
  */
 public class NavigationView extends RelativeLayout implements
-    AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener,
-    BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRefreshListener {
+AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener,
+BreadcrumbListener, OnSelectionChangedListener, OnSelectionListener, OnRequestRefreshListener {
 
     private static final String TAG = "NavigationView"; //$NON-NLS-1$
 
@@ -162,6 +164,12 @@ public class NavigationView extends RelativeLayout implements
             try {
                 // Response if the item can be removed
                 FileSystemObjectAdapter adapter = (FileSystemObjectAdapter)parent.getAdapter();
+
+                // Short circuit to protect OOBE
+                if (position < 0 || position >= adapter.getCount()) {
+                    return false;
+                }
+
                 FileSystemObject fso = adapter.getItem(position);
                 if (fso != null) {
                     if (fso instanceof ParentDirectory) {
@@ -212,15 +220,20 @@ public class NavigationView extends RelativeLayout implements
         private String mNewDirChecked;
         private final SearchInfoParcelable mSearchInfo;
         private final FileSystemObject mScrollTo;
+        private final Map<DisplayRestrictions, Object> mRestrictions;
+        private final boolean mChRooted;
 
         public NavigationTask(boolean useCurrent, boolean addToHistory, boolean reload,
-                SearchInfoParcelable searchInfo, FileSystemObject scrollTo) {
+                SearchInfoParcelable searchInfo, FileSystemObject scrollTo,
+                Map<DisplayRestrictions, Object> restrictions, boolean chRooted) {
             super();
             this.mUseCurrent = useCurrent;
             this.mAddToHistory = addToHistory;
             this.mSearchInfo = searchInfo;
             this.mReload = reload;
             this.mScrollTo = scrollTo;
+            this.mRestrictions = restrictions;
+            this.mChRooted = chRooted;
         }
 
         /**
@@ -232,15 +245,9 @@ public class NavigationView extends RelativeLayout implements
             // is created)
             mNewDirChecked = checkChRootedNavigation(params[0]);
 
-            //Check that it is really necessary change the directory
-            if (!mReload && NavigationView.this.mCurrentDir != null &&
-                    NavigationView.this.mCurrentDir.compareTo(mNewDirChecked) == 0) {
-                return null;
-            }
-
-            mHasChanged = !(NavigationView.this.mCurrentDir != null &&
-                    NavigationView.this.mCurrentDir.compareTo(mNewDirChecked) == 0);
-            mIsNewHistory = (NavigationView.this.mCurrentDir != null);
+            mHasChanged = !(NavigationView.this.mPreviousDir != null &&
+                    NavigationView.this.mPreviousDir.compareTo(mNewDirChecked) == 0);
+            mIsNewHistory = (NavigationView.this.mPreviousDir != null);
 
             try {
                 //Reset the custom title view and returns to breadcrumb
@@ -273,7 +280,12 @@ public class NavigationView extends RelativeLayout implements
                 if (!mUseCurrent) {
                     files = CommandHelper.listFiles(getContext(), mNewDirChecked, null);
                 }
-                return files;
+
+                //Apply user preferences
+                List<FileSystemObject> sortedFiles =
+                        FileHelper.applyUserPreferences(files, this.mRestrictions, this.mChRooted);
+
+                return sortedFiles;
 
             } catch (final ConsoleAllocException e) {
                 //Show exception and exists
@@ -299,32 +311,35 @@ public class NavigationView extends RelativeLayout implements
                         /**NON BLOCK**/
                     }
                 }
+                if (ex instanceof CancelledOperationException) {
+                    return null;
+                }
 
                 //Capture exception (attach task, and use listener to do the anim)
                 ExceptionUtil.attachAsyncTask(
-                    ex,
-                    new AsyncTask<Object, Integer, Boolean>() {
-                        private List<FileSystemObject> mTaskFiles = null;
-                        @Override
-                        @SuppressWarnings({
+                        ex,
+                        new AsyncTask<Object, Integer, Boolean>() {
+                            private List<FileSystemObject> mTaskFiles = null;
+                            @Override
+                            @SuppressWarnings({
                                 "unchecked", "unqualified-field-access"
-                        })
-                        protected Boolean doInBackground(Object... taskParams) {
-                            mTaskFiles = (List<FileSystemObject>)taskParams[0];
-                            return Boolean.TRUE;
-                        }
+                            })
+                            protected Boolean doInBackground(Object... taskParams) {
+                                mTaskFiles = (List<FileSystemObject>)taskParams[0];
+                                return Boolean.TRUE;
+                            }
 
-                        @Override
-                        @SuppressWarnings("unqualified-field-access")
-                        protected void onPostExecute(Boolean result) {
-                            if (!result.booleanValue()) {
-                                return;
+                            @Override
+                            @SuppressWarnings("unqualified-field-access")
+                            protected void onPostExecute(Boolean result) {
+                                if (!result.booleanValue()) {
+                                    return;
+                                }
+                                onPostExecuteTask(
+                                        mTaskFiles, mAddToHistory, mIsNewHistory, mHasChanged,
+                                        mSearchInfo, mNewDirChecked, mScrollTo);
                             }
-                            onPostExecuteTask(
-                                    mTaskFiles, mAddToHistory, mIsNewHistory, mHasChanged,
-                                    mSearchInfo, mNewDirChecked, mScrollTo);
-                        }
-                    });
+                        });
                 final OnRelaunchCommandResult exListener =
                         new OnRelaunchCommandResult() {
                     @Override
@@ -364,13 +379,11 @@ public class NavigationView extends RelativeLayout implements
         @Override
         protected void onPostExecute(List<FileSystemObject> files) {
             // This means an exception. This method will be recalled then
-            if (files != null) {
-                onPostExecuteTask(files, mAddToHistory, mIsNewHistory, mHasChanged,
+            onPostExecuteTask(files, mAddToHistory, mIsNewHistory, mHasChanged,
                         mSearchInfo, mNewDirChecked, mScrollTo);
 
-                // Do animation
-                fadeEfect(false);
-            }
+            // Do animation
+            fadeEfect(false);
         }
 
         /**
@@ -385,18 +398,19 @@ public class NavigationView extends RelativeLayout implements
                 public void run() {
                     Animation fadeAnim = out ?
                             new AlphaAnimation(1, 0) :
-                            new AlphaAnimation(0, 1);
-                    fadeAnim.setDuration(50L);
-                    fadeAnim.setFillAfter(true);
-                    fadeAnim.setInterpolator(new AccelerateInterpolator());
-                    NavigationView.this.startAnimation(fadeAnim);
+                                new AlphaAnimation(0, 1);
+                            fadeAnim.setDuration(50L);
+                            fadeAnim.setFillAfter(true);
+                            fadeAnim.setInterpolator(new AccelerateInterpolator());
+                            NavigationView.this.startAnimation(fadeAnim);
                 }
             });
         }
-   };
+    };
 
     private int mId;
     private String mCurrentDir;
+    private String mPreviousDir;
     private NavigationLayoutMode mCurrentMode;
     /**
      * @hide
@@ -417,6 +431,8 @@ public class NavigationView extends RelativeLayout implements
     // Restrictions
     private Map<DisplayRestrictions, Object> mRestrictions;
 
+    private NavigationTask mNavigationTask;
+
     /**
      * @hide
      */
@@ -489,10 +505,18 @@ public class NavigationView extends RelativeLayout implements
         //Return the persistent the data
         NavigationViewInfoParcelable parcel = new NavigationViewInfoParcelable();
         parcel.setId(this.mId);
-        parcel.setCurrentDir(this.mCurrentDir);
+        parcel.setCurrentDir(this.mPreviousDir);
         parcel.setChRooted(this.mChRooted);
         parcel.setSelectedFiles(this.mAdapter.getSelectedItems());
         parcel.setFiles(this.mFiles);
+
+        int firstVisiblePosition = mAdapterView.getFirstVisiblePosition();
+        if (firstVisiblePosition >= 0 && firstVisiblePosition < mAdapter.getCount()) {
+            FileSystemObject firstVisible = mAdapter
+                    .getItem(firstVisiblePosition);
+            parcel.setFirstVisible(firstVisible);
+        }
+
         return parcel;
     }
 
@@ -510,8 +534,10 @@ public class NavigationView extends RelativeLayout implements
         this.mFiles = info.getFiles();
         this.mAdapter.setSelectedItems(info.getSelectedFiles());
 
+        final FileSystemObject firstVisible = info.getFirstVisible();
+
         //Update the views
-        refresh();
+        refresh(firstVisible);
         return true;
     }
 
@@ -525,8 +551,8 @@ public class NavigationView extends RelativeLayout implements
         // Retrieve the mode
         this.mNavigationMode = NAVIGATION_MODE.BROWSABLE;
         int mode = tarray.getInteger(
-                                R.styleable.Navigable_navigation,
-                                NAVIGATION_MODE.BROWSABLE.ordinal());
+                R.styleable.Navigable_navigation,
+                NAVIGATION_MODE.BROWSABLE.ordinal());
         if (mode >= 0 && mode < NAVIGATION_MODE.values().length) {
             this.mNavigationMode = NAVIGATION_MODE.values()[mode];
         }
@@ -709,7 +735,7 @@ public class NavigationView extends RelativeLayout implements
             if (this.mAdapterView instanceof FlingerListView) {
                 if (useFlinger) {
                     ((FlingerListView)this.mAdapterView).
-                        setOnItemFlingerListener(this.mOnItemFlingerListener);
+                    setOnItemFlingerListener(this.mOnItemFlingerListener);
                 } else {
                     ((FlingerListView)this.mAdapterView).setOnItemFlingerListener(null);
                 }
@@ -722,17 +748,32 @@ public class NavigationView extends RelativeLayout implements
      *
      * @param fso The file system object
      */
-    public void scrollTo(FileSystemObject fso) {
-        if (fso != null) {
-            try {
-                int position = this.mAdapter.getPosition(fso);
-                this.mAdapterView.setSelection(position);
-            } catch (Exception e) {
-                this.mAdapterView.setSelection(0);
+    public void scrollTo(final FileSystemObject fso) {
+
+        this.mAdapterView.post(new Runnable() {
+
+            @Override
+            public void run() {
+                if (fso != null) {
+                    try {
+                        int position = mAdapter.getPosition(fso);
+                        mAdapterView.setSelection(position);
+
+                        // Make the scrollbar appear
+                        if (position > 0) {
+                            mAdapterView.scrollBy(0, 1);
+                            mAdapterView.scrollBy(0, -1);
+                        }
+
+                    } catch (Exception e) {
+                        mAdapterView.setSelection(0);
+                    }
+                } else {
+                    mAdapterView.setSelection(0);
+                }
             }
-        } else {
-            this.mAdapterView.setSelection(0);
-        }
+        });
+
     }
 
     /**
@@ -772,8 +813,25 @@ public class NavigationView extends RelativeLayout implements
             return;
         }
 
+        boolean addToHistory = false;
+        boolean reload = true;
+        boolean useCurrent = false;
+        SearchInfoParcelable searchInfo = null;
+
+        String newDir = this.mCurrentDir;
+        if (this.mNavigationTask != null) {
+            addToHistory = this.mNavigationTask.mAddToHistory;
+            reload = this.mNavigationTask.mReload;
+            useCurrent = this.mNavigationTask.mUseCurrent;
+            searchInfo = this.mNavigationTask.mSearchInfo;
+            this.mNavigationTask.cancel(true);
+            this.mNavigationTask = null;
+            this.mCurrentDir = this.mPreviousDir;
+            this.mPreviousDir = null;
+        }
+
         //Reload data
-        changeCurrentDir(this.mCurrentDir, false, true, false, null, scrollTo);
+        changeCurrentDir(newDir, addToHistory, reload, useCurrent, searchInfo, scrollTo);
     }
 
     /**
@@ -801,9 +859,9 @@ public class NavigationView extends RelativeLayout implements
         boolean useFlinger =
                 Preferences.getSharedPreferences().getBoolean(
                         FileManagerSettings.SETTINGS_USE_FLINGER.getId(),
-                            ((Boolean)FileManagerSettings.
-                                    SETTINGS_USE_FLINGER.
-                                        getDefaultValue()).booleanValue());
+                        ((Boolean)FileManagerSettings.
+                                SETTINGS_USE_FLINGER.
+                                getDefaultValue()).booleanValue());
 
         //Creates the new layout
         AdapterView<ListAdapter> newView = null;
@@ -822,7 +880,7 @@ public class NavigationView extends RelativeLayout implements
             if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
                 if (useFlinger && newView instanceof FlingerListView) {
                     ((FlingerListView)newView).
-                        setOnItemFlingerListener(this.mOnItemFlingerListener);
+                    setOnItemFlingerListener(this.mOnItemFlingerListener);
                 }
             }
 
@@ -835,7 +893,7 @@ public class NavigationView extends RelativeLayout implements
             if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
                 if (useFlinger && newView instanceof FlingerListView) {
                     ((FlingerListView)newView).
-                        setOnItemFlingerListener(this.mOnItemFlingerListener);
+                    setOnItemFlingerListener(this.mOnItemFlingerListener);
                 }
             }
         }
@@ -948,6 +1006,16 @@ public class NavigationView extends RelativeLayout implements
      * Method that changes the current directory of the view.
      *
      * @param newDir The new directory location
+     * @param addToHistory Add the directory to history
+     */
+    public void changeCurrentDir(final String newDir, boolean addToHistory) {
+        changeCurrentDir(newDir, addToHistory, false, false, null, null);
+    }
+
+    /**
+     * Method that changes the current directory of the view.
+     *
+     * @param newDir The new directory location
      * @param searchInfo The search information (if calling activity is {@link "SearchActivity"})
      */
     public void changeCurrentDir(final String newDir, SearchInfoParcelable searchInfo) {
@@ -968,9 +1036,39 @@ public class NavigationView extends RelativeLayout implements
             final String newDir, final boolean addToHistory,
             final boolean reload, final boolean useCurrent,
             final SearchInfoParcelable searchInfo, final FileSystemObject scrollTo) {
-        NavigationTask task = new NavigationTask(useCurrent, addToHistory, reload,
-                searchInfo, scrollTo);
-        task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, newDir);
+        if (mNavigationTask != null) {
+            this.mCurrentDir = this.mPreviousDir;
+            this.mPreviousDir = null;
+            mNavigationTask.cancel(true);
+            mNavigationTask = null;
+        }
+
+        this.mPreviousDir = this.mCurrentDir;
+        this.mCurrentDir = newDir;
+        mNavigationTask = new NavigationTask(useCurrent, addToHistory, reload,
+                searchInfo, scrollTo, mRestrictions, mChRooted);
+        mNavigationTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, newDir);
+    }
+
+    /**
+     * Remove all unmounted files in the current selection
+     */
+    public void removeUnmountedSelection() {
+        List<FileSystemObject> selection = mAdapter.getSelectedItems();
+        int cc = selection.size() - 1;
+        for (int i = cc; i >= 0; i--) {
+            FileSystemObject item = selection.get(i);
+            VirtualMountPointConsole vc =
+                    VirtualMountPointConsole.getVirtualConsoleForPath(item.getFullPath());
+            if (vc != null && !vc.isMounted()) {
+                selection.remove(i);
+            }
+        }
+        mAdapter.setSelectedItems(selection);
+        mAdapter.notifyDataSetChanged();
+
+        // Do not call the selection listener. This method is supposed to be called by the
+        // listener itself
     }
 
 
@@ -993,13 +1091,10 @@ public class NavigationView extends RelativeLayout implements
         try {
             //Check that there is not errors and have some data
             if (files == null) {
+                this.mCurrentDir = this.mPreviousDir;
                 return;
             }
 
-            //Apply user preferences
-            List<FileSystemObject> sortedFiles =
-                    FileHelper.applyUserPreferences(files, this.mRestrictions, this.mChRooted);
-
             //Remove parent directory if we are in the root of a chrooted environment
             if (this.mChRooted && StorageHelper.isStorageVolume(newDir)) {
                 if (files.size() > 0 && files.get(0) instanceof ParentDirectory) {
@@ -1007,13 +1102,6 @@ public class NavigationView extends RelativeLayout implements
                 }
             }
 
-            //Load the data
-            loadData(sortedFiles);
-            this.mFiles = sortedFiles;
-            if (searchInfo != null) {
-                searchInfo.setSuccessNavigation(true);
-            }
-
             //Add to history?
             if (addToHistory && hasChanged && isNewHistory) {
                 if (this.mOnHistoryListener != null) {
@@ -1022,28 +1110,36 @@ public class NavigationView extends RelativeLayout implements
                 }
             }
 
+            //Load the data
+            loadData(files);
+            this.mFiles = files;
+            if (searchInfo != null) {
+                searchInfo.setSuccessNavigation(true);
+            }
+
             //Change the breadcrumb
             if (this.mBreadcrumb != null) {
                 this.mBreadcrumb.changeBreadcrumbPath(newDir, this.mChRooted);
             }
 
-            //Scroll to object?
-            if (scrollTo != null) {
-                scrollTo(scrollTo);
-            }
+            //If scrollTo is null, the position will be set to 0
+            scrollTo(scrollTo);
 
             //The current directory is now the "newDir"
-            this.mCurrentDir = newDir;
             if (this.mOnDirectoryChangedListener != null) {
                 FileSystemObject dir = FileHelper.createFileSystemObject(new File(newDir));
                 this.mOnDirectoryChangedListener.onDirectoryChanged(dir);
             }
+
         } finally {
             //If calling activity is search, then save the search history
             if (searchInfo != null) {
                 this.mOnHistoryListener.onNewHistory(searchInfo);
             }
 
+            this.mPreviousDir = null;
+            mNavigationTask = null;
+
             //End of loading data
             try {
                 NavigationView.this.mBreadcrumb.endLoading();
@@ -1069,7 +1165,6 @@ public class NavigationView extends RelativeLayout implements
         adapter.clear();
         adapter.addAll(files);
         adapter.notifyDataSetChanged();
-        view.setSelection(0);
     }
 
     /**
@@ -1081,6 +1176,9 @@ public class NavigationView extends RelativeLayout implements
 
         // Get the adapter and the fso
         FileSystemObjectAdapter adapter = ((FileSystemObjectAdapter)parent.getAdapter());
+        if (adapter == null || position < 0 || (position >= adapter.getCount())) {
+            return false;
+        }
         FileSystemObject fso = adapter.getItem(position);
 
         // Parent directory hasn't actions
@@ -1118,7 +1216,7 @@ public class NavigationView extends RelativeLayout implements
             changeCurrentDir(fso.getFullPath(), searchInfo);
         } else {
             // Open the file with the preferred registered app
-            IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null, null);
+            IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null);
         }
     }
 
@@ -1150,7 +1248,7 @@ public class NavigationView extends RelativeLayout implements
             // Open the file (edit or pick)
             if (this.mNavigationMode.compareTo(NAVIGATION_MODE.BROWSABLE) == 0) {
                 // Open the file with the preferred registered app
-                IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null, null);
+                IntentsActionPolicy.openFileSystemObject(getContext(), fso, false, null);
             } else {
                 // Request a file pick selection
                 if (this.mOnFilePickedListener != null) {
@@ -1181,6 +1279,14 @@ public class NavigationView extends RelativeLayout implements
      * {@inheritDoc}
      */
     @Override
+    public void onRequestBookmarksRefresh() {
+        // Ignore
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public void onRequestRemove(Object o, boolean clearSelection) {
         if (o != null && o instanceof FileSystemObject) {
             removeItem((FileSystemObject)o);
@@ -1200,6 +1306,11 @@ public class NavigationView extends RelativeLayout implements
         // Ignored
     }
 
+    @Override
+    public void onCancel() {
+        // nop
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -1306,7 +1417,7 @@ public class NavigationView extends RelativeLayout implements
 
         //Change to first storage volume
         StorageVolume[] volumes =
-                StorageHelper.getStorageVolumes(getContext());
+                StorageHelper.getStorageVolumes(getContext(), false);
         if (volumes != null && volumes.length > 0) {
             changeCurrentDir(volumes[0].getPath(), false, true, false, null, null);
         }
@@ -1337,7 +1448,7 @@ public class NavigationView extends RelativeLayout implements
 
         // Check if the path is owned by one of the storage volumes
         if (!StorageHelper.isPathInStorageVolume(newDir)) {
-            StorageVolume[] volumes = StorageHelper.getStorageVolumes(getContext());
+            StorageVolume[] volumes = StorageHelper.getStorageVolumes(getContext(), false);
             if (volumes != null && volumes.length > 0) {
                 return volumes[0].getPath();
             }