package org.openintents.filemanager.lists;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.Toast;
import org.openintents.filemanager.FileManagerApplication;
import org.openintents.filemanager.PreferenceActivity;
import org.openintents.filemanager.R;
import org.openintents.filemanager.compatibility.ActionbarRefreshHelper;
import org.openintents.filemanager.compatibility.FileMultiChoiceModeHelper;
import org.openintents.filemanager.dialogs.CreateDirectoryDialog;
import org.openintents.filemanager.files.FileHolder;
import org.openintents.filemanager.util.CopyHelper;
import org.openintents.filemanager.util.FileUtils;
import org.openintents.filemanager.util.MenuUtils;
import org.openintents.filemanager.view.PathBar;
import org.openintents.filemanager.view.PathBar.Mode;
import org.openintents.filemanager.view.PathBar.OnDirectoryChangedListener;
import org.openintents.intents.FileManagerIntents;
import java.io.File;
import java.io.IOException;
/**
* A file list fragment that supports context menu and CAB selection.
*
* @author George Venios
*/
public class SimpleFileListFragment extends FileListFragment {
private static final String INSTANCE_STATE_PATHBAR_MODE = "pathbar_mode";
protected static final int REQUEST_CODE_MULTISELECT = 2;
private PathBar mPathBar;
private boolean mActionsEnabled = true;
private int mSingleSelectionMenu = R.menu.context;
private int mMultiSelectionMenu = R.menu.multiselect;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.filelist_browse, null);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Pathbar init.
mPathBar = (PathBar) view.findViewById(R.id.pathbar);
// Handle mPath differently if we restore state or just initially create the view.
if (savedInstanceState == null)
mPathBar.setInitialDirectory(getPath());
else
mPathBar.cd(getPath());
mPathBar.setOnDirectoryChangedListener(new OnDirectoryChangedListener() {
@Override
public void directoryChanged(File newCurrentDir) {
Context activity = getActivity();
if (activity == null) {
return;
}
open(new FileHolder(newCurrentDir, activity));
}
});
if (savedInstanceState != null && savedInstanceState.getBoolean(INSTANCE_STATE_PATHBAR_MODE))
mPathBar.switchToManualInput();
// Removed else clause as the other mode is the default. It seems faster this way on Nexus S.
initContextualActions();
}
/**
* Override this to handle initialization of list item long clicks.
*/
void initContextualActions() {
if (mActionsEnabled) {
if (VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
registerForContextMenu(getListView());
} else {
FileMultiChoiceModeHelper multiChoiceModeHelper = new FileMultiChoiceModeHelper(mSingleSelectionMenu, mMultiSelectionMenu);
multiChoiceModeHelper.setListView(getListView());
multiChoiceModeHelper.setPathBar(mPathBar);
multiChoiceModeHelper.setContext(this);
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
}
setHasOptionsMenu(true);
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo) {
MenuInflater inflater = new MenuInflater(getActivity());
// Obtain context menu info
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
e.printStackTrace();
return;
}
MenuUtils.fillContextMenu((FileHolder) mAdapter.getItem(info.position), menu, mSingleSelectionMenu, inflater, getActivity());
}
@Override
public boolean onContextItemSelected(MenuItem item) {
FileHolder fh = (FileHolder) mAdapter.getItem(((AdapterContextMenuInfo) item.getMenuInfo()).position);
return MenuUtils.handleSingleSelectionAction(this, item, fh, getActivity());
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
FileHolder item = (FileHolder) mAdapter.getItem(position);
openInformingPathBar(item);
}
/**
* Use this to open files and folders using this fragment. Appropriately handles pathbar updates.
*
* @param item The dir/file to open.
*/
public void openInformingPathBar(FileHolder item) {
if (mPathBar == null)
open(item);
else
mPathBar.cd(item.getFile());
}
/**
* Point this Fragment to show the contents of the passed file.
*
* @param f If same as current, does nothing.
*/
private void open(FileHolder f) {
if (!f.getFile().exists())
return;
if (f.getFile().isDirectory()) {
openDir(f);
} else if (f.getFile().isFile()) {
openFile(f);
}
}
private void openFile(FileHolder fileholder) {
FileUtils.openFile(fileholder, getActivity());
}
/**
* Attempts to open a directory for browsing.
* Override this to handle folder click behavior.
*
* @param fileholder The holder of the directory to open.
*/
protected void openDir(FileHolder fileholder) {
// Avoid unnecessary attempts to load.
if (fileholder.getFile().getAbsolutePath().equals(getPath()))
return;
setPath(fileholder.getFile());
refresh();
}
protected void setLongClickMenus(int singleSelectionResource, int multiSelectionResource) {
mSingleSelectionMenu = singleSelectionResource;
mMultiSelectionMenu = multiSelectionResource;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.simple_file_list, menu);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
// We only know about ".nomedia" once scanning is finished.
boolean showMediaScanMenuItem = PreferenceActivity.getMediaScanFromPreference(getActivity());
if (!mScanner.isRunning() && showMediaScanMenuItem) {
menu.findItem(R.id.menu_media_scan_include).setVisible(mScanner.getNoMedia());
menu.findItem(R.id.menu_media_scan_exclude).setVisible(!mScanner.getNoMedia());
} else {
menu.findItem(R.id.menu_media_scan_include).setVisible(false);
menu.findItem(R.id.menu_media_scan_exclude).setVisible(false);
}
if (((FileManagerApplication) getActivity().getApplication()).getCopyHelper().canPaste()) {
menu.findItem(R.id.menu_paste).setVisible(true);
} else {
menu.findItem(R.id.menu_paste).setVisible(false);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_create_folder:
CreateDirectoryDialog dialog = new CreateDirectoryDialog();
dialog.setTargetFragment(this, 0);
Bundle args = new Bundle();
args.putString(FileManagerIntents.EXTRA_DIR_PATH, getPath());
dialog.setArguments(args);
dialog.show(getActivity().getSupportFragmentManager(), CreateDirectoryDialog.class.getName());
return true;
case R.id.menu_media_scan_include:
includeInMediaScan();
return true;
case R.id.menu_media_scan_exclude:
excludeFromMediaScan();
return true;
case R.id.menu_paste:
if (((FileManagerApplication) getActivity().getApplication()).getCopyHelper().canPaste())
((FileManagerApplication) getActivity().getApplication()).getCopyHelper().paste(new File(getPath()), new CopyHelper.OnOperationFinishedListener() {
@Override
public void operationFinished(boolean success) {
refresh();
// Refresh options menu
if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB)
ActionbarRefreshHelper.activity_invalidateOptionsMenu(getActivity());
}
});
else
Toast.makeText(getActivity(), R.string.nothing_to_paste, Toast.LENGTH_LONG).show();
return true;
case R.id.menu_multiselect:
Intent intent = new Intent(FileManagerIntents.ACTION_MULTI_SELECT);
intent.putExtra(FileManagerIntents.EXTRA_DIR_PATH, getPath());
startActivityForResult(intent, REQUEST_CODE_MULTISELECT);
return true;
default:
return false;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Automatically refresh to display possible changes done through the multiselect fragment.
if (requestCode == REQUEST_CODE_MULTISELECT)
refresh();
super.onActivityResult(requestCode, resultCode, data);
}
private void includeInMediaScan() {
// Delete the .nomedia file.
File file = FileUtils.getFile(mPathBar.getCurrentDirectory(),
FileUtils.NOMEDIA_FILE_NAME);
if (file.delete()) {
Toast.makeText(getActivity(),
getString(R.string.media_scan_included), Toast.LENGTH_LONG)
.show();
} else {
// That didn't work.
Toast.makeText(getActivity(), getString(R.string.error_generic),
Toast.LENGTH_LONG).show();
}
refresh();
}
private void excludeFromMediaScan() {
// Create the .nomedia file.
File file = FileUtils.getFile(mPathBar.getCurrentDirectory(),
FileUtils.NOMEDIA_FILE_NAME);
try {
if (file.createNewFile()) {
Toast.makeText(getActivity(),
getString(R.string.media_scan_excluded),
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(),
getString(R.string.error_media_scan), Toast.LENGTH_LONG)
.show();
}
} catch (IOException e) {
// That didn't work.
Toast.makeText(getActivity(),
getString(R.string.error_generic) + e.getMessage(), Toast.LENGTH_LONG).show();
}
refresh();
}
public void browseToHome() {
mPathBar.cd(mPathBar.getInitialDirectory());
}
public boolean pressBack() {
return mPathBar.pressBack();
}
/**
* Set whether to show menu and selection actions. Must be set before OnViewCreated is called.
*
* @param enabled
*/
public void setActionsEnabled(boolean enabled) {
mActionsEnabled = enabled;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(INSTANCE_STATE_PATHBAR_MODE, mPathBar.getMode() == Mode.MANUAL_INPUT);
}
}