updated android-filechooser library (non-public release from HBA)
fixed bug with date parsing in Dropbox added caching of FileEntry in Kp2aFileProvider.java
This commit is contained in:
		@@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
@@ -298,13 +299,22 @@ public class DropboxFileStorage implements JavaFileStorage {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private FileEntry convertToFileEntry(com.dropbox.client2.DropboxAPI.Entry e) {
 | 
			
		||||
		//Log.d("JFS","e="+e);
 | 
			
		||||
		FileEntry fileEntry = new FileEntry();
 | 
			
		||||
		fileEntry.canRead = true;
 | 
			
		||||
		fileEntry.canWrite = true;
 | 
			
		||||
		fileEntry.isDirectory = e.isDir;
 | 
			
		||||
		fileEntry.sizeInBytes = e.bytes;
 | 
			
		||||
		fileEntry.path = e.path;
 | 
			
		||||
		fileEntry.lastModifiedTime = com.dropbox.client2.RESTUtility.parseDate(e.modified).getTime();
 | 
			
		||||
		//Log.d("JFS","fileEntry="+fileEntry);
 | 
			
		||||
		Date lastModifiedDate = null;
 | 
			
		||||
		if (e.modified != null)
 | 
			
		||||
			lastModifiedDate = com.dropbox.client2.RESTUtility.parseDate(e.modified);
 | 
			
		||||
		if (lastModifiedDate != null)
 | 
			
		||||
			fileEntry.lastModifiedTime = lastModifiedDate.getTime();
 | 
			
		||||
		else 
 | 
			
		||||
			fileEntry.lastModifiedTime = -1;
 | 
			
		||||
		//Log.d("JFS","Ok. Dir="+fileEntry.isDirectory);
 | 
			
		||||
		return fileEntry;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -324,7 +334,10 @@ public class DropboxFileStorage implements JavaFileStorage {
 | 
			
		||||
	public FileEntry getFileEntry(String filename) throws Exception {
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			Log.d("JFS", "Hi!");
 | 
			
		||||
			Log.d("JFS", "mApi = "+mApi);
 | 
			
		||||
			com.dropbox.client2.DropboxAPI.Entry dbEntry = mApi.metadata(filename, 0, null, false, null);
 | 
			
		||||
			Log.d("JFS", "dbEntry = "+dbEntry);
 | 
			
		||||
			
 | 
			
		||||
			if (dbEntry.isDeleted)
 | 
			
		||||
				throw new FileNotFoundException(filename+" is deleted!");
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,6 @@ import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.providers.basefile.BaseFileContract.BaseFile;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.Converter;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.DateUtils;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.Utils;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.ui.LoadingDialog;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.ui.Ui;
 | 
			
		||||
@@ -510,11 +509,11 @@ public class BaseFileAdapter extends ResourceCursorAdapter {
 | 
			
		||||
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void onClick(final int resId) {
 | 
			
		||||
                            new LoadingDialog(v.getContext(),
 | 
			
		||||
                            new LoadingDialog<Void, Void, Void>(v.getContext(),
 | 
			
		||||
                                    R.string.afc_msg_loading, false) {
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                protected Object doInBackground(Void... params) {
 | 
			
		||||
                                protected Void doInBackground(Void... params) {
 | 
			
		||||
                                    if (resId == R.string.afc_cmd_advanced_selection_all)
 | 
			
		||||
                                        asyncSelectAll(-1, true);
 | 
			
		||||
                                    else if (resId == R.string.afc_cmd_advanced_selection_none)
 | 
			
		||||
@@ -533,7 +532,7 @@ public class BaseFileAdapter extends ResourceCursorAdapter {
 | 
			
		||||
                                }// doInBackground()
 | 
			
		||||
 | 
			
		||||
                                @Override
 | 
			
		||||
                                protected void onPostExecute(Object result) {
 | 
			
		||||
                                protected void onPostExecute(Void result) {
 | 
			
		||||
                                    super.onPostExecute(result);
 | 
			
		||||
                                    notifyDataSetChanged();
 | 
			
		||||
                                }// onPostExecute()
 | 
			
		||||
@@ -544,4 +543,5 @@ public class BaseFileAdapter extends ResourceCursorAdapter {
 | 
			
		||||
            return true;
 | 
			
		||||
        }// onLongClick()
 | 
			
		||||
    };// mCheckboxSelectionOnLongClickListener
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -214,7 +214,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
    private boolean mNewLoader = true;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Controls.
 | 
			
		||||
     * CONTROLS
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    private View mBtnGoHome;
 | 
			
		||||
@@ -268,7 +268,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                FileChooserActivity.EXTRA_MAX_FILE_COUNT, 1000);
 | 
			
		||||
        mFileAdapter = new BaseFileAdapter(getActivity(), mFilterMode,
 | 
			
		||||
                mIsMultiSelection);
 | 
			
		||||
        mFileAdapter.setBuildOptionsMenuListener(mOnBuildOptionsMenuListener);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * History.
 | 
			
		||||
@@ -320,12 +320,16 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                .findViewById(R.id.afc_textview_saveas_filename);
 | 
			
		||||
        mBtnOk = (Button) rootView.findViewById(R.id.afc_button_ok);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * INIT CONTROLS
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        return rootView;
 | 
			
		||||
    }// onCreateView()
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onActivityCreated(Bundle savedInstanceState) {
 | 
			
		||||
    public void onActivityCreated(final Bundle savedInstanceState) {
 | 
			
		||||
        super.onActivityCreated(savedInstanceState);
 | 
			
		||||
 | 
			
		||||
        setupHeader();
 | 
			
		||||
@@ -343,7 +347,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onPrepareOptionsMenu(Menu menu) {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "onPrepareOptionsMenu()");
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
@@ -406,13 +410,13 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onOptionsItemSelected(MenuItem item) {
 | 
			
		||||
        if (item.getItemId() == R.id.afc_menuitem_sort)
 | 
			
		||||
            doResortViewFiles();
 | 
			
		||||
            resortViewFiles();
 | 
			
		||||
        else if (item.getItemId() == R.id.afc_menuitem_new_folder)
 | 
			
		||||
            doCreateNewDir();
 | 
			
		||||
            createNewDir();
 | 
			
		||||
        else if (item.getItemId() == R.id.afc_menuitem_switch_viewmode)
 | 
			
		||||
            doSwitchViewType();
 | 
			
		||||
            switchViewType();
 | 
			
		||||
        else if (item.getItemId() == R.id.afc_menuitem_home)
 | 
			
		||||
            doGoHome();
 | 
			
		||||
            goHome();
 | 
			
		||||
        else
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -427,16 +431,16 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onStop() {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "onStop()");
 | 
			
		||||
 | 
			
		||||
        super.onStop();
 | 
			
		||||
        HistoryProviderUtils.clearHistory(getActivity());
 | 
			
		||||
        HistoryProviderUtils.doCleanupOutdatedHistoryItems(getActivity());
 | 
			
		||||
    }// onStop()
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onDestroy() {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "onDestroy()");
 | 
			
		||||
 | 
			
		||||
        super.onDestroy();
 | 
			
		||||
@@ -470,7 +474,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        String negativeRegex = getArguments().getString(
 | 
			
		||||
                FileChooserActivity.EXTRA_NEGATIVE_REGEX_FILTER);
 | 
			
		||||
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "onCreateLoader() >> path = " + path);
 | 
			
		||||
 | 
			
		||||
        return new CursorLoader(
 | 
			
		||||
@@ -532,7 +536,6 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        final Uri uriInfo = BaseFileProviderUtils.getUri(data);
 | 
			
		||||
        final Uri selectedFile = (Uri) getArguments().getParcelable(
 | 
			
		||||
                FileChooserActivity.EXTRA_SELECT_FILE);
 | 
			
		||||
        final int colUri = data.getColumnIndex(BaseFile.COLUMN_URI);
 | 
			
		||||
        if (selectedFile != null)
 | 
			
		||||
            getArguments().remove(FileChooserActivity.EXTRA_SELECT_FILE);
 | 
			
		||||
 | 
			
		||||
@@ -554,76 +557,8 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                        : getString(R.string.afc_msg_empty),
 | 
			
		||||
                mFileAdapter.isEmpty());
 | 
			
		||||
 | 
			
		||||
        if (mNewLoader || selectedFile != null) {
 | 
			
		||||
            /*
 | 
			
		||||
             * Select either the parent path of last path, or the file provided
 | 
			
		||||
             * by key EXTRA_SELECT_FILE. Use a Runnable to make sure this work.
 | 
			
		||||
             * Because if the list view is handling data, this might not work.
 | 
			
		||||
             */
 | 
			
		||||
            mViewFiles.post(new Runnable() {
 | 
			
		||||
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    int shouldBeSelectedIdx = -1;
 | 
			
		||||
                    final Uri uri = selectedFile != null ? selectedFile
 | 
			
		||||
                            : getLastLocation();
 | 
			
		||||
                    if (uri != null
 | 
			
		||||
                            && BaseFileProviderUtils.fileExists(getActivity(),
 | 
			
		||||
                                    uri)) {
 | 
			
		||||
                        final String fileName = BaseFileProviderUtils
 | 
			
		||||
                                .getFileName(getActivity(), uri);
 | 
			
		||||
                        if (fileName != null) {
 | 
			
		||||
                            Uri parentUri = BaseFileProviderUtils
 | 
			
		||||
                                    .getParentFile(getActivity(), uri);
 | 
			
		||||
                            if ((uri == getLastLocation()
 | 
			
		||||
                                    && !getCurrentLocation().equals(
 | 
			
		||||
                                            getLastLocation()) && BaseFileProviderUtils
 | 
			
		||||
                                        .isAncestorOf(getActivity(),
 | 
			
		||||
                                                getCurrentLocation(), uri))
 | 
			
		||||
                                    || getCurrentLocation().equals(parentUri)) {
 | 
			
		||||
                                if (data.moveToFirst()) {
 | 
			
		||||
                                    while (!data.isLast()) {
 | 
			
		||||
                                        Uri subUri = Uri.parse(data
 | 
			
		||||
                                                .getString(colUri));
 | 
			
		||||
                                        if (uri == getLastLocation()) {
 | 
			
		||||
                                            if (data.getInt(data
 | 
			
		||||
                                                    .getColumnIndex(BaseFile.COLUMN_TYPE)) == BaseFile.FILE_TYPE_DIRECTORY) {
 | 
			
		||||
                                                if (subUri.equals(uri)
 | 
			
		||||
                                                        || BaseFileProviderUtils
 | 
			
		||||
                                                                .isAncestorOf(
 | 
			
		||||
                                                                        getActivity(),
 | 
			
		||||
                                                                        subUri,
 | 
			
		||||
                                                                        uri)) {
 | 
			
		||||
                                                    shouldBeSelectedIdx = Math.max(
 | 
			
		||||
                                                            0,
 | 
			
		||||
                                                            data.getPosition() - 2);
 | 
			
		||||
                                                    break;
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        } else {
 | 
			
		||||
                                            if (uri.equals(subUri)) {
 | 
			
		||||
                                                shouldBeSelectedIdx = Math.max(
 | 
			
		||||
                                                        0,
 | 
			
		||||
                                                        data.getPosition() - 2);
 | 
			
		||||
                                                break;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        data.moveToNext();
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (shouldBeSelectedIdx >= 0
 | 
			
		||||
                            && shouldBeSelectedIdx < mFileAdapter.getCount())
 | 
			
		||||
                        mViewFiles.setSelection(shouldBeSelectedIdx);
 | 
			
		||||
                    else if (!mFileAdapter.isEmpty())
 | 
			
		||||
                        mViewFiles.setSelection(0);
 | 
			
		||||
                }// run()
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        if (mNewLoader || selectedFile != null)
 | 
			
		||||
            createFileSelector();
 | 
			
		||||
 | 
			
		||||
        mNewLoader = false;
 | 
			
		||||
    }// onLoadFinished()
 | 
			
		||||
@@ -693,7 +628,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        mViewGoForward.setEnabled(false);
 | 
			
		||||
        mViewGoForward.setOnClickListener(mBtnGoForwardOnClickListener);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
    }// setupHeader()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -770,7 +705,9 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * </ul>
 | 
			
		||||
     */
 | 
			
		||||
    private void setupFooter() {
 | 
			
		||||
        // by default, view group footer and all its child views are hidden
 | 
			
		||||
        /*
 | 
			
		||||
         * By default, view group footer and all its child views are hidden.
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        ViewGroup viewGroupFooterContainer = (ViewGroup) getView()
 | 
			
		||||
                .findViewById(R.id.afc_viewgroup_footer_container);
 | 
			
		||||
@@ -851,6 +788,10 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
            mFooterView.setVisibility(View.GONE);
 | 
			
		||||
    }// showFooterView()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This should be called after the owner activity has been created
 | 
			
		||||
     * successfully.
 | 
			
		||||
     */
 | 
			
		||||
    private void initGestureDetector() {
 | 
			
		||||
        mListviewFilesGestureDetector = new GestureDetector(getActivity(),
 | 
			
		||||
                new GestureDetector.SimpleOnGestureListener() {
 | 
			
		||||
@@ -920,12 +861,12 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                                if (BaseFileProviderUtils.isFile(data)) {
 | 
			
		||||
                                    mTxtSaveas.setText(BaseFileProviderUtils
 | 
			
		||||
                                            .getFileName(data));
 | 
			
		||||
                                    doCheckSaveasFilenameAndFinish(BaseFileProviderUtils
 | 
			
		||||
                                    checkSaveasFilenameAndFinish(BaseFileProviderUtils
 | 
			
		||||
                                            .getFileName(data));
 | 
			
		||||
                                } else
 | 
			
		||||
                                    return false;
 | 
			
		||||
                            } else
 | 
			
		||||
                                doFinish(BaseFileProviderUtils.getUri(data));
 | 
			
		||||
                                finish(BaseFileProviderUtils.getUri(data));
 | 
			
		||||
                        }// double tap to choose files
 | 
			
		||||
                        else {
 | 
			
		||||
                            // do nothing
 | 
			
		||||
@@ -963,8 +904,8 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                                        .setAction(MotionEvent.ACTION_CANCEL);
 | 
			
		||||
                                mViewFiles.onTouchEvent(cancelEvent);
 | 
			
		||||
 | 
			
		||||
                                doDeleteFile(mViewFiles
 | 
			
		||||
                                        .getFirstVisiblePosition() + pos);
 | 
			
		||||
                                deleteFile(mViewFiles.getFirstVisiblePosition()
 | 
			
		||||
                                        + pos);
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
@@ -985,7 +926,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * @param savedInstanceState
 | 
			
		||||
     */
 | 
			
		||||
    private void loadInitialPath(final Bundle savedInstanceState) {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, String.format(
 | 
			
		||||
                    "loadInitialPath() >> authority=[%s] | mRoot=[%s]",
 | 
			
		||||
                    mFileProviderAuthority, mRoot));
 | 
			
		||||
@@ -1046,11 +987,24 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                                    .getAuthority());
 | 
			
		||||
 | 
			
		||||
        if (path == null) {
 | 
			
		||||
            doShowCannotConnectToServiceAndFinish();
 | 
			
		||||
            showCannotConnectToServiceAndFinish();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!BaseFileProviderUtils.fileCanRead(getActivity(), path)) {
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "loadInitialPath() >> " + path);
 | 
			
		||||
 | 
			
		||||
        setCurrentLocation(path);
 | 
			
		||||
 | 
			
		||||
        if (BaseFileProviderUtils.fileCanRead(getActivity(), path)) {
 | 
			
		||||
            /*
 | 
			
		||||
             * Prepare the loader. Either re-connect with an existing one, or
 | 
			
		||||
             * start a new one.
 | 
			
		||||
             */
 | 
			
		||||
            Bundle args = new Bundle();
 | 
			
		||||
            args.putParcelable(PATH, path);
 | 
			
		||||
            getLoaderManager().initLoader(mIdLoaderData, args, this);
 | 
			
		||||
        } else {
 | 
			
		||||
            Dlg.toast(
 | 
			
		||||
                    getActivity(),
 | 
			
		||||
                    getString(R.string.afc_pmsg_cannot_access_dir,
 | 
			
		||||
@@ -1058,19 +1012,6 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                                    path)), Dlg.LENGTH_SHORT);
 | 
			
		||||
            getActivity().finish();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
            Log.d(CLASSNAME, "loadInitialPath() >> " + path);
 | 
			
		||||
 | 
			
		||||
        setCurrentLocation(path);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Prepare the loader. Either re-connect with an existing one, or start
 | 
			
		||||
         * a new one.
 | 
			
		||||
         */
 | 
			
		||||
        Bundle b = new Bundle();
 | 
			
		||||
        b.putParcelable(PATH, path);
 | 
			
		||||
        getLoaderManager().initLoader(mIdLoaderData, b, this);
 | 
			
		||||
    }// loadInitialPath()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -1100,7 +1041,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
    /**
 | 
			
		||||
     * As the name means...
 | 
			
		||||
     */
 | 
			
		||||
    private void doShowCannotConnectToServiceAndFinish() {
 | 
			
		||||
    private void showCannotConnectToServiceAndFinish() {
 | 
			
		||||
        Dlg.showError(getActivity(),
 | 
			
		||||
                R.string.afc_msg_cannot_connect_to_file_provider_service,
 | 
			
		||||
                new DialogInterface.OnCancelListener() {
 | 
			
		||||
@@ -1111,7 +1052,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                        getActivity().finish();
 | 
			
		||||
                    }// onCancel()
 | 
			
		||||
                });
 | 
			
		||||
    }// doShowCannotConnectToServiceAndFinish()
 | 
			
		||||
    }// showCannotConnectToServiceAndFinish()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets last location.
 | 
			
		||||
@@ -1154,9 +1095,10 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        updateDbHistory(location);
 | 
			
		||||
    }// setCurrentLocation()
 | 
			
		||||
 | 
			
		||||
    private void doGoHome() {
 | 
			
		||||
    private void goHome() {
 | 
			
		||||
        goTo(mRoot);
 | 
			
		||||
    }// doGoHome()
 | 
			
		||||
    }// goHome()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static final int[] BUTTON_SORT_IDS = {
 | 
			
		||||
            R.id.afc_button_sort_by_name_asc,
 | 
			
		||||
@@ -1169,7 +1111,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * Show a dialog for sorting options and resort file list after user
 | 
			
		||||
     * selected an option.
 | 
			
		||||
     */
 | 
			
		||||
    private void doResortViewFiles() {
 | 
			
		||||
    private void resortViewFiles() {
 | 
			
		||||
        final Dialog dialog = new Dialog(getActivity(), Ui.resolveAttribute(
 | 
			
		||||
                getActivity(), R.attr.afc_theme_dialog));
 | 
			
		||||
        dialog.setCanceledOnTouchOutside(true);
 | 
			
		||||
@@ -1245,12 +1187,12 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        dialog.setTitle(R.string.afc_title_sort_by);
 | 
			
		||||
        dialog.setContentView(view);
 | 
			
		||||
        dialog.show();
 | 
			
		||||
    }// doResortViewFiles()
 | 
			
		||||
    }// resortViewFiles()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Switch view type between {@link ViewType#LIST} and {@link ViewType#GRID}
 | 
			
		||||
     */
 | 
			
		||||
    private void doSwitchViewType() {
 | 
			
		||||
    private void switchViewType() {
 | 
			
		||||
        switch (DisplayPrefs.getViewType(getActivity())) {
 | 
			
		||||
        case GRID:
 | 
			
		||||
            DisplayPrefs.setViewType(getActivity(), ViewType.LIST);
 | 
			
		||||
@@ -1263,12 +1205,12 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        setupViewFiles();
 | 
			
		||||
        getActivity().supportInvalidateOptionsMenu();
 | 
			
		||||
        goTo(getCurrentLocation());
 | 
			
		||||
    }// doSwitchViewType()
 | 
			
		||||
    }// switchViewType()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Confirms user to create new directory.
 | 
			
		||||
     */
 | 
			
		||||
    private void doCreateNewDir() {
 | 
			
		||||
    private void createNewDir() {
 | 
			
		||||
        if (LocalFileContract.getAuthority(getActivity()).equals(
 | 
			
		||||
                mFileProviderAuthority)
 | 
			
		||||
                && !Utils.hasPermissions(getActivity(),
 | 
			
		||||
@@ -1329,22 +1271,23 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (getActivity()
 | 
			
		||||
                                .getContentResolver()
 | 
			
		||||
                                .insert(BaseFile
 | 
			
		||||
                                        .genContentUriBase(
 | 
			
		||||
                        if (BaseFileProviderUtils
 | 
			
		||||
                                .insertInBackground(
 | 
			
		||||
                                        getActivity(),
 | 
			
		||||
                                        BaseFile.genContentUriBase(
 | 
			
		||||
                                                getCurrentLocation()
 | 
			
		||||
                                                        .getAuthority())
 | 
			
		||||
                                        .buildUpon()
 | 
			
		||||
                                        .appendPath(
 | 
			
		||||
                                                getCurrentLocation()
 | 
			
		||||
                                                        .getLastPathSegment())
 | 
			
		||||
                                        .appendQueryParameter(
 | 
			
		||||
                                                BaseFile.PARAM_NAME, name)
 | 
			
		||||
                                        .appendQueryParameter(
 | 
			
		||||
                                                BaseFile.PARAM_FILE_TYPE,
 | 
			
		||||
                                                Integer.toString(BaseFile.FILE_TYPE_DIRECTORY))
 | 
			
		||||
                                        .build(), null) != null) {
 | 
			
		||||
                                                .buildUpon()
 | 
			
		||||
                                                .appendPath(
 | 
			
		||||
                                                        getCurrentLocation()
 | 
			
		||||
                                                                .getLastPathSegment())
 | 
			
		||||
                                                .appendQueryParameter(
 | 
			
		||||
                                                        BaseFile.PARAM_NAME,
 | 
			
		||||
                                                        name)
 | 
			
		||||
                                                .appendQueryParameter(
 | 
			
		||||
                                                        BaseFile.PARAM_FILE_TYPE,
 | 
			
		||||
                                                        Integer.toString(BaseFile.FILE_TYPE_DIRECTORY))
 | 
			
		||||
                                                .build(), null) != null) {
 | 
			
		||||
                            Dlg.toast(getActivity(),
 | 
			
		||||
                                    getString(R.string.afc_msg_done),
 | 
			
		||||
                                    Dlg.LENGTH_SHORT);
 | 
			
		||||
@@ -1383,7 +1326,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                        .trim()));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }// doCreateNewDir()
 | 
			
		||||
    }// createNewDir()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deletes a file.
 | 
			
		||||
@@ -1391,7 +1334,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * @param position
 | 
			
		||||
     *            the position of item to be delete.
 | 
			
		||||
     */
 | 
			
		||||
    private void doDeleteFile(final int position) {
 | 
			
		||||
    private void deleteFile(final int position) {
 | 
			
		||||
        Cursor cursor = (Cursor) mFileAdapter.getItem(position);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
@@ -1440,13 +1383,15 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void onClick(DialogInterface dialog, int which) {
 | 
			
		||||
                        new LoadingDialog(getActivity(), getString(
 | 
			
		||||
                                R.string.afc_pmsg_deleting_file,
 | 
			
		||||
                                isFile ? getString(R.string.afc_file)
 | 
			
		||||
                                        : getString(R.string.afc_folder),
 | 
			
		||||
                                filename), true) {
 | 
			
		||||
                        new LoadingDialog<Void, Void, Void>(
 | 
			
		||||
                                getActivity(),
 | 
			
		||||
                                getString(
 | 
			
		||||
                                        R.string.afc_pmsg_deleting_file,
 | 
			
		||||
                                        isFile ? getString(R.string.afc_file)
 | 
			
		||||
                                                : getString(R.string.afc_folder),
 | 
			
		||||
                                        filename), true) {
 | 
			
		||||
 | 
			
		||||
                            final int mTaskId = EnvUtils.genId();
 | 
			
		||||
                            final int taskId = EnvUtils.genId();
 | 
			
		||||
 | 
			
		||||
                            private void notifyFileDeleted() {
 | 
			
		||||
                                mHistory.removeAll(new HistoryFilter<Uri>() {
 | 
			
		||||
@@ -1472,15 +1417,15 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                            }// notifyFileDeleted()
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            protected Object doInBackground(Void... arg0) {
 | 
			
		||||
                                getActivity()
 | 
			
		||||
                                        .getContentResolver()
 | 
			
		||||
                                        .delete(uri
 | 
			
		||||
                                                .buildUpon()
 | 
			
		||||
                                                .appendQueryParameter(
 | 
			
		||||
                                                        BaseFile.PARAM_TASK_ID,
 | 
			
		||||
                                                        Integer.toString(mTaskId))
 | 
			
		||||
                                                .build(), null, null);
 | 
			
		||||
                            protected Void doInBackground(Void... params) {
 | 
			
		||||
                                BaseFileProviderUtils
 | 
			
		||||
                                        .deleteInBackground(
 | 
			
		||||
                                                getActivity(),
 | 
			
		||||
                                                uri.buildUpon()
 | 
			
		||||
                                                        .appendQueryParameter(
 | 
			
		||||
                                                                BaseFile.PARAM_TASK_ID,
 | 
			
		||||
                                                                Integer.toString(taskId))
 | 
			
		||||
                                                        .build(), null, null);
 | 
			
		||||
 | 
			
		||||
                                return null;
 | 
			
		||||
                            }// doInBackground()
 | 
			
		||||
@@ -1490,7 +1435,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                                if (getCurrentLocation() != null)
 | 
			
		||||
                                    BaseFileProviderUtils.cancelTask(
 | 
			
		||||
                                            getActivity(), getCurrentLocation()
 | 
			
		||||
                                                    .getAuthority(), mTaskId);
 | 
			
		||||
                                                    .getAuthority(), taskId);
 | 
			
		||||
 | 
			
		||||
                                if (BaseFileProviderUtils.fileExists(
 | 
			
		||||
                                        getActivity(), uri)) {
 | 
			
		||||
@@ -1505,7 +1450,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                            }// onCancelled()
 | 
			
		||||
 | 
			
		||||
                            @Override
 | 
			
		||||
                            protected void onPostExecute(Object result) {
 | 
			
		||||
                            protected void onPostExecute(Void result) {
 | 
			
		||||
                                super.onPostExecute(result);
 | 
			
		||||
 | 
			
		||||
                                if (BaseFileProviderUtils.fileExists(
 | 
			
		||||
@@ -1530,7 +1475,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                        mFileAdapter.markItemAsDeleted(id, false);
 | 
			
		||||
                    }// onCancel()
 | 
			
		||||
                });
 | 
			
		||||
    }// doDeleteFile()
 | 
			
		||||
    }// deleteFile()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * As the name means.
 | 
			
		||||
@@ -1538,7 +1483,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * @param filename
 | 
			
		||||
     * @since v1.91
 | 
			
		||||
     */
 | 
			
		||||
    private void doCheckSaveasFilenameAndFinish(String filename) {
 | 
			
		||||
    private void checkSaveasFilenameAndFinish(String filename) {
 | 
			
		||||
        if (!BaseFileProviderUtils.fileCanWrite(getActivity(),
 | 
			
		||||
                getCurrentLocation())) {
 | 
			
		||||
            Dlg.toast(getActivity(),
 | 
			
		||||
@@ -1553,7 +1498,8 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final Cursor cursor = getActivity().getContentResolver().query(
 | 
			
		||||
        final Cursor cursor = BaseFileProviderUtils.queryInBackground(
 | 
			
		||||
                getActivity(),
 | 
			
		||||
                getCurrentLocation()
 | 
			
		||||
                        .buildUpon()
 | 
			
		||||
                        .appendQueryParameter(BaseFile.PARAM_APPEND_NAME,
 | 
			
		||||
@@ -1583,7 +1529,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                                    @Override
 | 
			
		||||
                                    public void onClick(DialogInterface dialog,
 | 
			
		||||
                                            int which) {
 | 
			
		||||
                                        doFinish(uri);
 | 
			
		||||
                                        finish(uri);
 | 
			
		||||
                                    }// onClick()
 | 
			
		||||
                                });
 | 
			
		||||
 | 
			
		||||
@@ -1593,7 +1539,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                        /*
 | 
			
		||||
                         * TODO file type unknown?
 | 
			
		||||
                         */
 | 
			
		||||
                        doFinish(uri);
 | 
			
		||||
                        finish(uri);
 | 
			
		||||
                        break;// FILE_TYPE_NOT_EXISTED
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1601,7 +1547,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                cursor.close();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }// doCheckSaveasFilenameAndFinish()
 | 
			
		||||
    }// checkSaveasFilenameAndFinish()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Goes to a specified location.
 | 
			
		||||
@@ -1616,7 +1562,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
            dir = BaseFileProviderUtils.getDefaultPath(getActivity(),
 | 
			
		||||
                    mFileProviderAuthority);
 | 
			
		||||
        if (dir == null) {
 | 
			
		||||
            doShowCannotConnectToServiceAndFinish();
 | 
			
		||||
            showCannotConnectToServiceAndFinish();
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1655,7 +1601,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * Updates or inserts {@code path} into history database.
 | 
			
		||||
     */
 | 
			
		||||
    private void updateDbHistory(Uri path) {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "updateDbHistory() >> path = " + path);
 | 
			
		||||
 | 
			
		||||
        Calendar cal = Calendar.getInstance();
 | 
			
		||||
@@ -1663,7 +1609,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                - (cal.get(Calendar.HOUR_OF_DAY) * 60 * 60 * 1000
 | 
			
		||||
                        + cal.get(Calendar.MINUTE) * 60 * 1000 + cal
 | 
			
		||||
                        .get(Calendar.SECOND) * 1000);
 | 
			
		||||
        if (Utils.doLog()) {
 | 
			
		||||
        if (BuildConfig.DEBUG) {
 | 
			
		||||
            Log.d(CLASSNAME,
 | 
			
		||||
                    String.format("beginToday = %s (%s)", DbUtils
 | 
			
		||||
                            .formatNumber(beginTodayMillis), new Date(
 | 
			
		||||
@@ -1730,8 +1676,8 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        final int dim = getResources().getDimensionPixelSize(R.dimen.afc_5dp);
 | 
			
		||||
        int count = 0;
 | 
			
		||||
 | 
			
		||||
        Cursor cursor = getActivity().getContentResolver().query(path, null,
 | 
			
		||||
                null, null, null);
 | 
			
		||||
        Cursor cursor = BaseFileProviderUtils.queryInBackground(getActivity(),
 | 
			
		||||
                path, null, null, null, null);
 | 
			
		||||
        while (cursor != null) {
 | 
			
		||||
            Uri lastUri = null;
 | 
			
		||||
            if (cursor.moveToFirst()) {
 | 
			
		||||
@@ -1771,7 +1717,8 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
            /*
 | 
			
		||||
             * Process the parent directory.
 | 
			
		||||
             */
 | 
			
		||||
            cursor = getActivity().getContentResolver().query(
 | 
			
		||||
            cursor = BaseFileProviderUtils.queryInBackground(
 | 
			
		||||
                    getActivity(),
 | 
			
		||||
                    BaseFile.genContentUriApi(lastUri.getAuthority())
 | 
			
		||||
                            .buildUpon()
 | 
			
		||||
                            .appendPath(BaseFile.CMD_GET_PARENT)
 | 
			
		||||
@@ -1809,12 +1756,12 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * @param files
 | 
			
		||||
     *            list of {@link Uri}.
 | 
			
		||||
     */
 | 
			
		||||
    private void doFinish(Uri... files) {
 | 
			
		||||
    private void finish(Uri... files) {
 | 
			
		||||
        List<Uri> list = new ArrayList<Uri>();
 | 
			
		||||
        for (Uri uri : files)
 | 
			
		||||
            list.add(uri);
 | 
			
		||||
        doFinish((ArrayList<Uri>) list);
 | 
			
		||||
    }// doFinish()
 | 
			
		||||
        finish((ArrayList<Uri>) list);
 | 
			
		||||
    }// finish()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Finishes this activity.
 | 
			
		||||
@@ -1822,7 +1769,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * @param files
 | 
			
		||||
     *            list of {@link Uri}.
 | 
			
		||||
     */
 | 
			
		||||
    private void doFinish(ArrayList<Uri> files) {
 | 
			
		||||
    private void finish(ArrayList<Uri> files) {
 | 
			
		||||
        if (files == null || files.isEmpty()) {
 | 
			
		||||
            getActivity().setResult(Activity.RESULT_CANCELED);
 | 
			
		||||
            getActivity().finish();
 | 
			
		||||
@@ -1842,7 +1789,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
            DisplayPrefs.setLastLocation(getActivity(), null);
 | 
			
		||||
 | 
			
		||||
        getActivity().finish();
 | 
			
		||||
    }// doFinish()
 | 
			
		||||
    }// finish()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * ******************************************************* BUTTON LISTENERS
 | 
			
		||||
@@ -1852,10 +1799,12 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            doGoHome();
 | 
			
		||||
            goHome();
 | 
			
		||||
        }// onClick()
 | 
			
		||||
    };// mBtnGoHomeOnClickListener
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private final View.OnClickListener mBtnGoBackOnClickListener = new View.OnClickListener() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@@ -1894,7 +1843,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
            if (BaseFile.FILTER_FILES_ONLY == mFilterMode || mIsSaveDialog)
 | 
			
		||||
                return false;
 | 
			
		||||
 | 
			
		||||
            doFinish((Uri) v.getTag());
 | 
			
		||||
            finish((Uri) v.getTag());
 | 
			
		||||
 | 
			
		||||
            return false;
 | 
			
		||||
        }// onLongClick()
 | 
			
		||||
@@ -1922,6 +1871,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        }// onClick()
 | 
			
		||||
    };// mBtnGoForwardOnClickListener
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    private final TextView.OnEditorActionListener mTxtFilenameOnEditorActionListener = new TextView.OnEditorActionListener() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@@ -1941,7 +1891,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            Ui.showSoftKeyboard(v, false);
 | 
			
		||||
            String filename = mTxtSaveas.getText().toString().trim();
 | 
			
		||||
            doCheckSaveasFilenameAndFinish(filename);
 | 
			
		||||
            checkSaveasFilenameAndFinish(filename);
 | 
			
		||||
        }// onClick()
 | 
			
		||||
    };// mBtnOk_SaveDialog_OnClickListener
 | 
			
		||||
 | 
			
		||||
@@ -1949,7 +1899,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onClick(View v) {
 | 
			
		||||
            doFinish(mFileAdapter.getSelectedItems());
 | 
			
		||||
            finish(mFileAdapter.getSelectedItems());
 | 
			
		||||
        }// onClick()
 | 
			
		||||
    };// mBtnOk_OpenDialog_OnClickListener
 | 
			
		||||
 | 
			
		||||
@@ -1957,7 +1907,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
     * FRAGMENT LISTENERS
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    /*
 | 
			
		||||
     * LISTVIEW HELPER
 | 
			
		||||
     */
 | 
			
		||||
@@ -1986,10 +1936,10 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                if (mIsSaveDialog)
 | 
			
		||||
                    doCheckSaveasFilenameAndFinish(BaseFileProviderUtils
 | 
			
		||||
                    checkSaveasFilenameAndFinish(BaseFileProviderUtils
 | 
			
		||||
                            .getFileName(cursor));
 | 
			
		||||
                else
 | 
			
		||||
                    doFinish(BaseFileProviderUtils.getUri(cursor));
 | 
			
		||||
                    finish(BaseFileProviderUtils.getUri(cursor));
 | 
			
		||||
            }// single tap to choose files
 | 
			
		||||
        }// onItemClick()
 | 
			
		||||
    };// mViewFilesOnItemClickListener
 | 
			
		||||
@@ -2009,7 +1959,7 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
                        && !mIsMultiSelection
 | 
			
		||||
                        && BaseFileProviderUtils.isDirectory(cursor)
 | 
			
		||||
                        && (BaseFile.FILTER_DIRECTORIES_ONLY == mFilterMode || BaseFile.FILTER_FILES_AND_DIRECTORIES == mFilterMode)) {
 | 
			
		||||
                    doFinish(BaseFileProviderUtils.getUri(cursor));
 | 
			
		||||
                    finish(BaseFileProviderUtils.getUri(cursor));
 | 
			
		||||
                }
 | 
			
		||||
            }// single tap to choose files
 | 
			
		||||
 | 
			
		||||
@@ -2020,22 +1970,119 @@ public class FragmentFiles extends Fragment implements
 | 
			
		||||
        }// onItemLongClick()
 | 
			
		||||
    };// mViewFilesOnItemLongClickListener
 | 
			
		||||
 | 
			
		||||
    private final BaseFileAdapter.OnBuildOptionsMenuListener mOnBuildOptionsMenuListener = new BaseFileAdapter.OnBuildOptionsMenuListener() {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onBuildOptionsMenu(View view, Cursor cursor) {
 | 
			
		||||
            if (!BaseFileProviderUtils.fileCanRead(cursor)
 | 
			
		||||
                    || !BaseFileProviderUtils.isDirectory(cursor))
 | 
			
		||||
                return;
 | 
			
		||||
    /**
 | 
			
		||||
     * We use a {@link LoadingDialog} to avoid of
 | 
			
		||||
     * {@code NetworkOnMainThreadException}.
 | 
			
		||||
     */
 | 
			
		||||
    private LoadingDialog<Void, Void, Integer> mFileSelector;
 | 
			
		||||
 | 
			
		||||
            final Uri uri = BaseFileProviderUtils.getUri(cursor);
 | 
			
		||||
            final String name = BaseFileProviderUtils.getFileName(cursor);
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new {@link #mFileSelector} to select appropriate file after
 | 
			
		||||
     * loading a folder's content. It's either the parent path of last path, or
 | 
			
		||||
     * the file provided by key {@link FileChooserActivity#EXTRA_SELECT_FILE}.
 | 
			
		||||
     * Note that this also cancels previous selector if there is such one.
 | 
			
		||||
     */
 | 
			
		||||
    private void createFileSelector() {
 | 
			
		||||
        if (mFileSelector != null)
 | 
			
		||||
            mFileSelector.cancel(true);
 | 
			
		||||
 | 
			
		||||
        }// onBuildOptionsMenu()
 | 
			
		||||
        mFileSelector = new LoadingDialog<Void, Void, Integer>(getActivity(),
 | 
			
		||||
                R.string.afc_msg_loading, true) {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            protected Integer doInBackground(Void... params) {
 | 
			
		||||
                final Cursor cursor = mFileAdapter.getCursor();
 | 
			
		||||
                if (cursor == null || cursor.isClosed())
 | 
			
		||||
                    return -1;
 | 
			
		||||
 | 
			
		||||
                final Uri selectedFile = (Uri) getArguments().getParcelable(
 | 
			
		||||
                        FileChooserActivity.EXTRA_SELECT_FILE);
 | 
			
		||||
                final int colUri = cursor.getColumnIndex(BaseFile.COLUMN_URI);
 | 
			
		||||
                if (selectedFile != null)
 | 
			
		||||
                    getArguments()
 | 
			
		||||
                            .remove(FileChooserActivity.EXTRA_SELECT_FILE);
 | 
			
		||||
 | 
			
		||||
                int shouldBeSelectedIdx = -1;
 | 
			
		||||
                final Uri uri = selectedFile != null ? selectedFile
 | 
			
		||||
                        : getLastLocation();
 | 
			
		||||
                if (uri == null
 | 
			
		||||
                        || !BaseFileProviderUtils
 | 
			
		||||
                                .fileExists(getActivity(), uri))
 | 
			
		||||
                    return -1;
 | 
			
		||||
 | 
			
		||||
                final String fileName = BaseFileProviderUtils.getFileName(
 | 
			
		||||
                        getActivity(), uri);
 | 
			
		||||
                if (fileName == null)
 | 
			
		||||
                    return -1;
 | 
			
		||||
 | 
			
		||||
                Uri parentUri = BaseFileProviderUtils.getParentFile(
 | 
			
		||||
                        getActivity(), uri);
 | 
			
		||||
                if ((uri == getLastLocation()
 | 
			
		||||
                        && !getCurrentLocation().equals(getLastLocation()) && BaseFileProviderUtils
 | 
			
		||||
                            .isAncestorOf(getActivity(), getCurrentLocation(),
 | 
			
		||||
                                    uri))
 | 
			
		||||
                        || getCurrentLocation().equals(parentUri)) {
 | 
			
		||||
                    if (cursor.moveToFirst()) {
 | 
			
		||||
                        while (!cursor.isLast()) {
 | 
			
		||||
                            if (isCancelled())
 | 
			
		||||
                                return -1;
 | 
			
		||||
 | 
			
		||||
                            Uri subUri = Uri.parse(cursor.getString(colUri));
 | 
			
		||||
                            if (uri == getLastLocation()) {
 | 
			
		||||
                                if (cursor.getInt(cursor
 | 
			
		||||
                                        .getColumnIndex(BaseFile.COLUMN_TYPE)) == BaseFile.FILE_TYPE_DIRECTORY) {
 | 
			
		||||
                                    if (subUri.equals(uri)
 | 
			
		||||
                                            || BaseFileProviderUtils
 | 
			
		||||
                                                    .isAncestorOf(
 | 
			
		||||
                                                            getActivity(),
 | 
			
		||||
                                                            subUri, uri)) {
 | 
			
		||||
                                        shouldBeSelectedIdx = Math.max(0,
 | 
			
		||||
                                                cursor.getPosition() - 2);
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            } else {
 | 
			
		||||
                                if (uri.equals(subUri)) {
 | 
			
		||||
                                    shouldBeSelectedIdx = Math.max(0,
 | 
			
		||||
                                            cursor.getPosition() - 2);
 | 
			
		||||
                                    break;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            cursor.moveToNext();
 | 
			
		||||
                        }// while
 | 
			
		||||
                    }// if
 | 
			
		||||
                }// if
 | 
			
		||||
 | 
			
		||||
                return shouldBeSelectedIdx;
 | 
			
		||||
            }// doInBackground()
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            protected void onPostExecute(final Integer result) {
 | 
			
		||||
                super.onPostExecute(result);
 | 
			
		||||
 | 
			
		||||
                if (isCancelled() || mFileAdapter.isEmpty())
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                /*
 | 
			
		||||
                 * Use a Runnable to make sure this works. Because if the list
 | 
			
		||||
                 * view is handling data, this might not work.
 | 
			
		||||
                 */
 | 
			
		||||
                mViewFiles.post(new Runnable() {
 | 
			
		||||
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void run() {
 | 
			
		||||
                        if (result >= 0 && result < mFileAdapter.getCount())
 | 
			
		||||
                            mViewFiles.setSelection(result);
 | 
			
		||||
                        else if (!mFileAdapter.isEmpty())
 | 
			
		||||
                            mViewFiles.setSelection(0);
 | 
			
		||||
                    }// run()
 | 
			
		||||
                });
 | 
			
		||||
            }// onPostExecute()
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        mFileSelector.execute();
 | 
			
		||||
    }// createFileSelector()
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void onBuildAdvancedOptionsMenu(View view, Cursor cursor) {
 | 
			
		||||
            // TODO Auto-generated method stub
 | 
			
		||||
        }// onBuildAdvancedOptionsMenu()
 | 
			
		||||
    };// mOnBuildOptionsMenuListener
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
 | 
			
		||||
package group.pals.android.lib.ui.filechooser.prefs;
 | 
			
		||||
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.Sys;
 | 
			
		||||
import android.annotation.TargetApi;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.SharedPreferences;
 | 
			
		||||
@@ -14,11 +15,10 @@ import android.os.Build;
 | 
			
		||||
import android.preference.PreferenceActivity;
 | 
			
		||||
import android.preference.PreferenceFragment;
 | 
			
		||||
import android.preference.PreferenceManager;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convenient class for working with preferences.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Hai Bison
 | 
			
		||||
 * @since v4.3 beta
 | 
			
		||||
 */
 | 
			
		||||
@@ -26,60 +26,58 @@ public class Prefs {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This unique ID is used for storing preferences.
 | 
			
		||||
     *
 | 
			
		||||
     * 
 | 
			
		||||
     * @since v4.9 beta
 | 
			
		||||
     */
 | 
			
		||||
    public static final String UID = "9795e88b-2ab4-4b81-a548-409091a1e0c6";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates global preference filename of this library.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context the context.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return the global preference filename.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String genPreferenceFilename(Context context) {
 | 
			
		||||
        return String.format("%s_%s", context.getString(R.string.afc_lib_name),
 | 
			
		||||
                UID);
 | 
			
		||||
    public static final String genPreferenceFilename() {
 | 
			
		||||
        return String.format("%s_%s", Sys.LIB_NAME, UID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates global database filename.
 | 
			
		||||
     *
 | 
			
		||||
     * @param context the context.
 | 
			
		||||
     * @param name    the database filename.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param name
 | 
			
		||||
     *            the database filename.
 | 
			
		||||
     * @return the global database filename.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String genDatabaseFilename(Context context, String name) {
 | 
			
		||||
        return String.format("%s_%s_%s",
 | 
			
		||||
                context.getString(R.string.afc_lib_name), UID, name);
 | 
			
		||||
    public static final String genDatabaseFilename(String name) {
 | 
			
		||||
        return String.format("%s_%s_%s", Sys.LIB_NAME, UID, name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets new {@link SharedPreferences}
 | 
			
		||||
     *
 | 
			
		||||
     * @param context the context.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            the context.
 | 
			
		||||
     * @return {@link SharedPreferences}
 | 
			
		||||
     */
 | 
			
		||||
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 | 
			
		||||
    public static SharedPreferences p(Context context) {
 | 
			
		||||
        // always use application context
 | 
			
		||||
        return context.getApplicationContext().getSharedPreferences(
 | 
			
		||||
                genPreferenceFilename(context), Context.MODE_MULTI_PROCESS);
 | 
			
		||||
                genPreferenceFilename(), Context.MODE_MULTI_PROCESS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Setup {@code pm} to use global unique filename and global access mode.
 | 
			
		||||
     * You must use this method if you let the user change preferences via UI
 | 
			
		||||
     * (such as {@link PreferenceActivity}, {@link PreferenceFragment}...).
 | 
			
		||||
     *
 | 
			
		||||
     * @param context the context.
 | 
			
		||||
     * @param pm      {@link PreferenceManager}.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param pm
 | 
			
		||||
     *            {@link PreferenceManager}.
 | 
			
		||||
     * @since v4.9 beta
 | 
			
		||||
     */
 | 
			
		||||
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 | 
			
		||||
    public static void setupPreferenceManager(Context context,
 | 
			
		||||
                                              PreferenceManager pm) {
 | 
			
		||||
    public static void setupPreferenceManager(PreferenceManager pm) {
 | 
			
		||||
        pm.setSharedPreferencesMode(Context.MODE_MULTI_PROCESS);
 | 
			
		||||
        pm.setSharedPreferencesName(genPreferenceFilename(context));
 | 
			
		||||
        pm.setSharedPreferencesName(genPreferenceFilename());
 | 
			
		||||
    }// setupPreferenceManager()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,11 +16,14 @@ import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
 | 
			
		||||
import android.content.ContentResolver;
 | 
			
		||||
import android.content.ContentValues;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.database.Cursor;
 | 
			
		||||
import android.database.MatrixCursor;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utilities for base file provider.
 | 
			
		||||
@@ -115,11 +118,10 @@ public class BaseFileProviderUtils {
 | 
			
		||||
        String result = getProviderName(providerId);
 | 
			
		||||
 | 
			
		||||
        if (result == null) {
 | 
			
		||||
            Cursor cursor = context
 | 
			
		||||
                    .getContentResolver()
 | 
			
		||||
                    .query(BaseFile
 | 
			
		||||
                            .genContentUriApi(getProviderAuthority(providerId)),
 | 
			
		||||
                            null, null, null, null);
 | 
			
		||||
            Cursor cursor = queryInBackground(
 | 
			
		||||
                    context,
 | 
			
		||||
                    BaseFile.genContentUriApi(getProviderAuthority(providerId)),
 | 
			
		||||
                    null, null, null, null);
 | 
			
		||||
            if (cursor == null)
 | 
			
		||||
                return null;
 | 
			
		||||
 | 
			
		||||
@@ -165,11 +167,10 @@ public class BaseFileProviderUtils {
 | 
			
		||||
        int attr = MAP_PROVIDER_INFO.get(providerId).getInt(
 | 
			
		||||
                BaseFile.COLUMN_PROVIDER_ICON_ATTR);
 | 
			
		||||
        if (attr == 0) {
 | 
			
		||||
            Cursor cursor = context
 | 
			
		||||
                    .getContentResolver()
 | 
			
		||||
                    .query(BaseFile
 | 
			
		||||
                            .genContentUriApi(getProviderAuthority(providerId)),
 | 
			
		||||
                            null, null, null, null);
 | 
			
		||||
            Cursor cursor = queryInBackground(
 | 
			
		||||
                    context,
 | 
			
		||||
                    BaseFile.genContentUriApi(getProviderAuthority(providerId)),
 | 
			
		||||
                    null, null, null, null);
 | 
			
		||||
            if (cursor != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    if (cursor.moveToFirst()) {
 | 
			
		||||
@@ -249,8 +250,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     *         otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isDirectory(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "isDir? "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -285,8 +286,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return {@code true} if {@code uri} is a file, {@code false} otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isFile(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "isFile? "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -320,8 +321,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return the file name if {@code uri} is a file, {@code null} otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static String getFileName(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "getFileName "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
@@ -358,8 +359,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return the real URI of {@code uri}.
 | 
			
		||||
     */
 | 
			
		||||
    public static Uri getRealUri(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "getRealUri "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return null;
 | 
			
		||||
 | 
			
		||||
@@ -399,8 +400,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     *         {@link #FILE_TYPE_UNKNOWN}, {@link #FILE_TYPE_NOT_EXISTED}.
 | 
			
		||||
     */
 | 
			
		||||
    public static int getFileType(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "filetype? "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return BaseFile.FILE_TYPE_NOT_EXISTED;
 | 
			
		||||
 | 
			
		||||
@@ -448,8 +449,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return {@code true} or {@code false}.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean fileExists(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "exists? "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -473,8 +474,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return {@code true} or {@code false}.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean fileCanRead(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "canread? "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -510,8 +511,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return {@code true} or {@code false}.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean fileCanWrite(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(uri, null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    	//Log.d("AFC", "canWrite? "+uri.toString());
 | 
			
		||||
        Cursor cursor = queryInBackground(context, uri, null, null, null, null);
 | 
			
		||||
        if (cursor == null)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
@@ -547,7 +548,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return the default path, can be {@code null}.
 | 
			
		||||
     */
 | 
			
		||||
    public static Uri getDefaultPath(Context context, String authority) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(
 | 
			
		||||
        Cursor cursor = queryInBackground(
 | 
			
		||||
                context,
 | 
			
		||||
                BaseFile.genContentUriApi(authority).buildUpon()
 | 
			
		||||
                        .appendPath(BaseFile.CMD_GET_DEFAULT_PATH).build(),
 | 
			
		||||
                null, null, null, null);
 | 
			
		||||
@@ -574,7 +576,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     * @return the parent file if it exists, {@code null} otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static Uri getParentFile(Context context, Uri uri) {
 | 
			
		||||
        Cursor cursor = context.getContentResolver().query(
 | 
			
		||||
        Cursor cursor = queryInBackground(
 | 
			
		||||
                context,
 | 
			
		||||
                BaseFile.genContentUriApi(uri.getAuthority())
 | 
			
		||||
                        .buildUpon()
 | 
			
		||||
                        .appendPath(BaseFile.CMD_GET_PARENT)
 | 
			
		||||
@@ -607,7 +610,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     *         {@code false} otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isAncestorOf(Context context, Uri uri1, Uri uri2) {
 | 
			
		||||
        return context.getContentResolver().query(
 | 
			
		||||
        return queryInBackground(
 | 
			
		||||
                context,
 | 
			
		||||
                BaseFile.genContentUriApi(uri1.getAuthority())
 | 
			
		||||
                        .buildUpon()
 | 
			
		||||
                        .appendPath(BaseFile.CMD_IS_ANCESTOR_OF)
 | 
			
		||||
@@ -629,7 +633,8 @@ public class BaseFileProviderUtils {
 | 
			
		||||
     *            the task ID.
 | 
			
		||||
     */
 | 
			
		||||
    public static void cancelTask(Context context, String authority, int taskId) {
 | 
			
		||||
        context.getContentResolver().query(
 | 
			
		||||
        queryInBackground(
 | 
			
		||||
                context,
 | 
			
		||||
                BaseFile.genContentUriApi(authority)
 | 
			
		||||
                        .buildUpon()
 | 
			
		||||
                        .appendPath(BaseFile.CMD_CANCEL)
 | 
			
		||||
@@ -637,4 +642,186 @@ public class BaseFileProviderUtils {
 | 
			
		||||
                                Integer.toString(taskId)).build(), null, null,
 | 
			
		||||
                null, null);
 | 
			
		||||
    }// cancelTask()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new background thread to delete given URI, waits for the thread
 | 
			
		||||
     * to finish (or be interrupted) and returns the result.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            the context.
 | 
			
		||||
     * @param uri
 | 
			
		||||
     *            the URI to delete, see
 | 
			
		||||
     *            {@link ContentResolver#delete(Uri, String, String[])} for more
 | 
			
		||||
     *            details.
 | 
			
		||||
     * @param where
 | 
			
		||||
     *            the {@code WHERE} clause, see
 | 
			
		||||
     *            {@link ContentResolver#delete(Uri, String, String[])} for more
 | 
			
		||||
     *            details.
 | 
			
		||||
     * @param selectionArgs
 | 
			
		||||
     *            the selection arguments, see
 | 
			
		||||
     *            {@link ContentResolver#delete(Uri, String, String[])} for more
 | 
			
		||||
     *            details.
 | 
			
		||||
     * @return the value returned from
 | 
			
		||||
     *         {@link ContentResolver#delete(Uri, String, String[])} , or
 | 
			
		||||
     *         {@code -1} if an error occurred.
 | 
			
		||||
     */
 | 
			
		||||
    public static int deleteInBackground(final Context context, final Uri uri,
 | 
			
		||||
            final String where, final String[] selectionArgs) {
 | 
			
		||||
        final int[] result = { 0 };
 | 
			
		||||
 | 
			
		||||
        Thread thread = new Thread() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                result[0] = context.getContentResolver().delete(uri, where,
 | 
			
		||||
                        selectionArgs);
 | 
			
		||||
            }// run()
 | 
			
		||||
        };
 | 
			
		||||
        thread.start();
 | 
			
		||||
        try {
 | 
			
		||||
            thread.join();
 | 
			
		||||
            return result[0];
 | 
			
		||||
        } catch (InterruptedException e) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }// deleteInBackground()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new background thread to insert values to given URI, waits for
 | 
			
		||||
     * the thread to finish (or be interrupted) and returns the result.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            the context.
 | 
			
		||||
     * @param uri
 | 
			
		||||
     *            the URI to insert values into, see
 | 
			
		||||
     *            {@link ContentResolver#insert(Uri, ContentValues)} for more
 | 
			
		||||
     *            details.
 | 
			
		||||
     * @param values
 | 
			
		||||
     *            the values to insert into, see
 | 
			
		||||
     *            {@link ContentResolver#insert(Uri, ContentValues)} for more
 | 
			
		||||
     *            details.
 | 
			
		||||
     * @return the URI returned from
 | 
			
		||||
     *         {@link ContentResolver#insert(Uri, ContentValues)}, or
 | 
			
		||||
     *         {@code null} if an error occurred.
 | 
			
		||||
     */
 | 
			
		||||
    public static Uri insertInBackground(final Context context, final Uri uri,
 | 
			
		||||
            final ContentValues values) {
 | 
			
		||||
        final Uri[] result = { null };
 | 
			
		||||
 | 
			
		||||
        Thread thread = new Thread() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                result[0] = context.getContentResolver().insert(uri, values);
 | 
			
		||||
            }// run()
 | 
			
		||||
        };
 | 
			
		||||
        thread.start();
 | 
			
		||||
        try {
 | 
			
		||||
            thread.join();
 | 
			
		||||
            return result[0];
 | 
			
		||||
        } catch (InterruptedException e) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }// insertInBackground()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new background thread to query given URI, waits for the thread to
 | 
			
		||||
     * finish (or be interrupted) and returns the result.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            the context.
 | 
			
		||||
     * @param uri
 | 
			
		||||
     *            the URI to query, see
 | 
			
		||||
     *            {@link ContentResolver#query(Uri, String[], String, String[], String)}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param projection
 | 
			
		||||
     *            the projection, see
 | 
			
		||||
     *            {@link ContentResolver#query(Uri, String[], String, String[], String)}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param selection
 | 
			
		||||
     *            the selection, see
 | 
			
		||||
     *            {@link ContentResolver#query(Uri, String[], String, String[], String)}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param selectionArgs
 | 
			
		||||
     *            the selection arguments, see
 | 
			
		||||
     *            {@link ContentResolver#query(Uri, String[], String, String[], String)}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param sortOrder
 | 
			
		||||
     *            the sort order, see
 | 
			
		||||
     *            {@link ContentResolver#query(Uri, String[], String, String[], String)}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @return the cursor returned from
 | 
			
		||||
     *         {@link ContentResolver#query(Uri, String[], String, String[], String)}
 | 
			
		||||
     *         , or {@code null} if an error occurred.
 | 
			
		||||
     */
 | 
			
		||||
    public static Cursor queryInBackground(final Context context,
 | 
			
		||||
            final Uri uri, final String[] projection, final String selection,
 | 
			
		||||
            final String[] selectionArgs, final String sortOrder) {
 | 
			
		||||
        final Cursor[] result = { null };
 | 
			
		||||
 | 
			
		||||
        Thread thread = new Thread() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                result[0] = context.getContentResolver().query(uri, projection,
 | 
			
		||||
                        selection, selectionArgs, sortOrder);
 | 
			
		||||
            }// run()
 | 
			
		||||
        };
 | 
			
		||||
        thread.start();
 | 
			
		||||
        try {
 | 
			
		||||
            thread.join();
 | 
			
		||||
            return result[0];
 | 
			
		||||
        } catch (InterruptedException e) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }// queryInBackground()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new background thread to update given URI, waits for the thread
 | 
			
		||||
     * to finish (or be interrupted) and returns the result.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            the context.
 | 
			
		||||
     * @param uri
 | 
			
		||||
     *            the URI to update, see
 | 
			
		||||
     *            {@link ContentResolver#update(Uri, ContentValues, String, String[])}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param values
 | 
			
		||||
     *            the values to update, see
 | 
			
		||||
     *            {@link ContentResolver#update(Uri, ContentValues, String, String[])}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param where
 | 
			
		||||
     *            the {@code WHERE} clause, see
 | 
			
		||||
     *            {@link ContentResolver#update(Uri, ContentValues, String, String[])}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @param selectionArgs
 | 
			
		||||
     *            the selection arguments, see
 | 
			
		||||
     *            {@link ContentResolver#update(Uri, ContentValues, String, String[])}
 | 
			
		||||
     *            for more details.
 | 
			
		||||
     * @return the value returned from
 | 
			
		||||
     *         {@link ContentResolver#update(Uri, ContentValues, String, String[])}
 | 
			
		||||
     *         , or {@code -1} if an error occurred.
 | 
			
		||||
     */
 | 
			
		||||
    public static int updateInBackground(final Context context, final Uri uri,
 | 
			
		||||
            final ContentValues values, final String where,
 | 
			
		||||
            final String[] selectionArgs) {
 | 
			
		||||
        final int[] result = { 0 };
 | 
			
		||||
 | 
			
		||||
        Thread thread = new Thread() {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
                result[0] = context.getContentResolver().update(uri, values,
 | 
			
		||||
                        where, selectionArgs);
 | 
			
		||||
            }// run()
 | 
			
		||||
        };
 | 
			
		||||
        thread.start();
 | 
			
		||||
        try {
 | 
			
		||||
            thread.join();
 | 
			
		||||
            return result[0];
 | 
			
		||||
        } catch (InterruptedException e) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }// updateInBackground()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,16 +7,16 @@
 | 
			
		||||
 | 
			
		||||
package group.pals.android.lib.ui.filechooser.providers.history;
 | 
			
		||||
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.prefs.Prefs;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.providers.DbUtils;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.database.sqlite.SQLiteDatabase;
 | 
			
		||||
import android.database.sqlite.SQLiteOpenHelper;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.prefs.Prefs;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.providers.DbUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SQLite helper for history database.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Hai Bison
 | 
			
		||||
 * @since v5.1 beta
 | 
			
		||||
 */
 | 
			
		||||
@@ -38,8 +38,8 @@ public class HistoryHelper extends SQLiteOpenHelper {
 | 
			
		||||
 | 
			
		||||
    public HistoryHelper(Context context) {
 | 
			
		||||
        // always use application context
 | 
			
		||||
        super(context.getApplicationContext(), Prefs.genDatabaseFilename(
 | 
			
		||||
                context, DB_FILENAME), null, DB_VERSION);
 | 
			
		||||
        super(context.getApplicationContext(), Prefs
 | 
			
		||||
                .genDatabaseFilename(DB_FILENAME), null, DB_VERSION);
 | 
			
		||||
    }// HistoryHelper()
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -54,4 +54,5 @@ public class HistoryHelper extends SQLiteOpenHelper {
 | 
			
		||||
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }// onUpgrade()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,6 @@ package group.pals.android.lib.ui.filechooser.providers.history;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.BuildConfig;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.R;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.providers.DbUtils;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.utils.Utils;
 | 
			
		||||
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
@@ -35,8 +34,8 @@ public class HistoryProviderUtils {
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            {@link Context}.
 | 
			
		||||
     */
 | 
			
		||||
    public static void clearHistory(Context context) {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
    public static void doCleanupOutdatedHistoryItems(Context context) {
 | 
			
		||||
        if (BuildConfig.DEBUG)
 | 
			
		||||
            Log.d(CLASSNAME, "doCleanupCache()");
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
@@ -47,9 +46,9 @@ public class HistoryProviderUtils {
 | 
			
		||||
            final long validityInMillis = new Date().getTime()
 | 
			
		||||
                    - 0;
 | 
			
		||||
 | 
			
		||||
            if (Utils.doLog())
 | 
			
		||||
            if (BuildConfig.DEBUG)
 | 
			
		||||
                Log.d(CLASSNAME, String.format(
 | 
			
		||||
                        "clearHistory() - validity = %,d (%s)",
 | 
			
		||||
                        "doCleanupCache() - validity = %,d (%s)",
 | 
			
		||||
                        validityInMillis, new Date(validityInMillis)));
 | 
			
		||||
            context.getContentResolver().delete(
 | 
			
		||||
                    HistoryContract.genContentUri(context),
 | 
			
		||||
@@ -61,5 +60,6 @@ public class HistoryProviderUtils {
 | 
			
		||||
             * Currently we just ignore it.
 | 
			
		||||
             */
 | 
			
		||||
        }
 | 
			
		||||
    }// clearHistory()
 | 
			
		||||
    }// doCleanupOutdatedHistoryItems()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -303,7 +303,6 @@ public class LocalFileProvider extends BaseFileProvider {
 | 
			
		||||
            newRow.add(type);
 | 
			
		||||
            newRow.add(file.lastModified());
 | 
			
		||||
            newRow.add(FileUtils.getResIcon(type, file.getName()));
 | 
			
		||||
 | 
			
		||||
        } else if (BaseFile.CMD_SHUTDOWN.equals(uri.getLastPathSegment())) {
 | 
			
		||||
            /*
 | 
			
		||||
             * TODO Stop all tasks. If the activity call this command in
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,7 @@
 | 
			
		||||
 | 
			
		||||
package group.pals.android.lib.ui.filechooser.utils;
 | 
			
		||||
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.R;
 | 
			
		||||
import android.app.Dialog;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
@@ -15,28 +16,27 @@ import android.view.ContextThemeWrapper;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.view.Window;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import group.pals.android.lib.ui.filechooser.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Something funny :-)
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Hai Bison
 | 
			
		||||
 */
 | 
			
		||||
public class E {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Shows it!
 | 
			
		||||
     *
 | 
			
		||||
     * @param context {@link Context}
 | 
			
		||||
     * 
 | 
			
		||||
     * @param context
 | 
			
		||||
     *            {@link Context}
 | 
			
		||||
     */
 | 
			
		||||
    public static void show(Context context) {
 | 
			
		||||
        String msg = null;
 | 
			
		||||
        try {
 | 
			
		||||
            msg = String.format("Hi  :-)\n\n" + "%s %s\n"
 | 
			
		||||
            msg = String.format("Hi  :-)\n\n" + "%s v%s\n"
 | 
			
		||||
                    + "…by Hai Bison Apps\n\n" + "http://www.haibison.com\n\n"
 | 
			
		||||
                    + "Hope you enjoy this library.",
 | 
			
		||||
                    context.getString(R.string.afc_lib_name),
 | 
			
		||||
                    context.getString(R.string.afc_lib_version_name));
 | 
			
		||||
                    + "Hope you enjoy this library.", Sys.LIB_NAME,
 | 
			
		||||
                    Sys.LIB_VERSION_NAME);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            msg = "Oops… You've found a broken Easter egg, try again later  :-(";
 | 
			
		||||
        }
 | 
			
		||||
@@ -70,4 +70,5 @@ public class E {
 | 
			
		||||
        dialog.setContentView(textView);
 | 
			
		||||
        dialog.show();
 | 
			
		||||
    }// show()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
 *    Copyright (c) 2012 Hai Bison
 | 
			
		||||
 *
 | 
			
		||||
 *    See the file LICENSE at the root directory of this project for copying
 | 
			
		||||
 *    permission.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package group.pals.android.lib.ui.filechooser.utils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * System variables.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author Hai Bison
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
public class Sys {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The library name.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String LIB_NAME = "android-filechooser";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The library version name.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String LIB_VERSION_NAME = "5.4.3 beta";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The library version code.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int LIB_VERSION_CODE = 54;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -35,7 +35,7 @@ public class Utils {
 | 
			
		||||
    
 | 
			
		||||
    public static boolean doLog()
 | 
			
		||||
    {
 | 
			
		||||
    	return false;
 | 
			
		||||
    	return true;
 | 
			
		||||
    	//return BuildConfig.DEBUG; //not working with Mono for Android
 | 
			
		||||
    	
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,8 @@ import android.util.Log;
 | 
			
		||||
 * @author Hai Bison
 | 
			
		||||
 * @since v2.1 alpha
 | 
			
		||||
 */
 | 
			
		||||
public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
public abstract class LoadingDialog<Params, Progress, Result> extends
 | 
			
		||||
        AsyncTask<Params, Progress, Result> {
 | 
			
		||||
 | 
			
		||||
    public static final String CLASSNAME = LoadingDialog.class.getName();
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +63,7 @@ public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }// LoadingDialog
 | 
			
		||||
    }// LoadingDialog()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates new {@link LoadingDialog}
 | 
			
		||||
@@ -76,12 +77,13 @@ public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
     */
 | 
			
		||||
    public LoadingDialog(Context context, int msgId, boolean cancelable) {
 | 
			
		||||
        this(context, context.getString(msgId), cancelable);
 | 
			
		||||
    }
 | 
			
		||||
    }// LoadingDialog()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * If you override this method, you must call {@code super.onPreExecute()}
 | 
			
		||||
     * at very first of the method.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onPreExecute() {
 | 
			
		||||
        new Handler().postDelayed(new Runnable() {
 | 
			
		||||
 | 
			
		||||
@@ -107,7 +109,8 @@ public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
     * If you override this method, you must call
 | 
			
		||||
     * {@code super.onPostExecute(result)} at the entry point of the method.
 | 
			
		||||
     */
 | 
			
		||||
    protected void onPostExecute(Object result) {
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onPostExecute(Result result) {
 | 
			
		||||
        doFinish();
 | 
			
		||||
    }// onPostExecute()
 | 
			
		||||
 | 
			
		||||
@@ -115,6 +118,7 @@ public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
     * If you override this method, you must call {@code super.onCancelled()} at
 | 
			
		||||
     * the entry point of the method.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected void onCancelled() {
 | 
			
		||||
        doFinish();
 | 
			
		||||
        super.onCancelled();
 | 
			
		||||
@@ -148,9 +152,10 @@ public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
     * 
 | 
			
		||||
     * @param delayTime
 | 
			
		||||
     *            the delay time to set
 | 
			
		||||
     * @return {@link LoadingDialog}
 | 
			
		||||
     * @return the instance of this dialog, for chaining multiple calls into a
 | 
			
		||||
     *         single statement.
 | 
			
		||||
     */
 | 
			
		||||
    public LoadingDialog setDelayTime(int delayTime) {
 | 
			
		||||
    public LoadingDialog<Params, Progress, Result> setDelayTime(int delayTime) {
 | 
			
		||||
        mDelayTime = delayTime >= 0 ? delayTime : 0;
 | 
			
		||||
        return this;
 | 
			
		||||
    }// setDelayTime()
 | 
			
		||||
@@ -174,4 +179,5 @@ public abstract class LoadingDialog extends AsyncTask<Void, Void, Object> {
 | 
			
		||||
    protected Throwable getLastException() {
 | 
			
		||||
        return mLastException;
 | 
			
		||||
    }// getLastException()
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,11 @@ import java.io.File;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.Comparator;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.CancellationException;
 | 
			
		||||
import android.content.ContentValues;
 | 
			
		||||
import android.database.Cursor;
 | 
			
		||||
@@ -50,6 +54,12 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
     * Used for debugging or something...
 | 
			
		||||
     */
 | 
			
		||||
    private static final String CLASSNAME = Kp2aFileProvider.class.getName();
 | 
			
		||||
    
 | 
			
		||||
    //cache for FileEntry objects to reduce network traffic
 | 
			
		||||
    private HashMap<String, FileEntry> fileEntryMap = new HashMap<String, FileEntry>();
 | 
			
		||||
    //during write operations it is not desired to put entries to the cache. This set indicates which 
 | 
			
		||||
    //files cannot be cached currently:
 | 
			
		||||
    private Set<String> cacheBlockedFiles = new HashSet<String>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -75,12 +85,16 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
            Log.d(CLASSNAME, "delete() >> " + uri);
 | 
			
		||||
 | 
			
		||||
        int count = 0;
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        switch (URI_MATCHER.match(uri)) {
 | 
			
		||||
        case URI_FILE: {
 | 
			
		||||
            boolean isRecursive = ProviderUtils.getBooleanQueryParam(uri,
 | 
			
		||||
                    BaseFile.PARAM_RECURSIVE, true);
 | 
			
		||||
            String filename = extractFile(uri);
 | 
			
		||||
            removeFromCache(filename, isRecursive);
 | 
			
		||||
            blockFromCache(filename);
 | 
			
		||||
            if (deletePath(filename, isRecursive))
 | 
			
		||||
            {
 | 
			
		||||
	            getContext()
 | 
			
		||||
@@ -96,7 +110,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
	                                            .build(), null);
 | 
			
		||||
	            count = 1; //success
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            blockFromCache(filename);
 | 
			
		||||
            break;// URI_FILE
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -113,6 +127,10 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
    public Uri insert(Uri uri, ContentValues values) {
 | 
			
		||||
        if (Utils.doLog())
 | 
			
		||||
@@ -247,7 +265,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
	                return null;
 | 
			
		||||
	            }
 | 
			
		||||
	            
 | 
			
		||||
	            String fname = getName(parentPath);
 | 
			
		||||
	            String fname = getFilenameFromPath(parentPath);
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	            matrixCursor = BaseFileProviderUtils.newBaseFileCursor();
 | 
			
		||||
@@ -291,7 +309,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
        return matrixCursor;
 | 
			
		||||
    }// doAnswerApiCommand()
 | 
			
		||||
 | 
			
		||||
    private String getName(String path) {
 | 
			
		||||
    protected String getFilenameFromPath(String path) {
 | 
			
		||||
    	path = removeTrailingSlash(path);
 | 
			
		||||
    	int lastSlashPos = path.lastIndexOf("/");
 | 
			
		||||
    	//if path is root, return its name. empty is ok
 | 
			
		||||
@@ -365,6 +383,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
                        break;
 | 
			
		||||
 | 
			
		||||
                    FileEntry f = files.get(i);
 | 
			
		||||
                    updateFileEntryCache(f);
 | 
			
		||||
                    
 | 
			
		||||
                    if (Utils.doLog())
 | 
			
		||||
                    	Log.d(CLASSNAME, "listing " + f.path +" for "+dirName);
 | 
			
		||||
@@ -396,9 +415,9 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
                                Boolean.toString(hasMoreFiles[0])).build()
 | 
			
		||||
                        .toString());
 | 
			
		||||
                newRow.add(dirName);
 | 
			
		||||
                newRow.add(getName(dirName));
 | 
			
		||||
                newRow.add(getFilenameFromPath(dirName));
 | 
			
		||||
                
 | 
			
		||||
                Log.d(CLASSNAME, "Returning name " + getName(dirName)+" for " +dirName);
 | 
			
		||||
                Log.d(CLASSNAME, "Returning name " + getFilenameFromPath(dirName)+" for " +dirName);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -420,6 +439,8 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
        return matrixCursor;
 | 
			
		||||
    }// doListFiles()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	private RowBuilder addFileInfo(MatrixCursor matrixCursor, int id,
 | 
			
		||||
			FileEntry f) {
 | 
			
		||||
		int type = !f.isDirectory ? BaseFile.FILE_TYPE_FILE : BaseFile.FILE_TYPE_DIRECTORY;
 | 
			
		||||
@@ -431,7 +452,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
		        .buildUpon().appendPath(f.path)
 | 
			
		||||
		        .build().toString());
 | 
			
		||||
		newRow.add(f.path);
 | 
			
		||||
		newRow.add(getName(f.path));
 | 
			
		||||
		newRow.add(getFilenameFromPath(f.path));
 | 
			
		||||
		newRow.add(f.canRead ? 1 : 0);
 | 
			
		||||
		newRow.add(f.canWrite ? 1 : 0);
 | 
			
		||||
		newRow.add(f.sizeInBytes);
 | 
			
		||||
@@ -440,7 +461,7 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
			newRow.add(f.lastModifiedTime);
 | 
			
		||||
		else 
 | 
			
		||||
			newRow.add(null);
 | 
			
		||||
		newRow.add(FileUtils.getResIcon(type, getName(f.path)));
 | 
			
		||||
		newRow.add(FileUtils.getResIcon(type, getFilenameFromPath(f.path)));
 | 
			
		||||
		return newRow;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -458,9 +479,9 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
 | 
			
		||||
        String filename = extractFile(uri);
 | 
			
		||||
        
 | 
			
		||||
        FileEntry f = getFileEntry(filename);
 | 
			
		||||
        FileEntry f = getFileEntryCached(filename);
 | 
			
		||||
        if (f == null)
 | 
			
		||||
        	 addDeletedFileInfo(matrixCursor, filename);
 | 
			
		||||
        	addDeletedFileInfo(matrixCursor, filename);
 | 
			
		||||
        else	
 | 
			
		||||
        	addFileInfo(matrixCursor, 0, f);
 | 
			
		||||
        
 | 
			
		||||
@@ -469,8 +490,60 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
    //puts the file entry in the cache for later reuse with retrieveFileInfo
 | 
			
		||||
	private void updateFileEntryCache(FileEntry f) {
 | 
			
		||||
		fileEntryMap.put(f.path, f);
 | 
			
		||||
	}
 | 
			
		||||
	//removes the file entry from the cache (if cached). Should be called whenever the file changes
 | 
			
		||||
	private void removeFromCache(String filename, boolean recursive) {
 | 
			
		||||
		fileEntryMap.remove(filename);
 | 
			
		||||
		
 | 
			
		||||
		if (recursive)
 | 
			
		||||
		{
 | 
			
		||||
			Set<String> keys = fileEntryMap.keySet();
 | 
			
		||||
			for (String key: keys)
 | 
			
		||||
			{
 | 
			
		||||
				if (key.startsWith(key))
 | 
			
		||||
					fileEntryMap.remove(key);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void blockFromCache(String filename) {
 | 
			
		||||
		cacheBlockedFiles.add(filename);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void unblockFromCache(String filename) {
 | 
			
		||||
		cacheBlockedFiles.remove(filename);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private void addDeletedFileInfo(MatrixCursor matrixCursor, String filename) {
 | 
			
		||||
	//returns the file entry from the cache if present or queries the concrete provider method to return the file info
 | 
			
		||||
    private FileEntry getFileEntryCached(String filename) {
 | 
			
		||||
    	//check if enry is cached:
 | 
			
		||||
    	FileEntry cachedEntry = fileEntryMap.get(filename);
 | 
			
		||||
    	if (cachedEntry != null)
 | 
			
		||||
    	{
 | 
			
		||||
    		if (Utils.doLog())
 | 
			
		||||
    			Log.d(CLASSNAME, "getFileEntryCached: from cache. " + filename);
 | 
			
		||||
    		return cachedEntry;
 | 
			
		||||
    	}
 | 
			
		||||
    	
 | 
			
		||||
		if (Utils.doLog())
 | 
			
		||||
			Log.d(CLASSNAME, "getFileEntryCached: not in cache :-( " + filename);
 | 
			
		||||
 | 
			
		||||
    	
 | 
			
		||||
    	//it's not -> query the information.
 | 
			
		||||
		FileEntry newEntry = getFileEntry(filename);
 | 
			
		||||
		
 | 
			
		||||
		if (!cacheBlockedFiles.contains(filename))
 | 
			
		||||
			updateFileEntryCache(newEntry);
 | 
			
		||||
		
 | 
			
		||||
		return newEntry;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void addDeletedFileInfo(MatrixCursor matrixCursor, String filename) {
 | 
			
		||||
    	int type = BaseFile.FILE_TYPE_NOT_EXISTED;
 | 
			
		||||
    	RowBuilder newRow = matrixCursor.newRow();
 | 
			
		||||
		newRow.add(0);// _ID
 | 
			
		||||
@@ -480,13 +553,13 @@ public abstract class Kp2aFileProvider extends BaseFileProvider {
 | 
			
		||||
		        .buildUpon().appendPath(filename)
 | 
			
		||||
		        .build().toString());
 | 
			
		||||
		newRow.add(filename);
 | 
			
		||||
		newRow.add(getName(filename));
 | 
			
		||||
		newRow.add(getFilenameFromPath(filename));
 | 
			
		||||
		newRow.add(0);
 | 
			
		||||
		newRow.add(0);
 | 
			
		||||
		newRow.add(0);
 | 
			
		||||
		newRow.add(type);
 | 
			
		||||
		newRow.add(null);
 | 
			
		||||
		newRow.add(FileUtils.getResIcon(type, getName(filename)));
 | 
			
		||||
		newRow.add(FileUtils.getResIcon(type, getFilenameFromPath(filename)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6237
									
								
								src/keepass2android/Resources/Resource.designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6237
									
								
								src/keepass2android/Resources/Resource.designer.cs
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user