/*
IfExplorer, an open source file manager for the Android system.
Copyright (C) 2014 Kevin Lin
<chenbin.lin@tpv-tech.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sparseboolean.ifexplorer;
import gem.com.readystatesoftware.viewbadger.BadgeView;
import gem.kevin.innov.FilePathUrlManager;
import gem.kevin.task.FileOperationTask;
import gem.kevin.task.FileOperationTask.FileOperationOptions;
import gem.kevin.task.FileOperationTask.SearchOpTaskListener;
import gem.kevin.util.DataUtil;
import gem.kevin.util.FileUtil;
import gem.kevin.util.StorageUtil;
import gem.kevin.util.ThumbnailCreator;
import gem.kevin.util.ui.BunchToStackAnimation;
import gem.kevin.widget.ActionModeDraggableView;
import gem.kevin.widget.ActionModeDraggableView.DragContextInfo;
import gem.kevin.widget.ClipItemAdapter;
import gem.kevin.widget.DropAcceptable;
import gem.kevin.widget.DropableGridView;
import gem.kevin.widget.DropableListView;
import gem.kevin.widget.FileClip;
import gem.kevin.widget.OnDropDelegate;
import gem.kevin.widget.OpenDelegate;
import gem.kevin.widget.Openable;
import java.io.File;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.format.Formatter;
import android.text.format.Time;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.DragShadowBuilder;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.sparseboolean.ifexplorer.IfExplorer.MultiChoiceConsumeOptions;
import com.sparseboolean.ifexplorer.ui.ClipHistoryAdapter;
import com.sparseboolean.ifexplorer.ui.DeviceDataAdapter;
import com.sparseboolean.ifexplorer.ui.FavoriteDataAdapter;
import com.sparseboolean.ifexplorer.ui.FilePathNavigator;
import com.sparseboolean.ifexplorer.ui.DropableFilePathButton;
public class IfAppController implements FilePathUrlManager.FilePathObserver,
ActionModeDraggableView.DragProgressDelegate, OnDropDelegate,
OpenDelegate, BunchToStackAnimation.BunchAnimationListener,
FilePathNavigator.NavigationCallback, SearchOpTaskListener {
public interface DeviceDataListener {
public void onStorageDeviceItemChanged();
}
public class FileDataGridAdapter extends ArrayAdapter<FileItem> {
public FileDataGridAdapter() {
super(mContext, R.layout.file_griditem, new ArrayList<FileItem>());
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final FileItemViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.file_griditem, null);
viewHolder = new FileItemViewHolder();
viewHolder.nameTextView = (TextView) convertView
.findViewById(R.id.file_name);
viewHolder.icon = (ImageView) convertView
.findViewById(R.id.file_icon);
viewHolder.draggingView = (ImageView) convertView
.findViewById(R.id.dragging_view);
viewHolder.dragReadyView = (ImageView) convertView
.findViewById(R.id.drag_ready_view);
viewHolder.normalView = convertView
.findViewById(R.id.normal_view);
viewHolder.position = position;
convertView.setTag(viewHolder);
} else {
viewHolder = (FileItemViewHolder) convertView.getTag();
}
viewHolder.position = position;
AbsListView absListView = (AbsListView) parent;
FileItem fileItem = getItem(position);
// //////////////////////////////////////////////////////
fileItem.setConvertView(convertView);
fileItem.setPositionInAdapterList(position);
if (fileItem.isVisible()) {
convertView.setVisibility(View.VISIBLE);
} else {
convertView.setVisibility(View.GONE);
}
if ((Object) convertView instanceof ActionModeDraggableView) {
ActionModeDraggableView dragabbleView = (ActionModeDraggableView) convertView;
dragabbleView.setDragable(IfConfig.FILE_SUPPORT_DRAG);
final DragContextInfo dragInfo = new DragContextInfo();
dragInfo.data = fileItem;
dragInfo.parentView = absListView;
dragInfo.positionAsChild = position;
dragInfo.draggingView = viewHolder.draggingView;
dragInfo.dragReadyView = viewHolder.dragReadyView;
dragInfo.normalView = viewHolder.normalView;
dragabbleView.setDragContextInfo(dragInfo);
dragabbleView.setInActionMode(absListView
.isItemChecked(position));
dragabbleView.setDragDropDelegate(IfAppController.this);
dragabbleView.setOnDropDelegate(IfAppController.this);
dragabbleView.setOpenDelegate(IfAppController.this);
} else {
Log.i(TAG, "File grid items are not dragable!");
}
// ////////////////////////////////
// icon
Drawable iconDrawable = fileItem.getIconDrawable();
if (iconDrawable != null) {
viewHolder.icon.setImageDrawable(iconDrawable);
} else {
viewHolder.icon.setImageResource(fileItem.getIconResource());
}
// name
String name = fileItem.getName();
if (!name.contains(" ") && name.length() > 24) {
viewHolder.nameTextView.setText(name.substring(0, 21) + "...");
} else if (name.contains(" ") && name.length() > 22) {
viewHolder.nameTextView.setText(name.substring(0, 19) + "...");
} else {
viewHolder.nameTextView.setText(name);
}
return convertView;
}
}
public class FileDataListAdapter extends ArrayAdapter<FileItem> {
private String mSizeStr;
private static final String STR_NA = "N/A";
public FileDataListAdapter() {
super(mContext, R.layout.file_listitem, new ArrayList<FileItem>());
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final FileItemViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(
R.layout.file_listitem, null);
viewHolder = new FileItemViewHolder();
viewHolder.nameTextView = (TextView) convertView
.findViewById(R.id.file_name);
viewHolder.infoTextView = (TextView) convertView
.findViewById(R.id.file_info);
viewHolder.icon = (ImageView) convertView
.findViewById(R.id.file_icon);
viewHolder.draggingView = (ImageView) convertView
.findViewById(R.id.dragging_view);
viewHolder.dragReadyView = (ImageView) convertView
.findViewById(R.id.drag_ready_view);
viewHolder.normalView = convertView
.findViewById(R.id.normal_view);
viewHolder.selectModeMark = (CheckBox) convertView
.findViewById(R.id.file_selected);
viewHolder.position = position;
convertView.setTag(viewHolder);
} else {
viewHolder = (FileItemViewHolder) convertView.getTag();
}
viewHolder.position = position;
AbsListView absListView = (AbsListView) parent;
FileItem fileItem = getItem(position);
// //////////////////////////////////////////////////////
fileItem.setConvertView(convertView);
fileItem.setPositionInAdapterList(position);
if (fileItem.isVisible()) {
convertView.setVisibility(View.VISIBLE);
} else {
convertView.setVisibility(View.GONE);
}
if ((Object) convertView instanceof ActionModeDraggableView) {
ActionModeDraggableView dragabbleView = (ActionModeDraggableView) convertView;
dragabbleView.setDragable(IfConfig.FILE_SUPPORT_DRAG);
final DragContextInfo dragInfo = new DragContextInfo();
dragInfo.data = fileItem;
dragInfo.parentView = absListView;
dragInfo.positionAsChild = position;
dragInfo.draggingView = viewHolder.draggingView;
dragInfo.dragReadyView = viewHolder.dragReadyView;
dragInfo.normalView = viewHolder.normalView;
dragabbleView.setDragContextInfo(dragInfo);
dragabbleView.setInActionMode(absListView
.isItemChecked(position));
dragabbleView.setDragDropDelegate(IfAppController.this);
dragabbleView.setOnDropDelegate(IfAppController.this);
dragabbleView.setOpenDelegate(IfAppController.this);
} else {
Log.i(TAG, "File list items are not dragable!");
}
// ////////////////////////////////
Resources resources = getContext().getResources();
// initial visibility for views in convertView
viewHolder.infoTextView.setVisibility(View.VISIBLE);
viewHolder.selectModeMark.setChecked(absListView
.isItemChecked(position));
// icon
Drawable iconDrawable = fileItem.getIconDrawable();
if (iconDrawable != null) {
viewHolder.icon.setImageDrawable(iconDrawable);
} else {
viewHolder.icon.setImageResource(fileItem.getIconResource());
}
// name
String name = fileItem.getName();
int maxDisplayLength = resources
.getInteger(R.integer.file_label_max_display_length);
if (name.length() > maxDisplayLength) {
viewHolder.nameTextView.setText(name.substring(0,
maxDisplayLength) + "...");
} else {
viewHolder.nameTextView.setText(name);
}
// info
String infoText = "";
String permissionStr = fileItem.getPermissionStr();
if (fileItem.isDirectory()) {
String strItems = resources.getString(R.string.items);
int num_items = (int) fileItem.getSize();
if (num_items >= 0) {
infoText = (permissionStr != null) ? num_items + " "
+ strItems + " " + permissionStr : num_items + " "
+ strItems;
} else {
infoText = (permissionStr != null) ? STR_NA + " "
+ permissionStr : STR_NA;
}
} else {
mSizeStr = Formatter.formatFileSize(mContext,
fileItem.getSize());
infoText = (permissionStr != null) ? mSizeStr + " "
+ permissionStr : mSizeStr;
}
viewHolder.infoTextView.setText(infoText);
return convertView;
}
}
public class FileDropData {
public String fromDirPath;
public HashSet<Object> dropData;
public FileDropData(String fromDirPath, HashSet<Object> dropData) {
this.fromDirPath = fromDirPath;
this.dropData = dropData;
}
}
public static interface UiCallback {
public void onUrlContentUpdated(String newUrl, int contentSize,
boolean fromHistory);
}
private class FileContentUpdateProcedure implements Runnable {
ArrayList<String> _filePaths;
boolean _fromHistory = false;
@SuppressWarnings("unchecked")
public FileContentUpdateProcedure(ArrayList<String> filePaths,
boolean fromHistory) {
_filePaths = (ArrayList<String>) filePaths.clone();
_fromHistory = fromHistory;
}
@Override
public void run() {
String currentUrl = mFileManager.getCurrentUrl();
for (String path : _filePaths) {
appendFileItem(path);
}
Message msg = mUiHandler.obtainMessage(MSG_CURRENT_DIR_UPDATED);
msg.obj = currentUrl;
msg.arg1 = _filePaths.size();
msg.arg2 = _fromHistory ? 1 : 0;
mUiHandler.sendMessage(msg);
}
}
private static class FileItemViewHolder {
TextView nameTextView;
TextView infoTextView;
ImageView icon;
CheckBox selectModeMark;
ImageView draggingView;
ImageView dragReadyView;
View normalView;
public int position;
}
private class StorageDeviceItemGenerator extends
AsyncTask<String, Void, ArrayList<DeviceItem>> {
private int type;
private StorageDeviceItemGenerator(int type) {
this.type = type;
}
@Override
protected ArrayList<DeviceItem> doInBackground(String... params) {
if (isCancelled()) {
return null;
}
switch (type) {
case GEN_SINGLE_DISK_DEVICE_ITEM: {
final ArrayList<DeviceItem> result = new ArrayList<DeviceItem>();
IfStorageVolume volume = mStorageUtil
.getIfStorageVolumeFromPath(params[0]);
if (volume == null) {
Log.i("@temp", "create IfStorageVolume by path:"
+ params[0]);
mStorageUtil.createIfStorageVolumeByPath(params[0]);
volume = mStorageUtil.getIfStorageVolumeFromPath(params[0]);
}
DeviceItem deviceItem = createDeviceItemFromIfStorageVolume(volume);
if (deviceItem != null) {
result.add(deviceItem);
}
return result;
}
case GEN_ALL_DEVICE_ITEM: {
final ArrayList<DeviceItem> result = new ArrayList<DeviceItem>();
ArrayList<IfStorageVolume> volumes = mStorageUtil
.getIfStorageVolumes();
if (volumes != null) {
for (IfStorageVolume volume : volumes) {
DeviceItem deviceItem = createDeviceItemFromIfStorageVolume(volume);
if (deviceItem != null) {
if (tempLOG) {
Log.i("@temp", "add IfStorageVolume, path:"
+ deviceItem.getPath());
}
result.add(deviceItem);
}
}
}
return result;
}
default:
return null;
}
}
@Override
protected void onPostExecute(final ArrayList<DeviceItem> result) {
switch (type) {
case GEN_SINGLE_DISK_DEVICE_ITEM: {
if (result == null) {
return;
}
DeviceItem deviceItem = result.get(0);
DeviceDataAdapter adapter = getApproximateDeviceAdapter(deviceItem
.getMountPort());
if (adapter != null) {
adapter.add(deviceItem);
adapter.notifyDataSetChanged();
DeviceDataListener deviceDataListener = getDeviceDataListener();
if (deviceDataListener != null) {
deviceDataListener.onStorageDeviceItemChanged();
}
}
break;
}
case GEN_ALL_DEVICE_ITEM: {
if (result == null) {
return;
}
for (DeviceItem item : result) {
DeviceDataAdapter adapter = getApproximateDeviceAdapter(item
.getMountPort());
if (adapter != null) {
if (tempLOG) {
Log.i("@temp",
"found adapter: " + adapter.getIfTag()
+ " for mount point:"
+ item.getPath());
}
adapter.add(item);
adapter.notifyDataSetChanged();
DeviceDataListener deviceDataListener = getDeviceDataListener();
if (deviceDataListener != null) {
deviceDataListener.onStorageDeviceItemChanged();
}
}
}
}
default:
return;
}
}
@Override
protected void onPreExecute() {
// do nothing
}
}
private UiCallback mUiCallback = null;
private static final String TAG = "IfExplorer-IfAppController";
private static final boolean KLOG = true;
private static final boolean tempLOG = false;
public static final int MSG_UPDATE_CURRENT_DIR = 0;
public static final int MSG_CURRENT_DIR_UPDATED = 1;
public static final int MSG_SEARCH_PATH_UPDATED = 2;
public static final int MSG_SEARCH_RESULT_UPDATED = 3;
public static final int MSG_SEARCH_FINISHED = 4;
public static final int MSG_SEARCH_CANCELLED = 5;
public static final int MSG_FILES_BUNCH_UP_TO_STACK = 10;
public static final int MSG_FILES_SPREAD_FROM_STACK = 11;
public static final int MSG_FILES_PREPARE_DRAGGING_VIEW = 12;
public static final int MSG_FILES_DRAG_READY = 13;
private static final int GEN_SINGLE_DISK_DEVICE_ITEM = 0x01;
private static final int GEN_ALL_DEVICE_ITEM = 0x02;
private static final int UPDATE_INTERVAL_BASE = 1500;
private static final ArrayList<AsyncTask<String, Void, ?>> mBackgroundWorks = new ArrayList<AsyncTask<String, Void, ?>>();
private ArrayList<String> mCachedAudioFilePaths;
private ArrayList<String> mCachedVideoFilePaths;
private ArrayList<String> mCachedImageFilePaths;
private ArrayList<String> mCachedApkFilePaths;
private HashMap<String, ArrayList<String>> mCachedSearchResult;
private boolean mAudioCached = false;
private boolean mImageCached = false;
private boolean mVideoCached = false;
private boolean mApkFilesCached = false;
private ProgressDialog mSearchDialog = null;
private long mSearchResultLastUpdateTiming;
private final Context mContext;
protected final FilePathUrlManager mFileManager;
private static final int SORT_NONE = FilePathUrlManager.SORT_NONE;
private static final int SORT_ALPHA = FilePathUrlManager.SORT_ALPHA;
private static final int SORT_TYPE = SORT_ALPHA + 1;
private int mSortType = SORT_ALPHA;
@SuppressWarnings("rawtypes")
private static final Comparator mTypeComparator = new Comparator<FileItem>() {
@Override
public int compare(FileItem fileItem0, FileItem fileItem1) {
String fileType0 = fileItem0.getFileType();
String fileType1 = fileItem1.getFileType();
if (fileType0.equals(FileItem.FILE_TYPE_FILE_FOLDER)
&& !fileType1.equals(FileItem.FILE_TYPE_FILE_FOLDER)) {
return -1;
} else if (!fileType0.equals(FileItem.FILE_TYPE_FILE_FOLDER)
&& fileType1.equals(FileItem.FILE_TYPE_FILE_FOLDER)) {
return 1;
}
return fileType0.toLowerCase().compareTo(fileType1.toLowerCase());
}
};
private StorageUtil mStorageUtil;
private ThumbnailCreator mThumbnailCreator;
private AbsListView mCurrentFileListView;
private FileDataListAdapter mFileDataListAdapter;
private FileDataGridAdapter mFileDataGridAdapter;
private FavoriteDataAdapter mFavoriteDataAdapter;
private ArrayList<FileItem> mCurrentFileContent;
// mounted device paths
private ArrayList<String> mMountedDevicePaths = new ArrayList<String>();
// internal storage list adapter
private DeviceDataAdapter mInternalStorageDataAdapter;
// external SD card storage list adapter
private DeviceDataAdapter mSdcardDataAdapter;
// USB storage lists adapters
private DeviceDataAdapter mUsb0StorageDataAdapter;
private DeviceDataAdapter mUsb1StorageDataAdapter;
private DeviceDataAdapter mUsb2StorageDataAdapter;
private DeviceDataAdapter mUsb3StorageDataAdapter;
private DeviceDataAdapter mUsb4StorageDataAdapter;
private DeviceDataAdapter mUsb5StorageDataAdapter;
private DeviceDataAdapter mStorageA_DataAdapter;
private DeviceDataAdapter mStorageB_DataAdapter;
private DeviceDataAdapter mStorageC_DataAdapter;
private DeviceDataAdapter mStorageD_DataAdapter;
private DeviceDataAdapter mStorageE_DataAdapter;
private DeviceDataAdapter mStorageF_DataAdapter;
private DeviceDataListener mDeviceDataListener;
// For animate drag buddies bunch up to a stack or spread out from a stack
private boolean mDragBuddiesPrepared = true;
private boolean mDragBuddiesPreparing = false;
private BunchToStackAnimation mCurrentBunchToStackAnimation;
private final int MAX_LAYER_NUM_4_BUNCH_STACK = 6;
private ActionModeDraggableView mCurrentDragStartPointView;
private LinkedList<Object> mCurrentDragBuddies;
private Object mCurrentDragStartPointData;
private LinkedList<View> mCurrentVisibleDragBuddyViews;
private boolean mCurrentDragBuddyViewsStacked = false;
private LayerDrawable mDrawableForStackedDragBuddies;
private ArrayList<DropAcceptable> mExtraFileDragListeners = new ArrayList<DropAcceptable>();
private Handler mUiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UPDATE_CURRENT_DIR:
updateDirectory(mFileManager.refreshUrlContent());
break;
case MSG_CURRENT_DIR_UPDATED:
if (mUiCallback != null) {
mUiCallback.onUrlContentUpdated((String) msg.obj, msg.arg1,
(msg.arg2 == 1));
}
notifyFileContentChanged();
break;
case MSG_SEARCH_RESULT_UPDATED:
updateFileManagerPatternPaths();
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis - mSearchResultLastUpdateTiming > 1500) {
mSearchResultLastUpdateTiming = currentTimeMillis;
updateSearchProgressDialog((String) msg.obj);
if (mCurrentFileContent != null
&& mCurrentFileContent.size() < 64) {
updateDirectory(mFileManager.refreshUrlContent());
}
}
break;
case MSG_SEARCH_PATH_UPDATED:
long currentTimeMillis1 = System.currentTimeMillis();
if (currentTimeMillis1 - mSearchResultLastUpdateTiming > UPDATE_INTERVAL_BASE) {
mSearchResultLastUpdateTiming = currentTimeMillis1;
updateSearchProgressDialog((String) msg.obj);
}
break;
case MSG_SEARCH_FINISHED:
hideSearchProgressDialog();
updateFileManagerPatternPaths();
updateDirectory(mFileManager.refreshUrlContent());
break;
case MSG_SEARCH_CANCELLED:
hideSearchProgressDialog();
updateDirectory(mFileManager.refreshUrlContent());
break;
case MSG_FILES_BUNCH_UP_TO_STACK:
// Ready to drag
break;
case MSG_FILES_PREPARE_DRAGGING_VIEW:
prepareCurrentDraggingView();
break;
case MSG_FILES_DRAG_READY:
dragCurrentDragSources();
break;
default:
return;
}
}
};
public IfAppController(Context context, final FilePathUrlManager manager) {
mContext = context;
mFileManager = manager;
mFileManager.setFilePathObserver(this);
mStorageUtil = StorageUtil.getSingleton(context);
DataUtil.getReflectedUtilAPIs();
mCachedAudioFilePaths = new ArrayList<String>();
mCachedImageFilePaths = new ArrayList<String>();
mCachedVideoFilePaths = new ArrayList<String>();
mCachedApkFilePaths = new ArrayList<String>();
// mCachedSearchFilePaths = new ArrayList<String>();
mCachedSearchResult = new HashMap<String, ArrayList<String>>();
mFileDataListAdapter = new FileDataListAdapter();
mFileDataGridAdapter = new FileDataGridAdapter();
mCurrentFileContent = new ArrayList<FileItem>();
Collator.getInstance(DataUtil.getLocaleFromContext(mContext));
mFavoriteDataAdapter = new FavoriteDataAdapter(mContext,
new ArrayList<FavoriteItem>());
mInternalStorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mInternalStorageDataAdapter.setIfTag(1);
// root dir
DeviceItem rootDir = new DeviceItem("/",
mStorageUtil.getStorageDescription(R.string.root_dir),
mStorageUtil.getStorageDescription(R.string.internal_storage),
false, true, StorageUtil.Internal, StorageUtil.TYPE_ROOT);
mInternalStorageDataAdapter.add(rootDir);
mSdcardDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mSdcardDataAdapter.setIfTag(2);
mUsb0StorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mUsb0StorageDataAdapter.setIfTag(3);
mUsb1StorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mUsb1StorageDataAdapter.setIfTag(4);
mUsb2StorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mUsb2StorageDataAdapter.setIfTag(5);
mUsb3StorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mUsb3StorageDataAdapter.setIfTag(6);
mUsb4StorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mUsb4StorageDataAdapter.setIfTag(7);
mUsb5StorageDataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mUsb5StorageDataAdapter.setIfTag(8);
mStorageA_DataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mStorageA_DataAdapter.setIfTag(9);
mStorageB_DataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mStorageB_DataAdapter.setIfTag(10);
mStorageC_DataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mStorageC_DataAdapter.setIfTag(11);
mStorageD_DataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mStorageD_DataAdapter.setIfTag(12);
mStorageE_DataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mStorageE_DataAdapter.setIfTag(13);
mStorageF_DataAdapter = new DeviceDataAdapter(mContext,
new ArrayList<DeviceItem>());
mStorageF_DataAdapter.setIfTag(14);
}
public void cancelAllBackgroundWork() {
if (mBackgroundWorks != null) {
for (AsyncTask<String, Void, ?> task : mBackgroundWorks) {
if (task != null
&& (task.getStatus() == AsyncTask.Status.RUNNING)) {
task.cancel(true);
}
}
}
}
public void changeDirectory(String newDirPath) {
File file = new File(newDirPath);
if (file.isDirectory()) {
if (file.canRead()) {
stopThumbnailThread();
updateDirectory(mFileManager.getNextUrlContent(newDirPath,
true, false));
// When entering a folder, always focus on
// the first item, for compatible with a device with
// keyboard/remote controller as input
if (mCurrentFileListView != null) {
mCurrentFileListView.setSelection(0);
}
} else {
Toast.makeText(mContext, R.string.read_fail_permission,
Toast.LENGTH_SHORT).show();
}
}
}
@Override
public boolean checkDropDataAcceptable(Object dropData, View dropTarget) {
if (dropTarget == null) {
return false;
}
if (dropTarget instanceof ActionModeDraggableView) {
Object data = ((ActionModeDraggableView) dropTarget)
.getDragContextInfo().data;
if (data == null) {
return false;
} else {
// Can not drop a source on itself
if (dropData != null && dropData instanceof FileDropData) {
FileDropData fileDropData = (FileDropData) dropData;
if (fileDropData.dropData.contains(data)) {
Log.i(TAG,
"Drop target is contained in drag source, deny!");
return false;
}
}
}
if (data instanceof FileItem) {
FileItem fileItem = (FileItem) data;
if (!fileItem.isDirectory() || fileItem.isReadOnly()
|| fileItem.isReadWriteDeny()
|| fileItem.isSystemFile()) {
return false;
} else {
return true;
}
}
} else if (dropTarget instanceof DropableGridView
|| dropTarget instanceof DropableListView) {
if (dropTarget.equals(mCurrentFileListView)
&& FileUtil.isWritableDirectory(mFileManager
.getCurrentUrl())) {
Log.i(TAG, "Drop in current file list view.");
return true;
}
} else if (dropTarget instanceof DropableFilePathButton) {
String path = ((DropableFilePathButton) dropTarget).getFilePath();
if (FileUtil.isWritableDirectory(path)) {
return true;
}
} else if (dropTarget instanceof FilePathNavigator) {
return false;
}
return false;
}
@Override
public boolean checkOpenable(Openable openable) {
if (openable instanceof ActionModeDraggableView) {
Log.i(TAG, "check openable on an ActionModeDraggableView");
ActionModeDraggableView draggableView = (ActionModeDraggableView) openable;
DragContextInfo info = draggableView.getDragContextInfo();
Object data = info.data;
if (data.equals(mCurrentDragStartPointData)) {
Log.i(TAG,
"Current drag start point can't be openable (because it's being dragged), skip!");
return false;
}
if (data instanceof FileItem) {
Log.i(TAG, "openable check on an view for FileItem.");
final FileItem fileItem = (FileItem) data;
if (FileUtil.isReadableDirectory(fileItem.getPath())) {
return true;
} else {
return false;
}
}
}
return false;
}
@Override
public void doOpen(Openable openable) {
if (openable instanceof ActionModeDraggableView) {
Log.i(TAG, "Open an ActionModeDraggableView");
ActionModeDraggableView draggableView = (ActionModeDraggableView) openable;
DragContextInfo dragInfo = draggableView.getDragContextInfo();
Object data = dragInfo.data;
if (data instanceof FileItem) {
Log.i(TAG, "Open on an view for FileItem.");
final FileItem fileItem = (FileItem) data;
changeDirectory(fileItem.getPath());
}
} else if (openable instanceof DropableFilePathButton) {
DropableFilePathButton pathButton = (DropableFilePathButton) openable;
changeDirectory(pathButton.getFilePath());
}
}
public LinkedList<Object> findCurrentDragBuddies(
ActionModeDraggableView dragSource) {
LinkedList<Object> dragBuddies = null;
ViewParent viewParent = dragSource.getParent();
if (viewParent != null && (viewParent instanceof AbsListView)) {
AbsListView parentListView = (AbsListView) viewParent;
ListAdapter adapter = parentListView.getAdapter();
int checkedCount = parentListView.getCheckedItemCount();
if (checkedCount <= 1) {
return null;
} else {
dragBuddies = new LinkedList<Object>();
}
int dragBuddiesCount = checkedCount - 1;
SparseBooleanArray items = parentListView.getCheckedItemPositions();
int found = 0;
for (int i = 0; i < parentListView.getCount(); i++) {
if (items.get(i)) {
Object checkedItem = adapter.getItem(i);
View buddyView = parentListView.getChildAt(i);
boolean isBuddy = false;
if (buddyView == null) {
// Buddy with its view out of the screen
// definite not the start point
isBuddy = true;
} else {
// Could be the drag start point
isBuddy = (buddyView.hashCode() != dragSource
.hashCode());
}
if (isBuddy) {
synchronized (dragBuddies) {
dragBuddies.add(checkedItem);
found++;
}
}
if (found == dragBuddiesCount) {
break;
}
}
}
}
dragSource.setDragBuddies(dragBuddies);
return dragBuddies;
}
public void forceRefreshFileListView() {
mFileDataListAdapter.notifyDataSetChanged();
mFileDataGridAdapter.notifyDataSetChanged();
}
@Override
public DragShadowBuilder generateDragShadow(
ActionModeDraggableView dragSource) {
if (mCurrentDragBuddies == null) {
return new DragShadowBuilder(dragSource);
} else {
// Get dragging image view for generating drag shadow
ImageView draggingView = dragSource.getDragContextInfo().draggingView;
return new DragShadowBuilder((draggingView != null) ? draggingView
: dragSource);
}
}
@Override
public Object generateDropData() {
/*
* Default data structure for drag data, the same type to parameter 'choices' of
*
* IfExplorer.MultiChoiceConsumer::consumeChoice(HashSet<Object> choices,
* MultiChoiceConsumeOptions options)
*/
if (mCurrentDragStartPointData != null) {
if (mCurrentDragStartPointData instanceof FileItem) {
Log.i(TAG, "Generate drop data for file dragging.");
HashSet<Object> fileItems = new HashSet<Object>();
fileItems.add(mCurrentDragStartPointData);
if (mCurrentDragBuddies != null) {
synchronized (mCurrentDragBuddies) {
for (Object buddy : mCurrentDragBuddies) {
if (buddy instanceof FileItem) {
fileItems.add(buddy);
}
}
}
}
String currentPath = ((FileItem) mCurrentDragStartPointData)
.getPath();
String parentDirPath = FileUtil.getParentDirPath(currentPath);
Log.i(TAG, "Parent directory path is: " + parentDirPath
+ " for current: " + currentPath);
FileDropData dropData = new FileDropData(parentDirPath,
fileItems);
return dropData;
} // else if
// other stuff TBD
}
return null;
}
public DeviceDataAdapter getApproximateDeviceAdapter(int position) {
switch (position) {
case StorageUtil.Internal:
return mInternalStorageDataAdapter;
case StorageUtil.SDSlot:
return mSdcardDataAdapter;
case StorageUtil.USBPort0:
return mUsb0StorageDataAdapter;
case StorageUtil.USBPort1:
return mUsb1StorageDataAdapter;
case StorageUtil.USBPort2:
return mUsb2StorageDataAdapter;
case StorageUtil.USBPort3:
return mUsb3StorageDataAdapter;
case StorageUtil.USBPort4:
return mUsb4StorageDataAdapter;
case StorageUtil.USBPort5:
return mUsb5StorageDataAdapter;
case StorageUtil.USBSDA:
return mStorageA_DataAdapter;
case StorageUtil.USBSDB:
return mStorageB_DataAdapter;
case StorageUtil.USBSDC:
return mStorageC_DataAdapter;
case StorageUtil.USBSDD:
return mStorageD_DataAdapter;
case StorageUtil.USBSDE:
return mStorageE_DataAdapter;
case StorageUtil.USBSDF:
return mStorageF_DataAdapter;
default:
return null;
}
}
public ArrayList<String> getCachedApkFilePaths() {
return mCachedApkFilePaths;
}
public ArrayList<String> getCachedAudioFilePaths() {
return mCachedAudioFilePaths;
}
public HashMap<String, ArrayList<String>> getCachedSearchResult() {
return mCachedSearchResult;
}
public ArrayList<String> getCachedVideoFilePaths() {
return mCachedVideoFilePaths;
}
public ActionModeDraggableView getCurrentBunchedDestView() {
return mCurrentDragStartPointView;
}
public ArrayList<String> getCurrentMountedFileSystems() {
ArrayList<String> result = new ArrayList<String>();
// root file system
result.add("/");
if (mStorageUtil != null) {
ArrayList<String> storageVolumePaths = mStorageUtil
.getMountedStorageVolumePaths();
if (storageVolumePaths != null) {
result.addAll(storageVolumePaths);
}
}
return result;
}
public DeviceDataAdapter getDeviceDataAdapter(int storagePosition) {
switch (storagePosition) {
case StorageUtil.Internal:
return mInternalStorageDataAdapter;
case StorageUtil.SDSlot:
return mSdcardDataAdapter;
case StorageUtil.USBPort0:
return mUsb0StorageDataAdapter;
case StorageUtil.USBPort1:
return mUsb1StorageDataAdapter;
case StorageUtil.USBPort2:
return mUsb2StorageDataAdapter;
case StorageUtil.USBPort3:
return mUsb3StorageDataAdapter;
case StorageUtil.USBPort4:
return mUsb4StorageDataAdapter;
case StorageUtil.USBPort5:
return mUsb5StorageDataAdapter;
case StorageUtil.USBSDA:
return mStorageA_DataAdapter;
case StorageUtil.USBSDB:
return mStorageB_DataAdapter;
case StorageUtil.USBSDC:
return mStorageC_DataAdapter;
case StorageUtil.USBSDD:
return mStorageD_DataAdapter;
case StorageUtil.USBSDE:
return mStorageE_DataAdapter;
case StorageUtil.USBSDF:
return mStorageF_DataAdapter;
default:
return null;
}
}
public DeviceDataListener getDeviceDataListener() {
return mDeviceDataListener;
}
public FavoriteDataAdapter getFavoriteDataAdapter() {
return mFavoriteDataAdapter;
}
public FileDataGridAdapter getFileDataGridAdapter() {
return mFileDataGridAdapter;
}
public FileDataListAdapter getFileDataListAdapter() {
return mFileDataListAdapter;
}
public FilePathUrlManager getFileManager() {
return mFileManager;
}
@Override
public boolean handleDrop(Object dropData, View dropTarget) {
if (dropData == null || dropTarget == null
|| !(dropData instanceof FileDropData)) {
return false;
}
// Make use of ClipHistoryAdapter
if (mContext instanceof IfExplorer) {
if (dropTarget instanceof ActionModeDraggableView) {
Object accepterData = ((ActionModeDraggableView) dropTarget)
.getDragContextInfo().data;
if (accepterData != null && accepterData instanceof FileItem) {
Log.i(TAG, "Drop on the current directory: "
+ ((FileItem) accepterData).getPath());
handleFileMoveAsMultiChoiceConsume((FileDropData) dropData,
((FileItem) accepterData).getPath());
return true;
}
} else if (dropTarget instanceof DropableGridView
|| dropTarget instanceof DropableListView) {
Log.i(TAG, "Drop on the file grid instead of a file item.");
revertDragPreparation(mCurrentDragStartPointView);
if (dropTarget.equals(mCurrentFileListView)) {
String moveTargetPath = mFileManager.getCurrentUrl();
FileDropData fileDropData = (FileDropData) dropData;
if (fileDropData != null
&& !moveTargetPath.equals(fileDropData.fromDirPath)
&& FileUtil.isExistingFilePath(moveTargetPath)) {
Log.i(TAG, "Move to a different valid directory: "
+ moveTargetPath);
handleFileMoveAsMultiChoiceConsume(
(FileDropData) dropData, moveTargetPath);
} else {
Log.i(TAG,
"Drop in the same directory or in an invalid directory");
}
}
return true;
} else if (dropTarget instanceof DropableFilePathButton) {
Log.i(TAG,
"Drop on the file path button item instead of a directory item.");
revertDragPreparation(mCurrentDragStartPointView);
String moveTargetPath = ((DropableFilePathButton) dropTarget)
.getFilePath();
FileDropData fileDropData = (FileDropData) dropData;
if (!fileDropData.fromDirPath.equals(moveTargetPath)
&& FileUtil.isExistingFilePath(moveTargetPath)) {
Log.i(TAG, "Move to a different valid directory: "
+ moveTargetPath);
handleFileMoveAsMultiChoiceConsume((FileDropData) dropData,
moveTargetPath);
} else {
Log.i(TAG,
"Drop in the same directory or in an invalid directory");
}
}
}
return false;
}
public void handleFileMoveAsMultiChoiceConsume(FileDropData fileDropData,
String moveTargetPath) {
if (fileDropData == null && moveTargetPath == null) {
return;
}
HashSet<Object> fileItems = fileDropData.dropData;
ClipHistoryAdapter clipHistoryAdapter = ((IfExplorer) mContext)
.getClipHistoryAdapter();
if (clipHistoryAdapter != null) {
// Mark
Log.i(TAG, "Mark data to be cut.");
MultiChoiceConsumeOptions cutOptions = new MultiChoiceConsumeOptions(
ClipHistoryAdapter.CLIP_CUT);
clipHistoryAdapter.consumeChoice(fileItems, cutOptions);
ActionMode activatingAm = ((IfExplorer) mContext)
.getActivatingActionMode();
if (activatingAm != null) {
activatingAm.finish();
}
// Execute
Log.i(TAG, "Cut data to places.");
int count = clipHistoryAdapter.getCount();
if (count >= 1) {
ClipItemAdapter adapter = clipHistoryAdapter
.getItem(clipHistoryAdapter.getCount() - 1);
if (adapter != null) {
HashSet<FileClip> toPaste = adapter.prepare();
if (toPaste.size() > 0) {
adapter.pasteFileClip(toPaste, moveTargetPath);
}
}
}
}
}
public boolean hasActionModeBunchedViews() {
return mCurrentDragBuddyViewsStacked;
}
/** called to update the favorite contents */
public void initializeDefaultFavorites() {
if (!mFavoriteDataAdapter.isEmpty()) {
mFavoriteDataAdapter.clear();
}
// kevin: TODO: implement as user configured
FavoriteItem favorite_music = new FavoriteItem(
FilePathUrlManager.SMART_MUSIC, mContext.getResources()
.getString(R.string.music), StorageUtil.TYPE_AUDIO,
R.drawable.type_music);
mFavoriteDataAdapter.add(favorite_music);
FavoriteItem favorite_videos = new FavoriteItem(
FilePathUrlManager.SMART_MOVIES, mContext.getResources()
.getString(R.string.videos), StorageUtil.TYPE_VIDEO,
R.drawable.type_movie);
mFavoriteDataAdapter.add(favorite_videos);
FavoriteItem favorite_apks = new FavoriteItem(
FilePathUrlManager.SMART_APK, mContext.getResources()
.getString(R.string.apkInstaller),
StorageUtil.TYPE_APKFILE, R.drawable.type_apk);
mFavoriteDataAdapter.add(favorite_apks);
mFavoriteDataAdapter.notifyDataSetChanged();
}
@Override
public void interruptDragPreparation(
final ActionModeDraggableView dragSource) {
Log.i(TAG, "Interrupt drag preparation!");
if (mCurrentBunchToStackAnimation != null) {
mCurrentBunchToStackAnimation.cancel();
}
mDragBuddiesPreparing = false;
}
public void intializeStorageDevicesAsync() {
StorageDeviceItemGenerator task = new StorageDeviceItemGenerator(
GEN_ALL_DEVICE_ITEM);
mBackgroundWorks.add(task);
task.execute("");
}
@Override
public boolean isDragOpDelegated(final ActionModeDraggableView dragSource) {
if (dragSource.isDragReady()) {
// Drag ready, no asynchronous preparation steps are needed,
// so we let the drag source do the drag by itself
return false;
} else {
// If the drag source is not ready to drag and it has buddies,
// then we will prepare its buddies for drag, including animating buddies bunch up to a stack.
// Only when the animation finished can we start the drag,
// so we delegate the drag operation.
if (dragSource.getDragBuddies() != null) {
return true;
} else {
return false;
}
}
}
@Override
public boolean isDragPrepared(final ActionModeDraggableView dragSource) {
if (mDragBuddiesPrepared) {
Log.i(TAG, "Preparing!");
return true;
} else {
Log.i(TAG, "Not preparing!");
return false;
}
}
@Override
public void navigateToPath(String path) {
updateDirectory(mFileManager.getNextUrlContent(path, true, false));
}
@Override
public void notifyAutoDragStarted(ActionModeDraggableView dragSource) {
mCurrentDragStartPointView = dragSource;
displayCurrentDragStartPoint(false);
// Finish action mode
ActionMode activatingAm = ((IfExplorer) mContext)
.getActivatingActionMode();
if (activatingAm != null) {
activatingAm.finish();
}
// Notify extra listeners a drag started
notifyFileDragStartedForExtraListener();
}
@Override
public void notifyDropDataDenied(Object dropData, View dropTarget) {
Log.i(TAG, "notifyDropDataDenied");
if (dropData instanceof FileDropData) {
FileDropData fileDropData = (FileDropData) dropData;
if (mCurrentFileListView.equals(dropTarget)) {
promptMoveFailureDueToPermission(fileDropData.fromDirPath,
mFileManager.getCurrentUrl());
} else if (dropTarget instanceof ActionModeDraggableView) {
Object data = ((ActionModeDraggableView) dropTarget)
.getDragContextInfo().data;
if (data instanceof FileItem) {
promptMoveFailureDueToPermission(fileDropData.fromDirPath,
((FileItem) data).getPath());
}
}
}
}
// implement
// gem.kevin.filmanager.FileManager.FilePathObserver::notifyOnAllEvents
@Override
public void notifyOnAllEvents(String path) {
mUiHandler.sendEmptyMessage(MSG_UPDATE_CURRENT_DIR);
}
@Override
public void onDropFailed(View dropTarget) {
revertDragPreparation(mCurrentDragStartPointView);
}
@Override
public void onDropSuccess(View dropTarget) {
// do nothing
}
@Override
public void onHover(View hoverTarget) {
if (hoverTarget instanceof Openable) {
final Openable openableTarget = (Openable) hoverTarget;
AlphaAnimation flickingAnim = new AlphaAnimation(0.1f, 1.0f);
flickingAnim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
// After flicking, open the target and revert drag preparation
openableTarget.open();
revertDragPreparation(mCurrentDragStartPointView);
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
});
flickingAnim.setDuration(200);
hoverTarget.startAnimation(flickingAnim);
}
}
@Override
public void onSearchOpTaskCancelled(FileOperationTask task) {
Message msg = mUiHandler.obtainMessage(MSG_SEARCH_CANCELLED);
mUiHandler.sendMessage(msg);
}
@Override
public void onSearchOpTaskFinished(FileOperationTask task) {
Message msg = mUiHandler.obtainMessage(MSG_SEARCH_FINISHED);
mUiHandler.sendMessage(msg);
Log.i(TAG, "onSearchOpTaskFinished");
int searchType = task.getOptions().searchType;
switch (searchType) {
case StorageUtil.TYPE_APKFILE:
mApkFilesCached = true;
break;
case StorageUtil.TYPE_AUDIO:
mAudioCached = true;
break;
case StorageUtil.TYPE_IMAGE:
mImageCached = true;
break;
case StorageUtil.TYPE_VIDEO:
mVideoCached = true;
break;
}
}
@Override
public void onSearchOpTaskProgressing(FileOperationTask task,
String searchDirPath, boolean dirFinished) {
Message msg;
if (dirFinished) {
msg = mUiHandler.obtainMessage(MSG_SEARCH_RESULT_UPDATED);
msg.obj = searchDirPath;
mUiHandler.sendMessage(msg);
} else {
msg = mUiHandler.obtainMessage(MSG_SEARCH_PATH_UPDATED);
msg.obj = searchDirPath;
mUiHandler.sendMessage(msg);
}
}
@Override
public void onSpreadAnimationCanceled(View animView) {
// TODO Auto-generated method stub
}
@Override
public void onSpreadAnimationFinished(View animView) {
// Since the view ends animating spread out from a stack
// it should be 'back' its original position
}
@Override
public void onSpreadAnimationStart(View animView) {
Log.i(TAG, "Spread animation START.");
// 'Split' the stacked views
mDrawableForStackedDragBuddies = null;
if (mCurrentDragStartPointView != null) {
splitCurrentDragBuddies();
mCurrentDragStartPointView.setDragReady(false);
}
}
@Override
public void onStackAnimationCanceled(View animView) {
// TODO Auto-generated method stub
Log.i(TAG, "Stack animation CANCELED.");
if (mCurrentBunchToStackAnimation.isCanceled()) {
Log.i(TAG, "All stack animations canceled.");
if (mCurrentDragStartPointView != null) {
Log.i(TAG,
"Revert drag prepartion for stack animation canceled.");
revertDragPreparation(mCurrentDragStartPointView);
// Drag preparation is canceled
mDragBuddiesPreparing = false;
mDragBuddiesPrepared = false;
}
} else {
Log.i(TAG, "Not all stack animations canceled yet.");
}
}
@Override
public void onStackAnimationFinished(View animView) {
Log.i(TAG, "Stack animation FINISHED.");
if (mCurrentBunchToStackAnimation.isFinished()) {
Log.i(TAG, "All stack animations finished.");
if (mDrawableForStackedDragBuddies != null
&& mCurrentDragStartPointView != null) {
stackCurrentDragBuddies();
// Drag preparation is finished
mDragBuddiesPreparing = false;
}
} else {
Log.i(TAG, "Not all stack animations finished yet.");
}
}
@Override
public void onStackAnimationStart(View animView) {
Log.i(TAG, "onStackAnimationStart");
}
@Override
public void prepareDrag(final ActionModeDraggableView dragSource) {
Log.i(TAG, "Prepare drag!");
mCurrentDragStartPointData = dragSource.getDragContextInfo().data;
mCurrentDragBuddies = findCurrentDragBuddies(dragSource);
if (mCurrentDragBuddies != null) {
mDragBuddiesPrepared = false;
mDragBuddiesPreparing = true;
mCurrentVisibleDragBuddyViews = getCurrentVisibleViewsForDragBuddies(mCurrentDragBuddies);
// Generate a stacked drawable could be time-consuming,
// so we generate it before the stack animation then show it
// after the animation
// TODO: May use an asynchronous way to generate the stacked view
if (dragSource.getDragContextInfo().draggingView != null) {
mDrawableForStackedDragBuddies = generateDrawableForStackedFiles(
mCurrentVisibleDragBuddyViews, dragSource);
}
// Do animation only if the stacked view is generated successfully
if (mDrawableForStackedDragBuddies != null) {
if (mCurrentBunchToStackAnimation == null) {
mCurrentBunchToStackAnimation = new BunchToStackAnimation(
mContext, false);
mCurrentBunchToStackAnimation
.setBunchAnimationListener(this);
}
mCurrentBunchToStackAnimation.clearAnimViews();
mCurrentDragStartPointView = dragSource;
for (View toStackView : mCurrentVisibleDragBuddyViews) {
mCurrentBunchToStackAnimation.addAnimView(toStackView);
}
mCurrentBunchToStackAnimation.animateBunchUpToPoint(
dragSource.getLeft(), dragSource.getTop());
// Hide buddies because they have 'left' their position
// and moving toward the bunch destination
displayCurrentDragBuddies(false);
}
}
}
public void resetCachedFilePaths() {
Log.i(TAG, "Reset cached file paths.");
if (!mCachedAudioFilePaths.isEmpty()) {
mCachedAudioFilePaths.clear();
}
if (!mCachedImageFilePaths.isEmpty()) {
mCachedImageFilePaths.clear();
}
if (!mCachedVideoFilePaths.isEmpty()) {
mCachedVideoFilePaths.clear();
}
if (!mCachedApkFilePaths.isEmpty()) {
mCachedApkFilePaths.clear();
}
/*
* if (!mCachedSearchFilePaths.isEmpty()) {
* mCachedSearchFilePaths.clear(); }
*/
if (!mCachedSearchResult.isEmpty()) {
mCachedSearchResult.clear();
}
mAudioCached = false;
mImageCached = false;
mVideoCached = false;
mApkFilesCached = false;
updateFileManagerPatternPaths();
}
@Override
public void revertDragPreparation(final ActionModeDraggableView dragSource) {
Log.i(TAG, "Revert drag preparation!");
splitCurrentDragBuddies();
dragSource.setDragReady(false);
// 'Put back' the drag start point
displayCurrentDragStartPoint(true);
// 'Put back the drag buddies
displayCurrentDragBuddies(true);
Log.i(TAG, "After revert!");
}
public void searchFiles(int searchType, String searchStr, String searchDir,
int searchDepth, boolean silent) {
boolean cached = false;
switch (searchType) {
case StorageUtil.TYPE_AUDIO:
cached = mAudioCached;
break;
case StorageUtil.TYPE_VIDEO:
cached = mVideoCached;
break;
case StorageUtil.TYPE_IMAGE:
cached = mImageCached;
break;
case StorageUtil.TYPE_APKFILE:
cached = mApkFilesCached;
break;
}
if (cached) {
// updateDirectory(mFileManager.refreshUrlContent());
return;
} else {
Log.i(TAG, "Not cached.");
}
HashMap<String, Object> searchParams = new HashMap<String, Object>();
searchParams.put(FileOperationOptions.KEY_SEARCH_DIR, searchDir);
searchParams.put(FileOperationOptions.KEY_SEARCH_RESEVERD_DIR, null);
searchParams.put(FileOperationOptions.KEY_SEARCH_DEPTH,
Integer.valueOf(searchDepth));
searchParams.put(FileOperationOptions.KEY_SEARCH_RECORD_LIMIT,
IfConfig.MAX_LISTITEM_COUNT);
switch (searchType) {
case StorageUtil.TYPE_AUDIO:
mCachedAudioFilePaths.clear();
searchParams.put(FileOperationOptions.KEY_SEARCH_SCOPE,
DataUtil.getSupportedAudioFileExtensions());
searchParams.put(FileOperationOptions.KEY_SEARCH_OUTPUT,
mCachedAudioFilePaths);
break;
case StorageUtil.TYPE_VIDEO:
mCachedVideoFilePaths.clear();
searchParams.put(FileOperationOptions.KEY_SEARCH_SCOPE,
DataUtil.getSupportedVideoFileExtensions());
searchParams.put(FileOperationOptions.KEY_SEARCH_OUTPUT,
mCachedVideoFilePaths);
break;
case StorageUtil.TYPE_IMAGE:
mCachedImageFilePaths.clear();
searchParams.put(FileOperationOptions.KEY_SEARCH_SCOPE,
DataUtil.getSupportedImageFileExtensions());
searchParams.put(FileOperationOptions.KEY_SEARCH_OUTPUT,
mCachedImageFilePaths);
break;
case StorageUtil.TYPE_APKFILE:
mCachedApkFilePaths.clear();
searchParams.put(FileOperationOptions.KEY_SEARCH_SCOPE,
DataUtil.getSupportedAppInstallerFileExtensions());
searchParams.put(FileOperationOptions.KEY_SEARCH_OUTPUT,
mCachedApkFilePaths);
break;
case StorageUtil.TYPE_FILE:
String searchId = FilePathUrlManager.buildSearchId(searchStr,
searchDir);
ArrayList<String> searchResult = mCachedSearchResult.get(searchId);
if (searchResult != null) {
Log.i(TAG, "Ever found.");
searchResult.clear();
} else {
searchResult = new ArrayList<String>();
mCachedSearchResult.put(searchId, searchResult);
}
searchParams.put(FileOperationOptions.KEY_SEARCH_SCOPE, null);
searchParams.put(FileOperationOptions.KEY_SEARCH_OUTPUT,
searchResult);
searchParams.put(FileOperationOptions.KEY_SEARCH_DEPTH,
Integer.valueOf(searchDepth) + 100);
break;
default: // do nothing if search request is not supported
return;
}
FileOperationOptions options = FileOperationTask
.makeDefaultOptions(FileOperationTask.OP_TYPE_SEARCH_FILE);
options.setSearchParams(searchParams);
options.setSearchType(searchType);
ArrayList<String> searchTargets = new ArrayList<String>();
searchTargets.add(searchStr);
Time time = new Time();
time.setToNow();
String taskId = String.format("%02d:%02d:%02d-search", time.hour,
time.minute, time.second);
final FileOperationTask searchTask = new FileOperationTask(mContext,
taskId, options, searchTargets, this);
searchTask.start();
mSearchResultLastUpdateTiming = System.currentTimeMillis();
if (!silent) {
showSearchProgressDialog(searchDir, searchStr, searchType,
searchTask);
}
updateDirectory(mFileManager.refreshUrlContent());
}
public void setCachedApkFilePaths(ArrayList<String> cachedApkFilePaths) {
mCachedApkFilePaths = cachedApkFilePaths;
}
public void setCachedAudioFilePaths(ArrayList<String> cachedAudioFilePaths) {
mCachedAudioFilePaths = cachedAudioFilePaths;
}
public void setCachedSearchResult(HashMap<String, ArrayList<String>> result) {
mCachedSearchResult = result;
}
public void setCachedVideoFilePaths(ArrayList<String> cachedVideoFilePaths) {
mCachedVideoFilePaths = cachedVideoFilePaths;
}
public void setCurrentFileListView(AbsListView absListView) {
mCurrentFileListView = absListView;
}
public void setDeviceDataListener(DeviceDataListener listener) {
mDeviceDataListener = listener;
}
public void addExtraFileDragStartedListener(DropAcceptable dropAcceptable) {
mExtraFileDragListeners.add(dropAcceptable);
}
public void setPathMode(boolean absolute) {
}
public void setUiCallback(UiCallback callback) {
mUiCallback = callback;
}
@Override
public boolean shouldDispathUnacceptableDropToParent(View dropTarget) {
if (dropTarget instanceof ActionModeDraggableView
&& dropTarget.getParent() != null
&& (dropTarget.getParent() instanceof DropableGridView || dropTarget
.getParent() instanceof DropableListView)) {
return false;
} else if (dropTarget instanceof DropableGridView) {
return false;
} else if (dropTarget instanceof DropableListView) {
return false;
} else if (dropTarget instanceof DropableFilePathButton) {
return false;
} else if (dropTarget instanceof FilePathNavigator) {
return false;
} else {
return false;
}
}
public void splitActionModeBunchedViews() {
splitCurrentDragBuddies();
}
/** this will stop our background thread that creates thumb nail icons if the
* thread is running. this should be stopped when ever we leave the folder
* the image files are in. */
public void stopThumbnailThread() {
if (mThumbnailCreator != null) {
mThumbnailCreator.setCancelThumbnails(true);
mThumbnailCreator = null;
}
}
public void updateDirectory(ArrayList<String> fileContent) {
updateDirectory(fileContent, false);
}
public void updateDirectory(ArrayList<String> fileContent,
boolean fromHistory) {
// TODO: too much work on main thread, refactor to working thread
Log.i(TAG, "update directory");
clearFileContent();
if (fileContent == null) {
notifyFileContentChanged();
return;
}
FileContentUpdateProcedure updateProcedure = new FileContentUpdateProcedure(
fileContent, fromHistory);
// Run work thread
// new Thread(updateProcedure).start();
// RUn on main thread
updateProcedure.run();
}
public void updateFileManagerPatternPaths() {
if (mFileManager != null) {
mFileManager.setAudioPatternPath(mCachedAudioFilePaths);
mFileManager.setVideoPatternPath(mCachedVideoFilePaths);
mFileManager.setImagePatternPath(mCachedImageFilePaths);
mFileManager.setApkPatternPath(mCachedApkFilePaths);
mFileManager.setSearchFilePatternPath(mCachedSearchResult);
}
}
public void updateStorageDevice(String mountPoint, String newState,
boolean async) {
int mountPort = StorageUtil.getMountPort(mountPoint);
DeviceDataAdapter adapter = getApproximateDeviceAdapter(mountPort);
if (adapter == null) {
Log.e(TAG, "Can't get adapter for path: " + mountPoint);
return;
}
if (newState.equals(Environment.MEDIA_MOUNTED)) {
if (async) {
StorageDeviceItemGenerator task = new StorageDeviceItemGenerator(
GEN_SINGLE_DISK_DEVICE_ITEM);
mBackgroundWorks.add(task);
task.execute(mountPoint);
} else {
// These operations are time-consuming
// Be careful to run them in main thread
IfStorageVolume volume = mStorageUtil
.getIfStorageVolumeFromPath(mountPoint);
DeviceItem newDeviceItem = createDeviceItemFromIfStorageVolume(volume);
adapter.add(newDeviceItem);
adapter.notifyDataSetChanged();
getDeviceDataListener().onStorageDeviceItemChanged();
}
} else if (newState.equals(Environment.MEDIA_UNMOUNTED)) {
for (int i = 0; i < adapter.getCount(); i++) {
DeviceItem target = adapter.getItem(i);
String path = target.getPath();
if (path.equals(mountPoint)) {
mMountedDevicePaths.remove(path);
adapter.remove(target);
adapter.notifyDataSetChanged();
mDeviceDataListener.onStorageDeviceItemChanged();
break;
}
}
} else if (newState.equals(Environment.MEDIA_BAD_REMOVAL)
|| newState.equals(Environment.MEDIA_REMOVED)) {
if (!adapter.isEmpty()) {
for (int i = 0; i < adapter.getCount(); i++) {
String path = adapter.getItem(i).getPath();
mMountedDevicePaths.remove(path);
}
adapter.clear();
adapter.notifyDataSetChanged();
mDeviceDataListener.onStorageDeviceItemChanged();
}
}
}
public void updateStorageDevices(boolean async) {
}
private void appendFileItem(String path) {
synchronized (mCurrentFileContent) {
FileItem fileItem = new FileItem(mContext, path);
mCurrentFileContent.add(fileItem);
}
}
@SuppressWarnings("unchecked")
private void sortFileItems(int sortType) {
if (sortType == mFileManager.getPreSortType()) {
// Sort type is the same to pre sort by file maanger,
// no need to sort again
return;
} else {
@SuppressWarnings("rawtypes")
Comparator sortComparator;
switch (sortType) {
case SORT_TYPE:
sortComparator = mTypeComparator;
break;
default:
sortComparator = null;
}
if (sortComparator != null) {
synchronized (mCurrentFileContent) {
Object[] array = mCurrentFileContent.toArray();
mCurrentFileContent.clear();
Arrays.sort(array, sortComparator);
for (Object a : array) {
mCurrentFileContent.add((FileItem) a);
}
}
}
}
}
private void clearFileContent() {
synchronized (mCurrentFileContent) {
if (!mCurrentFileContent.isEmpty()) {
mCurrentFileContent.clear();
}
}
}
private DeviceItem createDeviceItemFromIfStorageVolume(
IfStorageVolume volume) {
if (volume == null) {
return null;
}
String mountPoint = volume.getPath();
boolean removable = volume.isRemovable();
boolean emulated = volume.isEmulated();
boolean mounted = mStorageUtil.isMounted(mountPoint);
if (!mounted) {
// Currently doesn't support mount operation on single volume,
// so no need to show unmounted volumes
return null;
}
int mountPort = StorageUtil.getMountPort(mountPoint);
int type;
switch (mountPort) {
case StorageUtil.Internal:
type = StorageUtil.TYPE_HOME;
break;
case StorageUtil.SDSlot:
type = StorageUtil.TYPE_SDCARD;
break;
default:
type = StorageUtil.TYPE_UDISK;
}
String volumeLabel = null;
if (IfConfig.PRODUCT_SUPPORT_KEVIN_VOLD) {
volumeLabel = mStorageUtil.readVolIdForPath(mountPoint,
StorageUtil.VOLID_TAG_LABEL);
}
if (volumeLabel == null) {
if (emulated) {
volumeLabel = mStorageUtil
.getStorageDescription(R.string.home_dir);
} else {
if (mountPort == StorageUtil.Internal
&& IfConfig.PRODUCT_ROCK_CHIP) {
volumeLabel = mContext.getResources().getString(
R.string.home_dir);
} else {
volumeLabel = String.format("%s (%s)", mStorageUtil
.getStorageDescription(R.string.removable_disk),
FileUtil.getFileName(mountPoint));
}
}
}
String diskName = null;
if (IfConfig.PRODUCT_SUPPORT_KEVIN_VOLD) {
diskName = mStorageUtil.readDiskNameForPath(mountPoint);
}
final DeviceItem deviceItem = new DeviceItem(mountPoint,
(volumeLabel != null) ? volumeLabel : mStorageUtil
.getStorageDescription(emulated ? R.string.home_dir
: R.string.removable_disk),
(diskName != null && !diskName.isEmpty()) ? diskName : null,
removable, mounted, mountPort, type);
if (tempLOG) {
Log.i("@temp",
"createDeviceItemFromIfStorageVolume --- get device item for path: "
+ mountPoint);
}
return deviceItem;
}
private void displayCurrentDragBuddies(boolean show) {
/*
* If the views start animating bunch up to a stack
* they should have 'left' their original positions
* But we can't demonstrate the 'left' behavior
* by setting visibility of the views
*
* Because these views are AdapterView used in a AbsListView,
* they could be reused for different items. In other words,
* a view is not exactly correspond to FileItem, but a view
* could be used by several FileItems.
*
* So, we mark the exact data object to be 'dragged' from
* its original place and let the mark decide the visibility of
* its view
*/
if (mCurrentDragStartPointView != null) {
ViewParent parentView = mCurrentDragStartPointView.getParent();
if (parentView instanceof AbsListView
&& mCurrentDragBuddies != null) {
synchronized (mCurrentDragBuddies) {
for (Object buddy : mCurrentDragBuddies) {
if (buddy instanceof FileItem) {
((FileItem) buddy).setVisible(show);
}
}
}
ListAdapter adapter = ((AbsListView) parentView).getAdapter();
if (adapter instanceof FileDataGridAdapter) {
((FileDataGridAdapter) adapter).notifyDataSetChanged();
} else if (adapter instanceof FileDataListAdapter) {
((FileDataListAdapter) adapter).notifyDataSetChanged();
}
}
}
}
private void displayCurrentDragStartPoint(boolean show) {
Log.i(TAG, "displayCurrentDragStartPoint: " + show);
if (mCurrentDragStartPointView != null) {
ViewParent parentView = mCurrentDragStartPointView.getParent();
if (parentView instanceof AbsListView) {
ListAdapter adapter = ((AbsListView) parentView).getAdapter();
Object tag = mCurrentDragStartPointView.getTag();
if (tag instanceof FileItemViewHolder) {
int position = ((FileItemViewHolder) tag).position;
if (position >= 0) {
Object data = adapter.getItem(position);
if (data instanceof FileItem) {
((FileItem) data).setVisible(show);
}
}
if (adapter instanceof FileDataGridAdapter) {
((FileDataGridAdapter) adapter).notifyDataSetChanged();
} else if (adapter instanceof FileDataListAdapter) {
((FileDataListAdapter) adapter).notifyDataSetChanged();
}
}
}
}
}
private void dragCurrentDragSources() {
mDragBuddiesPrepared = true;
mCurrentDragStartPointView.setDragReady(true);
if (mCurrentDragStartPointView
.doDrag(generateDragShadow(mCurrentDragStartPointView))) {
// Hide the view because it has been 'dragged' from its original place
displayCurrentDragStartPoint(false);
// Finish action mode
ActionMode activatingAm = ((IfExplorer) mContext)
.getActivatingActionMode();
if (activatingAm != null) {
activatingAm.finish();
}
// Notify extra listeners a drag started
notifyFileDragStartedForExtraListener();
} else {
revertDragPreparation(mCurrentDragStartPointView);
}
}
private LayerDrawable generateDrawableForStackedFiles(
LinkedList<View> visibleDragBuddyViews, View topView) {
if (visibleDragBuddyViews == null || visibleDragBuddyViews.size() == 0) {
return null;
} else {
final int visibleBuddyCount = visibleDragBuddyViews.size();
final int layerCount;
if (visibleBuddyCount <= MAX_LAYER_NUM_4_BUNCH_STACK - 1) {
layerCount = visibleBuddyCount + 1;
} else {
layerCount = MAX_LAYER_NUM_4_BUNCH_STACK;
}
// Drawable layers for buddy views and the top view
Drawable[] shadowLayers = new Drawable[layerCount];
// Dimensions for build a stacked view from views
Resources resources = mContext.getResources();
int horizontalGap = resources
.getDimensionPixelSize(R.dimen.file_stack_horizontal_gap);
int verticalGap = resources
.getDimensionPixelSize(R.dimen.file_stack_vertical_gap);
int totalCutWidth = horizontalGap * (layerCount - 1);
int totalCutHeight = verticalGap * (layerCount - 1);
int layerIndex = 0;
// Buddies layers
for (View buddyView : mCurrentVisibleDragBuddyViews) {
if (layerIndex >= layerCount - 1) {
break;
}
// FIXME:
// Since the stacked view works for a drag preparation,
// we can stop the generating process if drag preparation is already finished or canceled
if (mDragBuddiesPrepared || !mDragBuddiesPreparing) {
return null;
}
Bitmap originalBitmap = DataUtil.getBitmapFromView(buddyView);
// Scale down each bitmap for single layer,
// so we can stack the bitmaps in layers with gap
// and keep same size with original bitmap
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap,
originalBitmap.getWidth() - totalCutWidth,
originalBitmap.getHeight() - totalCutHeight, true);
shadowLayers[layerIndex] = new BitmapDrawable(resources,
scaledBitmap);
layerIndex++;
}
// Source layer is on top.
Bitmap topOriginal = DataUtil.getBitmapFromView(topView);
Bitmap topScaled = Bitmap.createScaledBitmap(topOriginal,
topOriginal.getWidth() - totalCutWidth,
topOriginal.getHeight() - totalCutHeight, true);
shadowLayers[layerCount - 1] = new BitmapDrawable(resources,
topScaled);
// Stack together the layers and set gap between layers
// so we can see the stack effect
LayerDrawable shadowDrawable = new LayerDrawable(shadowLayers);
for (int index = 0; index < layerCount; index++) {
shadowDrawable
.setLayerInset(index, (layerCount - 1 - index)
* horizontalGap, index * verticalGap, index
* horizontalGap, (layerCount - 1 - index)
* verticalGap);
}
return shadowDrawable;
}
}
private LinkedList<View> getCurrentVisibleViewsForDragBuddies(
LinkedList<Object> dragBuddies) {
if (dragBuddies == null) {
return null;
}
LinkedList<View> visibleDragBuddyViews = new LinkedList<View>();
synchronized (dragBuddies) {
for (Object buddy : dragBuddies) {
if (buddy instanceof FileItem) {
FileItem fileItem = (FileItem) buddy;
if (fileItem.getConvertView() != null) {
FileItemViewHolder viewHolder = (FileItemViewHolder) fileItem
.getConvertView().getTag();
if (viewHolder.position == fileItem
.getPositionInAdapterList()) {
visibleDragBuddyViews
.add(fileItem.getConvertView());
}
}
}
}
}
return visibleDragBuddyViews;
}
private void hideSearchProgressDialog() {
if (mSearchDialog != null) {
mSearchDialog.dismiss();
}
}
private void notifyFileContentChanged() {
synchronized (mCurrentFileContent) {
mFileDataListAdapter.clear();
mFileDataListAdapter.addAll(mCurrentFileContent);
mFileDataGridAdapter.clear();
mFileDataGridAdapter.addAll(mCurrentFileContent);
}
// Every time file list view got updated, its child views (file item views)
// should be marked as 'can not get drag event'
// Because there could be some new child views been created after last drag started
if (mCurrentFileListView != null
&& mCurrentFileListView instanceof DropAcceptable) {
Log.i(TAG, "Mark file list item views can not get drag event.");
((DropAcceptable) mCurrentFileListView)
.markChildCanGetDragEvent(false);
}
}
private void notifyFileDragStartedForExtraListener() {
if (mExtraFileDragListeners != null) {
for (DropAcceptable extraListener : mExtraFileDragListeners) {
if (extraListener != null) {
extraListener.onDragStarted(null);
}
}
}
}
private void prepareCurrentDraggingView() {
ImageView draggingView = mCurrentDragStartPointView
.getDragContextInfo().draggingView;
BadgeView badge = mCurrentDragStartPointView.getBadgeView();
if (draggingView != null) {
if (badge != null) {
Drawable[] drawableWithBadge = new Drawable[2];
drawableWithBadge[0] = mDrawableForStackedDragBuddies;
drawableWithBadge[1] = new BitmapDrawable(
mContext.getResources(),
DataUtil.getBitmapFromView(badge));
LayerDrawable layerWithBadge = new LayerDrawable(
drawableWithBadge);
layerWithBadge.setLayerInset(
1,
mCurrentDragStartPointView.getWidth()
- badge.getWidth(),
0,
0,
mCurrentDragStartPointView.getHeight()
- badge.getHeight());
draggingView.setImageDrawable(layerWithBadge);
badge.setVisibility(View.GONE);
} else {
draggingView.setImageDrawable(mDrawableForStackedDragBuddies);
}
draggingView.setVisibility(View.VISIBLE);
ImageView dragReadyView = mCurrentDragStartPointView
.getDragContextInfo().dragReadyView;
if (dragReadyView != null) {
dragReadyView.setImageDrawable(null);
dragReadyView.setVisibility(View.GONE);
}
}
mCurrentDragStartPointView.invalidate();
mUiHandler.sendEmptyMessageDelayed(MSG_FILES_DRAG_READY, 10);
}
private void promptMoveFailureDueToPermission(String fromPath,
String targetPath) {
Log.i(TAG, "Move data from dir: " + fromPath + " to dir: " + targetPath);
// Move file drop data to its from directory means no move,
// in that case prompt for drop denied is not necessary.
if (!fromPath.equals(targetPath)) {
Toast.makeText(mContext, R.string.move_failed_permission_deny,
Toast.LENGTH_SHORT).show();
}
}
private void showSearchProgressDialog(String searchPath, String searchStr,
int searchType, final FileOperationTask searchTask) {
if (mSearchDialog == null) {
mSearchDialog = new ProgressDialog(mContext);
}
Resources resources = mContext.getResources();
String name = "";
switch (searchType) {
case StorageUtil.TYPE_AUDIO:
name = resources.getString(R.string.audio_file);
break;
case StorageUtil.TYPE_VIDEO:
name = resources.getString(R.string.video_file);
break;
case StorageUtil.TYPE_IMAGE:
name = resources.getString(R.string.image_file);
break;
case StorageUtil.TYPE_APKFILE:
name = resources.getString(R.string.apk_file);
break;
case StorageUtil.TYPE_FILE:
name = "'" + searchStr + "'";
break;
}
String title;
if (searchType == StorageUtil.TYPE_FILE) {
title = resources.getString(R.string.search_dlg_title, name);
} else {
title = resources.getString(R.string.global_search_dlg_title, name);
}
String message = resources.getString(R.string.search_dlg_message,
searchPath);
mSearchDialog.setTitle(title);
mSearchDialog.setMessage(message);
mSearchDialog.setCancelable(false);
mSearchDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
resources.getString(R.string.cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
searchTask.cancel();
mSearchDialog.dismiss();
}
});
mSearchDialog.show();
}
private void splitCurrentDragBuddies() {
Log.i(TAG, "splitCurrentDragBuddies");
if (mCurrentDragBuddyViewsStacked && mCurrentDragStartPointView != null) {
mCurrentDragStartPointView.setDragBuddies(null);
BadgeView badge = mCurrentDragStartPointView.getBadgeView();
if (badge != null) {
badge.hide();
}
ImageView dragReadyView = mCurrentDragStartPointView
.getDragContextInfo().dragReadyView;
ImageView draggingView = mCurrentDragStartPointView
.getDragContextInfo().draggingView;
View normalView = mCurrentDragStartPointView.getDragContextInfo().normalView;
if (dragReadyView != null) {
dragReadyView.setImageDrawable(null);
dragReadyView.setVisibility(View.GONE);
}
if (draggingView != null) {
draggingView.setImageDrawable(null);
draggingView.setVisibility(View.GONE);
}
if (normalView != null) {
normalView.setVisibility(View.VISIBLE);
}
mCurrentDragStartPointView.invalidate();
mCurrentDragBuddyViewsStacked = false;
}
}
private void stackCurrentDragBuddies() {
if (!mCurrentDragBuddyViewsStacked) {
Log.i(TAG, "stackCurrentDragBuddies");
ImageView dragReadyView = mCurrentDragStartPointView
.getDragContextInfo().dragReadyView;
if (dragReadyView != null) {
dragReadyView.setImageDrawable(mDrawableForStackedDragBuddies);
dragReadyView.setVisibility(View.VISIBLE);
if (mCurrentDragBuddies != null) {
BadgeView badge = new BadgeView(mContext, dragReadyView);
mCurrentDragStartPointView.setBadgeView(badge);
badge.setText(String.format("%d",
mCurrentDragBuddies.size() + 1));
badge.show();
}
}
View normalView = mCurrentDragStartPointView.getDragContextInfo().normalView;
if (normalView != null) {
normalView.setVisibility(View.GONE);
}
mCurrentDragStartPointView.invalidate();
mCurrentDragBuddyViewsStacked = true;
mUiHandler.sendMessageDelayed(
mUiHandler.obtainMessage(MSG_FILES_PREPARE_DRAGGING_VIEW),
10);
}
}
private void updateSearchProgressDialog(String searchPath) {
if (mSearchDialog != null) {
Resources resources = mContext.getResources();
mSearchDialog.setMessage(resources.getString(
R.string.search_dlg_message, searchPath));
}
}
}