diff --git a/project.properties b/project.properties
index 01d3191e6..41cfa65aa 100644
--- a/project.properties
+++ b/project.properties
@@ -13,3 +13,4 @@ java.encoding=utf-8
target=android-14
android.library.reference.1=third-party/AmbilWarna
android.library.reference.2=third-party/drag-sort-listview/library
+android.library.reference.3=third-party/android-filechooser/code
diff --git a/third-party/android-filechooser/LICENSE b/third-party/android-filechooser/LICENSE
new file mode 100755
index 000000000..530faaf0e
--- /dev/null
+++ b/third-party/android-filechooser/LICENSE
@@ -0,0 +1,18 @@
+Copyright (C) 2012 Hai Bison
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/third-party/android-filechooser/NOTICE b/third-party/android-filechooser/NOTICE
new file mode 100755
index 000000000..11615f17f
--- /dev/null
+++ b/third-party/android-filechooser/NOTICE
@@ -0,0 +1,273 @@
+android-filechooser
+
+Version: 5.0
+
+===========
+
+Feel free to contact us at:
+ - Homepage : http://www.haibison.com
+ - E-mails :
+ + haibison.apps(@)gmail(.)com
+ + support(@)haibison(.)com
+
+Or you can join this forum for discussion, and to receive news (new version,
+bugs...), your e-mail address will be kept private:
+ - https://groups.google.com/forum/#!forum/android-filechooser
+
+And here is history:
+
++++ Version 5.0 +++
+ - Release: October 21, 2012
+
+ - We don't use Apache License 2.0 anymore. Now the library is released under
+ MIT license.
+
++++ Version 4.9 +++
+ - Release: October 20, 2012
+
+ - Improves the speed of formatting file time;
+ - Uses a unique filename of SharedPreferences instead of default application's
+ SharedPreferences;
+ - Uses Context.MODE_MULTI_PROCESS for storing global preferences;
+ - Uses a Runnable + setSelection() to select item of list view of files.
+ Because if the list view is handling data, only setSelection() might not
+ work;
+ - Updates NOTICE;
+
++++ Version 4.9 beta +++
+ - Initialize: October 12, 2012
+
++++ Version 4.8.1 +++
+ - Release: October 12, 2012
+
+ - Fixes a bug that file item does not draw properly after flinging it to delete
+ files;
+
++++ Version 4.8 +++
+ - Release: October 12, 2012
+
+ - Fixes a small bug that last location or selected file will be not pushed into
+ history;
+
++++ Version 4.7 +++
+ - Release: October 12, 2012
+
+ - All date formatting utilities were moved from /IFileAdapter to
+ /utils.DateUtils;
+ - Removes key /FileChooserActivity._UseThemeDialog;
+ - Adds options for single tapping/ double tapping to choose files;
+ - Auto remembers last location;
+ - Adds key /FileChooserActivity._SelectFile to select a specific file on
+ startup;
+ - Updates new mime types;
+ - UI for footer;
+ - Minor changes;
+
++++ Version 4.7 beta +++
+ - Initialize: October 02, 2012
+
++++ Version 4.6.2 +++
+ - Release: October 01, 2012
+
+ - Fixes: View does not reload after changing view type between list view and
+ grid view.
+
++++ Version 4.6.1 +++
+ - Release: October 01, 2012
+
+ - Fixes: View does not reload after changing view type between list view and
+ grid view.
+
++++ Version 4.6 +++
+ - Release: October 01, 2012
+
+ - Updates UI;
+ - Removes deprecated method History.push(A, A);
+ - Keeps and shows full history to the user (wherever they have been gone to);
+ - Removes button Cancel in dialogs. Users can tap Back button or touch outside
+ of the dialogs to cancel them;
+ - Moves [/]io.LocalFile to [/]io.localfile.LocalFile;
+ - Fixes:
+ + Issue #6 (thanks to @buckelieg);
+ + Issue #10;
+
++++ Version 4.6 beta +++
+ - Initialize: September 08, 2012
+
++++ Version 4.5 +++
+ - Release: September 07, 2012
+
+ - New icons for menu Home, Reload and for file types audio, image, video,
+plain text and compressed;
+
++++ Version 4.5 beta +++
+ - Initialize: August 31, 2012
+
++++ Version 4.4 +++
+ - Release: August 30, 2012
+
+ - Added languages: Spanish, Vietnamese. Special thanks to C. - a kind friend
+ who helped us translate the library into Spanish;
+
++++ Version 4.3 +++
+ - Release: August 29, 2012
+
+ - Fixed issue #2 (http://code.google.com/p/android-filechooser/issues/detail?id=2);
+ - Upgraded UI;
+ - Added history viewer;
+ - Improved some minor code;
+
++++ Version 4.3 beta +++
+ - Initialization: May 19, 2012
+
++++ Version 4.2 +++
+ - Release: May 15, 2012
+
+ - due to this bug: http://code.google.com/p/android/issues/detail?id=30622,
+ so we prefix all resource names with 'afc_';
+ - add small text view below location bar, to show current location's full name
+ if it is truncated by the view's ellipsize property;
+ - save and restore state after screen orientation changed (except selected items
+ in multi-selection mode);
+ - add menu Reload;
+ - some UI fixes/ updates;
+
++++ Version 4.2 beta +++
+ - Initialization: May 13, 2012
+
++++ Version 4.1 +++
+ - Release: May 12, 2012
+
+ - update UI messages;
+ - if the app does not have permission WRITE_EXTERNAL_STORAGE, notify user
+ when he creates or deletes folder/ file;
+ - make location bar hold buttons of directories, which user can click to
+ go to;
+
++++ Version 4.1 beta +++
+ - Initialization: May 11, 2012
+
++++ Version 4.0 - Tablet +++
+ - Release: May 11, 2012
+
+ - add Home button;
+ - add grid view/ list view mode;
+ - allow creating new directory;
+ - allow deleting a single file/ directory by flinging its name;
+ - use android-support-v13.jar:
+ + show menu items as actions from API 11 and up;
+ + support new Android layout;
+ - change to new icons;
+ - some minor changes;
+
++++ Version 4.0 beta +++
+ - Initialization: May 08, 2012
+
++++ Version 3.5 +++
+ - Release: May 01, 2012
+
+ - remove button Cancel (use default Back button of system)
+ - hello May Day :-)
+
++++ Version 3.4 +++
+ - Release: March 23, 2012
+
+ - fix serious bug: hardcode service action name of local file provider;
+ the service will be called as a remote service, which will raise
+ fatal exception if there are multiple instances of the library installed
+ on the device;
+
++++ Version 3.3 +++
+ - Release: March 22, 2012
+
+ - fix bug in LoadingDialog: if the user finishes the owner activity,
+ the application can crash if the dialog is going to show up or dismiss;
+ - improve FileChooserActivity: make its height and width always fit the
+ screen size in dialog theme;
+
++++ Version 3.2 +++
+ - Release: March 16, 2012
+
+ - add package io: IFile and LocalFile;
+ - use IFile instead of java.io.File;
+ - remove FileContainer and package bean;
+
++++ Version 3.1 +++
+ - Release: March 15, 2012
+
+ - add FileProviderService;
+
++++ Version 3.0 +++
+ - Release: March 15, 2012
+
+ - move file listing functions to external service;
+ - change project name from FileChooser to android-filechooser :-D
+ - some minor changes:
+ + UI messages;
+ + icons;
+ + make LoadingDialog use AsyncTask instead of Thread;
+ + ...
+
++++ Version 2.0 +++
+ - Release: Feb 22, 2012
+
+ - change default date format to "yyyy.MM.dd hh:mm a";
+ - try using sdcard as rootpath if it is not specified; if sdcard is not available, use "/";
+ - add sorter (by name/ size/ date);
+ - show directories' date (last modified);
+
++++ Version 1.91 +++
+ - Release: Feb 06, 2012
+
+ - Add: show file time (last modified);
+
++++ Version 1.9 +++
+ - Release: Feb 06, 2012
+
+ - Fix: crash if cast footer of listview to DataModel;
+
++++ Version 1.8.2 +++
+ - Release: Feb 06, 2012
+
+ - enable fast scroll of the list view;
+
++++ Version 1.8.1 +++
+ - Release: Feb 05, 2012
+
+ - Fix: it doesn't remember the first path (rootpath) in history;
+
++++ Version 1.8 +++
+ - Release: Feb 05, 2012
+
+ - Shows progress dialog while listing files of a directory;
+ - Adds flag max file count allowed, in case the directory has thousands of files,
+ the application can harm memory. Default value is 1,024;
+ - TODO: let the user cancel the method java.io.File.listFiles().
+ It seems this is up to Android developers :-)
+
++++ Version 1.7 +++
+ - Release: Jan 22, 2012
+
+ - add function to check if filename (in save dialog mode) is valid or not;
+ - change name FilesAdapter to FileAdapter;
+
++++ Version 1.6 +++
+ - Release: Jan 13, 2012
+
+ - check and warn user if save as filename is a directory;
+ - when finish, return some flags for further use (in case the
+ caller needs);
+
++++ Version 1.5 +++
+ - Release: Jan 13, 2012
+
+ - apply Apache License 2.0;
+ - set result code to RESULT_CANCELED when user clicks button Cancel;
+
++++ Version 1.4 +++
+ - Release: Jan 08, 2012
+
+ - first publishing;
+ - choose file(s) dialog;
+ - choose file(s) and/or directory(ies) dialog;
+ - save as dialog;
diff --git a/third-party/android-filechooser/code/AndroidManifest.xml b/third-party/android-filechooser/code/AndroidManifest.xml
new file mode 100755
index 000000000..431c8d6a5
--- /dev/null
+++ b/third-party/android-filechooser/code/AndroidManifest.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/build.xml b/third-party/android-filechooser/code/build.xml
new file mode 100755
index 000000000..716fae9ee
--- /dev/null
+++ b/third-party/android-filechooser/code/build.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/proguard-project.txt b/third-party/android-filechooser/code/proguard-project.txt
new file mode 100755
index 000000000..f2fe1559a
--- /dev/null
+++ b/third-party/android-filechooser/code/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/third-party/android-filechooser/code/proguard.cfg b/third-party/android-filechooser/code/proguard.cfg
new file mode 100755
index 000000000..b1cdf17b5
--- /dev/null
+++ b/third-party/android-filechooser/code/proguard.cfg
@@ -0,0 +1,40 @@
+-optimizationpasses 5
+-dontusemixedcaseclassnames
+-dontskipnonpubliclibraryclasses
+-dontpreverify
+-verbose
+-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+-keep public class * extends android.app.backup.BackupAgentHelper
+-keep public class * extends android.preference.Preference
+-keep public class com.android.vending.licensing.ILicensingService
+
+-keepclasseswithmembernames class * {
+ native ;
+}
+
+-keepclasseswithmembers class * {
+ public (android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public (android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * extends android.app.Activity {
+ public void *(android.view.View);
+}
+
+-keepclassmembers enum * {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+-keep class * implements android.os.Parcelable {
+ public static final android.os.Parcelable$Creator *;
+}
diff --git a/third-party/android-filechooser/code/project.properties b/third-party/android-filechooser/code/project.properties
new file mode 100755
index 000000000..d52557723
--- /dev/null
+++ b/third-party/android-filechooser/code/project.properties
@@ -0,0 +1,12 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system use,
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-14
+android.library=true
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..c93964e77
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_home.png
new file mode 100755
index 000000000..72305cbec
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_listview.png
new file mode 100755
index 000000000..7b2e487bd
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_reload.png
new file mode 100755
index 000000000..1ed03f018
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..60873cf60
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..7cebfcdee
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..038546d62
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..bad538983
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..7772d62eb
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..5497e1476
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi-v11/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder.png
new file mode 100644
index 000000000..065383947
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder_disabled.png
new file mode 100644
index 000000000..2660e6fe0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder_pressed.png
new file mode 100644
index 000000000..ad50c0e83
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_create_folder_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid.png
new file mode 100644
index 000000000..6a94b4e90
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid_disabled.png
new file mode 100644
index 000000000..69b10f1e0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid_pressed.png
new file mode 100644
index 000000000..2a1172eb0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_grid_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list.png
new file mode 100644
index 000000000..a1b4eabe3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list_disabled.png
new file mode 100644
index 000000000..cf7ead6e1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list_pressed.png
new file mode 100644
index 000000000..a296a74da
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_folders_view_list_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left.png
new file mode 100644
index 000000000..71a2b2bbb
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left_disabled.png
new file mode 100755
index 000000000..d069ca2a0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left_pressed.png
new file mode 100755
index 000000000..3f1618067
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_left_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right.png
new file mode 100755
index 000000000..41a2ae2ee
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right_disabled.png
new file mode 100755
index 000000000..2c8c9e32d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right_pressed.png
new file mode 100755
index 000000000..c4a47a304
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_navi_right_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_ok_saveas.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_ok_saveas.png
new file mode 100755
index 000000000..dff270757
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_ok_saveas.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_ok_saveas_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_ok_saveas_pressed.png
new file mode 100755
index 000000000..358a571c7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_ok_saveas_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as.png
new file mode 100644
index 000000000..9accaa699
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as_disabled.png
new file mode 100644
index 000000000..5bd58d4b9
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as_pressed.png
new file mode 100644
index 000000000..b3387253b
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_as_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de.png
new file mode 100644
index 000000000..e233487ae
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de_disabled.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de_disabled.png
new file mode 100644
index 000000000..6e40c36b8
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de_pressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de_pressed.png
new file mode 100644
index 000000000..cf355aa65
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_button_sort_de_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_context_menu_item_divider.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_context_menu_item_divider.png
new file mode 100755
index 000000000..eba06e25e
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_context_menu_item_divider.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_file.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file.png
new file mode 100755
index 000000000..fcf239cf9
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_audio.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_audio.png
new file mode 100755
index 000000000..5d21334ad
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_audio.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_compressed.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_compressed.png
new file mode 100755
index 000000000..0fe46f32f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_compressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_image.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_image.png
new file mode 100755
index 000000000..ccc114009
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_image.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_plain_text.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_plain_text.png
new file mode 100755
index 000000000..fe20bb44d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_plain_text.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_video.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_video.png
new file mode 100755
index 000000000..21596889e
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_file_video.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_folder.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_folder.png
new file mode 100644
index 000000000..d7629aef7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_folder.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_folder_locked.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_folder_locked.png
new file mode 100644
index 000000000..1705a11e1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_folder_locked.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..e5f007da7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_home.png
new file mode 100755
index 000000000..d5bf46541
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_listview.png
new file mode 100755
index 000000000..428553da4
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_reload.png
new file mode 100755
index 000000000..04ae1dbcc
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..93cd66bdc
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..5d6161820
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..0994e963c
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..f3b90c58c
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..b0248642c
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..3fab84c2a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-hdpi/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..d65bb4e95
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_home.png
new file mode 100755
index 000000000..1b85f9ae7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_listview.png
new file mode 100755
index 000000000..fc288784f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_reload.png
new file mode 100755
index 000000000..16f86cfa3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..0bdf02a16
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..d51b86ba9
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..7dd1e11c1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..79838ec8f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..44fda6301
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..76c061a5b
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi-v11/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left.png
new file mode 100755
index 000000000..9d730f8da
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left_disabled.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left_disabled.png
new file mode 100755
index 000000000..33346b201
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left_pressed.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left_pressed.png
new file mode 100755
index 000000000..d668d8fe3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_left_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right.png
new file mode 100755
index 000000000..03c67d5ab
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right_disabled.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right_disabled.png
new file mode 100755
index 000000000..1734c0a6d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right_pressed.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right_pressed.png
new file mode 100755
index 000000000..c57ab9ec1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_navi_right_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_ok_saveas.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_ok_saveas.png
new file mode 100755
index 000000000..2551cb028
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_ok_saveas.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_ok_saveas_pressed.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_ok_saveas_pressed.png
new file mode 100755
index 000000000..32cbaf1ff
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_button_ok_saveas_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_context_menu_item_divider.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_context_menu_item_divider.png
new file mode 100755
index 000000000..31988f947
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_context_menu_item_divider.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_file.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file.png
new file mode 100755
index 000000000..3df85c804
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_audio.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_audio.png
new file mode 100755
index 000000000..c0432e97d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_audio.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_compressed.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_compressed.png
new file mode 100755
index 000000000..44832586a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_compressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_image.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_image.png
new file mode 100755
index 000000000..1ff8c5240
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_image.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_plain_text.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_plain_text.png
new file mode 100755
index 000000000..8e3c81a1b
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_plain_text.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_video.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_video.png
new file mode 100755
index 000000000..4424caccf
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_file_video.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_folder.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_folder.png
new file mode 100644
index 000000000..d7629aef7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_folder.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_folder_locked.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_folder_locked.png
new file mode 100644
index 000000000..1705a11e1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_folder_locked.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..9756336ef
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_home.png
new file mode 100755
index 000000000..be4e35b25
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_listview.png
new file mode 100755
index 000000000..bfa02fd80
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_reload.png
new file mode 100755
index 000000000..e8f658adc
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..af94a1315
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..2bd3fe623
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..80b408eb0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..cc69cc265
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..a72437454
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..e61dc50d3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-ldpi/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..69f766270
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_home.png
new file mode 100755
index 000000000..cb89c8f9d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_listview.png
new file mode 100755
index 000000000..226042a44
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_reload.png
new file mode 100755
index 000000000..a75b6d73d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..ca2f1a74f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..ba9658788
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..8daa7febc
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..6e53d2311
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..777c94947
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..b9290a3d0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi-v11/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left.png
new file mode 100755
index 000000000..0c7e069b7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left_disabled.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left_disabled.png
new file mode 100755
index 000000000..fb744df3a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left_pressed.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left_pressed.png
new file mode 100755
index 000000000..81329de0f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_left_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right.png
new file mode 100755
index 000000000..44fe22b76
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right_disabled.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right_disabled.png
new file mode 100755
index 000000000..989209d9f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right_pressed.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right_pressed.png
new file mode 100755
index 000000000..32183b1c0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_navi_right_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_ok_saveas.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_ok_saveas.png
new file mode 100755
index 000000000..01eff9826
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_ok_saveas.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_ok_saveas_pressed.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_ok_saveas_pressed.png
new file mode 100755
index 000000000..90bafe831
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_button_ok_saveas_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_context_menu_item_divider.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_context_menu_item_divider.png
new file mode 100755
index 000000000..1cb23d927
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_context_menu_item_divider.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_file.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file.png
new file mode 100755
index 000000000..91a494a22
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_audio.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_audio.png
new file mode 100755
index 000000000..6614e53d9
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_audio.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_compressed.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_compressed.png
new file mode 100755
index 000000000..bd522fa0d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_compressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_image.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_image.png
new file mode 100755
index 000000000..677ce77d3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_image.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_plain_text.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_plain_text.png
new file mode 100755
index 000000000..74e5fc89d
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_plain_text.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_video.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_video.png
new file mode 100755
index 000000000..7e68e8b23
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_file_video.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_folder.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_folder.png
new file mode 100644
index 000000000..d7629aef7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_folder.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_folder_locked.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_folder_locked.png
new file mode 100644
index 000000000..1705a11e1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_folder_locked.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..db52be166
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_home.png
new file mode 100755
index 000000000..284fbe084
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_listview.png
new file mode 100755
index 000000000..cd1025610
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_reload.png
new file mode 100755
index 000000000..9841ba415
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..77cc5b262
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..dd10b070a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..15ee746d1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..05a0a9047
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..e30b379bc
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..c71524ac6
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-mdpi/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..019dc18d4
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_home.png
new file mode 100755
index 000000000..bec48ec04
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_listview.png
new file mode 100755
index 000000000..1e2c31af0
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_reload.png
new file mode 100755
index 000000000..4531d20e4
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..f38791bc2
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..98d53e8b7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..c9b246024
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..0711902f3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..929608368
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..ddb53f823
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi-v11/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left.png
new file mode 100755
index 000000000..7ff958bc3
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left_disabled.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left_disabled.png
new file mode 100755
index 000000000..3aaface84
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left_pressed.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left_pressed.png
new file mode 100755
index 000000000..ccc0a1a46
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_left_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right.png
new file mode 100755
index 000000000..778dc246a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right_disabled.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right_disabled.png
new file mode 100755
index 000000000..8f3362dbb
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right_disabled.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right_pressed.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right_pressed.png
new file mode 100755
index 000000000..ff0d91b0b
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_navi_right_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_ok_saveas.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_ok_saveas.png
new file mode 100755
index 000000000..7a70073d6
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_ok_saveas.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_ok_saveas_pressed.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_ok_saveas_pressed.png
new file mode 100755
index 000000000..02994cc5a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_button_ok_saveas_pressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_context_menu_item_divider.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_context_menu_item_divider.png
new file mode 100755
index 000000000..d69823b60
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_context_menu_item_divider.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file.png
new file mode 100755
index 000000000..3744656b2
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_audio.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_audio.png
new file mode 100755
index 000000000..c93678166
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_audio.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_compressed.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_compressed.png
new file mode 100755
index 000000000..87270f8dc
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_compressed.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_image.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_image.png
new file mode 100755
index 000000000..9da2f5de9
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_image.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_plain_text.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_plain_text.png
new file mode 100755
index 000000000..6ae1b983f
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_plain_text.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_video.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_video.png
new file mode 100755
index 000000000..c508431c6
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_file_video.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_folder.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_folder.png
new file mode 100644
index 000000000..d7629aef7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_folder.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_folder_locked.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_folder_locked.png
new file mode 100644
index 000000000..1705a11e1
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_folder_locked.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_gridview.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_gridview.png
new file mode 100755
index 000000000..b5ca4d015
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_gridview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_home.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_home.png
new file mode 100755
index 000000000..903dbbe11
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_home.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_listview.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_listview.png
new file mode 100755
index 000000000..9ce6bb757
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_listview.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_reload.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_reload.png
new file mode 100755
index 000000000..6d2e14ae7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_reload.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_date_asc.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_date_asc.png
new file mode 100755
index 000000000..b618ef5c7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_date_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_date_desc.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_date_desc.png
new file mode 100755
index 000000000..eff5fce6a
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_date_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_name_asc.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_name_asc.png
new file mode 100755
index 000000000..3377d28b7
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_name_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_name_desc.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_name_desc.png
new file mode 100755
index 000000000..8aa3d4992
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_name_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_size_asc.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_size_asc.png
new file mode 100755
index 000000000..0a71054b5
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_size_asc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_size_desc.png b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_size_desc.png
new file mode 100755
index 000000000..477acaf04
Binary files /dev/null and b/third-party/android-filechooser/code/res/drawable-xhdpi/afc_ic_menu_sort_by_size_desc.png differ
diff --git a/third-party/android-filechooser/code/res/drawable/afc_button_location_dark_pressed.xml b/third-party/android-filechooser/code/res/drawable/afc_button_location_dark_pressed.xml
new file mode 100755
index 000000000..0cfca1235
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_button_location_dark_pressed.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_create_folder.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_create_folder.xml
new file mode 100755
index 000000000..0d6c63cb0
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_create_folder.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_folders_view_grid.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_folders_view_grid.xml
new file mode 100755
index 000000000..5886530a5
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_folders_view_grid.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_folders_view_list.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_folders_view_list.xml
new file mode 100755
index 000000000..969faaf5a
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_folders_view_list.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_location_dark.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_location_dark.xml
new file mode 100755
index 000000000..dc2f94ddb
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_location_dark.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_navi_left.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_navi_left.xml
new file mode 100755
index 000000000..4734e3758
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_navi_left.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_navi_right.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_navi_right.xml
new file mode 100755
index 000000000..d0a36205e
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_navi_right.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_ok_saveas.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_ok_saveas.xml
new file mode 100755
index 000000000..2d4b37ea5
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_ok_saveas.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_sort_as.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_sort_as.xml
new file mode 100755
index 000000000..8e0e25dd3
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_sort_as.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/drawable/afc_selector_button_sort_de.xml b/third-party/android-filechooser/code/res/drawable/afc_selector_button_sort_de.xml
new file mode 100755
index 000000000..c1bc07805
--- /dev/null
+++ b/third-party/android-filechooser/code/res/drawable/afc_selector_button_sort_de.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/layout-v11/afc_file_chooser.xml b/third-party/android-filechooser/code/res/layout-v11/afc_file_chooser.xml
new file mode 100755
index 000000000..1e523ca0a
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout-v11/afc_file_chooser.xml
@@ -0,0 +1,215 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/layout-v11/afc_settings_sort_view.xml b/third-party/android-filechooser/code/res/layout-v11/afc_settings_sort_view.xml
new file mode 100755
index 000000000..9bdad4691
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout-v11/afc_settings_sort_view.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_button_location.xml b/third-party/android-filechooser/code/res/layout/afc_button_location.xml
new file mode 100755
index 000000000..ca4b26c79
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_button_location.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_context_menu_tiem.xml b/third-party/android-filechooser/code/res/layout/afc_context_menu_tiem.xml
new file mode 100755
index 000000000..22bb8cf8d
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_context_menu_tiem.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_context_menu_view.xml b/third-party/android-filechooser/code/res/layout/afc_context_menu_view.xml
new file mode 100755
index 000000000..6e6d31917
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_context_menu_view.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_file_chooser.xml b/third-party/android-filechooser/code/res/layout/afc_file_chooser.xml
new file mode 100755
index 000000000..935c1ed90
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_file_chooser.xml
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_file_item.xml b/third-party/android-filechooser/code/res/layout/afc_file_item.xml
new file mode 100755
index 000000000..e7f2925d0
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_file_item.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_gridview_files.xml b/third-party/android-filechooser/code/res/layout/afc_gridview_files.xml
new file mode 100755
index 000000000..97d04bd6f
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_gridview_files.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_listview_files.xml b/third-party/android-filechooser/code/res/layout/afc_listview_files.xml
new file mode 100755
index 000000000..f7bc4f72c
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_listview_files.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_settings_sort_view.xml b/third-party/android-filechooser/code/res/layout/afc_settings_sort_view.xml
new file mode 100755
index 000000000..0d4da1b68
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_settings_sort_view.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/layout/afc_simple_text_input_view.xml b/third-party/android-filechooser/code/res/layout/afc_simple_text_input_view.xml
new file mode 100755
index 000000000..581f7d824
--- /dev/null
+++ b/third-party/android-filechooser/code/res/layout/afc_simple_text_input_view.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/menu/afc_file_chooser_activity.xml b/third-party/android-filechooser/code/res/menu/afc_file_chooser_activity.xml
new file mode 100755
index 000000000..ef678507a
--- /dev/null
+++ b/third-party/android-filechooser/code/res/menu/afc_file_chooser_activity.xml
@@ -0,0 +1,26 @@
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/values-es/strings.xml b/third-party/android-filechooser/code/res/values-es/strings.xml
new file mode 100755
index 000000000..c3fe58ccd
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-es/strings.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ Todos
+ Invertir selección
+ Ninguno
+ Limpiar
+ Cuadricula
+ Inicio
+ Lista
+ Nuevo directorio…
+ Recargar
+ Eliminar de la lista
+ Seleccionar todos los ficheros
+ Seleccionar todas los directorios
+ Ordenar…
+ …
+ fichero
+ directorio
+ Doble clic para seleccionar fichero/directorio
+ nombre de directorio
+ nombre de fichero
+ La aplicación no tiene permisos para crear ficheros/directorios
+ La aplicación no tiene permisos para eliminar ficheros/directorios
+ Cancelado
+ No se puede conectar con el servicio proveedor de ficheros
+ Hecho
+ …vacío
+ Nombre de fichero vacío
+ Cargando…
+ No se puede acceder a \"%1$s\"
+ No se puede crear el directorio \"%1$s\"
+ No se puede borrar %1$s \"%2$s\"
+ ¿Seguro que deseas eliminar este %1$s \"%2$s\"?
+ El fichero \"%1$s\" ya existe.\n\n¿Quieres reemplazarlo?
+ Eliminando %1$s \"%2$s\"…
+ …%1$s \"%2$s\" ha sido eliminado
+ \"%1$s\" es un directorio
+ El nombre de fichero \"%1$s\" no es válido
+ …tiene mas ficheros, máximos permitidos: %1$,d
+ Error desconocido: %1$s
+ %1$,d elementos
+ Raiz
+ Seleccionar…
+ Alerta
+ Seleccionar directorios…
+ Seleccionar ficheros…
+ Seleccionar ficheros/directorios…
+ Confirmación
+ Fecha
+ Error
+ Historial
+ Información
+ Nombre
+ Guardar como…
+ Tamaño
+ Ordenar por…
+ Ayer
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values-hdpi/dimens.xml b/third-party/android-filechooser/code/res/values-hdpi/dimens.xml
new file mode 100755
index 000000000..8e072f938
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-hdpi/dimens.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ 48px
+ 48px
+ 72px
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values-ldpi/dimens.xml b/third-party/android-filechooser/code/res/values-ldpi/dimens.xml
new file mode 100755
index 000000000..5b8d51f7a
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-ldpi/dimens.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ 24px
+ 24px
+ 36px
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values-mdpi/dimens.xml b/third-party/android-filechooser/code/res/values-mdpi/dimens.xml
new file mode 100755
index 000000000..35c4477c5
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-mdpi/dimens.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ 32px
+ 32px
+ 48px
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values-ru/strings.xml b/third-party/android-filechooser/code/res/values-ru/strings.xml
new file mode 100644
index 000000000..d7d83b087
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-ru/strings.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+ Все
+ Инвертировать выделение
+ Ни один
+ Очистить
+ Таблицей
+ Домой
+ Списком
+ Создать папку…
+ Обновить
+ Удалить из списка
+ Выбрать все файлы
+ Выбрать все папки
+ Сортировать…
+ …
+ файл
+ папка
+ Нажмите дважды, чтобы выбрать файл/ папку
+ имя папки
+ имя файла
+ Недостаточно прав для создания файлов/ папок
+ Недостаточно прав для удаления файлов/ папок
+ Отмена
+ Невозможно соединиться с сервисом
+ Готово
+ …пусто
+ Имя файла не может быть пустым
+ Загружается…
+ Нет доступа к \"%1$s\"
+ Невозможно создать папку \"%1$s\"
+ Невозможно удалить %1$s \"%2$s\"
+ Удалить файл %1$s \"%2$s\"?
+ Файл \"%1$s\" уже существует.\n\nПерезаписать?
+ Удаление %1$s \"%2$s\"…
+ Файл %1$s \"%2$s\" удалён
+ \"%1$s\" имя папки
+ Невозможно назвать файл \"%1$s\"
+ …содержит другие файлы, возможный максимум: %1$,d
+ Неизвестная ошибка: %1$s
+ %1$,d файлов
+ Корень
+ Выберите…
+ Внимание!
+ Выберите папки…
+ Выберите файл…
+ Выберите файл/ папку…
+ Внимание!
+ Дата
+ Ошибка
+ История
+ Информация
+ Имя
+ Сохранить как…
+ Размер
+ Сортировать по…
+ Вчера
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values-v11/styles.xml b/third-party/android-filechooser/code/res/values-v11/styles.xml
new file mode 100755
index 000000000..ebeadc4c7
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-v11/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/values-v14/styles.xml b/third-party/android-filechooser/code/res/values-v14/styles.xml
new file mode 100755
index 000000000..23994d3ef
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-v14/styles.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/res/values-vi/strings.xml b/third-party/android-filechooser/code/res/values-vi/strings.xml
new file mode 100755
index 000000000..c3397edbe
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-vi/strings.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+ Tất cả
+ Đảo lựa chọn
+ Không chọn
+ Xóa hết
+ Lưới
+ Nhà
+ Danh sách
+ Tạo thư mục mới…
+ Tải lại
+ Xóa khỏi danh sách
+ Chọn hết tập tin
+ Chọn hết thư mục
+ Sắp xếp…
+ …
+ tập tin
+ thư mục
+ Chạm 2 lần để chọn tập tin/ thư mục…
+ tên thư mục
+ tên tập tin
+ Ứng dụng này không có quyền tạo mới tập tin/ thư mục
+ Ứng dụng này không có quyền xóa tập tin/ thư mục
+ Hủy bỏ
+ Không thể kết nối đến dịch vụ cung cấp tập tin
+ Xong
+ …trống
+ Tên tập tin không hợp lệ
+ Đang tải…
+ Không thể truy cập \"%1$s\"
+ Không thể tạo thư mục \"%1$s\"
+ Không thể xóa %1$s \"%2$s\"
+ Bạn có chắc muốn xóa %1$s \"%2$s\"?
+ Tập tin \"%1$s\" đã có.\n\nBạn có muốn ghi đè lên?
+ Đang xóa %1$s \"%2$s\"…
+ …%1$s \"%2$s\" đã được xoá
+ \"%1$s\" là một thư mục
+ Tên tập tin \"%1$s\" không hợp lệ
+ …còn nhiều tập tin hơn, cho phép hiển thị: %1$,d
+ Không rõ lỗi: %1$s
+ %1$,d lựa chọn
+ Chọn…
+ Cảnh báo
+ Chọn thư mục…
+ Chọn tập tin…
+ Chọn tập tin/ thư mục…
+ Xác nhận
+ Ngày tháng
+ Lỗi
+ Lịch sử
+ Thông tin
+ Tên
+ Lưu…
+ Kích thước
+ Sắp xếp theo…
+ Hôm qua
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values-xhdpi/dimens.xml b/third-party/android-filechooser/code/res/values-xhdpi/dimens.xml
new file mode 100755
index 000000000..bf7c5bf86
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values-xhdpi/dimens.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ 72px
+ 72px
+ 96px
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values/colors.xml b/third-party/android-filechooser/code/res/values/colors.xml
new file mode 100755
index 000000000..f9c427221
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values/colors.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+ #33B5E5
+
+
diff --git a/third-party/android-filechooser/code/res/values/dimens.xml b/third-party/android-filechooser/code/res/values/dimens.xml
new file mode 100755
index 000000000..624c038f8
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values/dimens.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+ 30dp
+ 15dp
+ 10dp
+ 5dp
+ 256sp
+ 15sp
+ 18sp
+ 192sp
+ 1dp
+
+
diff --git a/third-party/android-filechooser/code/res/values/preferences.xml b/third-party/android-filechooser/code/res/values/preferences.xml
new file mode 100755
index 000000000..555733353
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values/preferences.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+ afc.display.view_type
+ afc.display.sort_type
+ afc.display.sort_ascending
+ afc.display.show_time_for_old_days_this_year
+ afc.display.show_time_for_old_days
+ afc.display.remember_last_location
+ afc.display.last_location
+
+ 0
+ 0
+
+ true
+ false
+ false
+ true
+
+
\ No newline at end of file
diff --git a/third-party/android-filechooser/code/res/values/strings.xml b/third-party/android-filechooser/code/res/values/strings.xml
new file mode 100755
index 000000000..948b987ad
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values/strings.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+ android-filechooser
+ All
+ Invert selection
+ None
+ Clear
+ Grid view
+ Home
+ List view
+ New folder…
+ Reload
+ Remove from list
+ Select all files
+ Select all folders
+ Sort…
+ …
+ file
+ folder
+ Double tap to select file/ folder
+ folder name
+ filename
+ This application does not have permission to create files/ folders
+ This application does not have permission to delete files/ folders
+ Cancelled
+ Can not connect to file provider service
+ Done
+ …empty
+ Filename is empty
+ Loading…
+ Can not access \"%1$s\"
+ Can not create folder \"%1$s\"
+ Can not delete %1$s \"%2$s\"
+ Are you sure you want to delete this %1$s \"%2$s\"?
+ This file \"%1$s\" already exists.\n\nDo you want to replace it?
+ Deleting %1$s \"%2$s\"…
+ …%1$s \"%2$s\" has been deleted
+ \"%1$s\" is a folder
+ File name \"%1$s\" is invalid
+ …has more files, max allowed: %1$,d
+ Unknown error: %1$s
+ %1$,d items
+ Root
+ Select…
+ Alert
+ Choose folders…
+ Choose files…
+ Choose files/ folders…
+ Confirmation
+ Date
+ Error
+ History
+ Info
+ Name
+ Save as…
+ Size
+ Sort by…
+ Yesterday
+ Can\'t create folder in this directory
+ Can\'t choose this folder
+
+
diff --git a/third-party/android-filechooser/code/res/values/styles.xml b/third-party/android-filechooser/code/res/values/styles.xml
new file mode 100755
index 000000000..053712192
--- /dev/null
+++ b/third-party/android-filechooser/code/res/values/styles.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/third-party/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/FileChooserActivity.java b/third-party/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/FileChooserActivity.java
new file mode 100755
index 000000000..d8093813b
--- /dev/null
+++ b/third-party/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/FileChooserActivity.java
@@ -0,0 +1,1910 @@
+/*
+ * 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;
+
+import group.pals.android.lib.ui.filechooser.io.IFile;
+import group.pals.android.lib.ui.filechooser.io.IFileFilter;
+import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs;
+import group.pals.android.lib.ui.filechooser.services.FileProviderService;
+import group.pals.android.lib.ui.filechooser.services.IFileProvider;
+import group.pals.android.lib.ui.filechooser.services.IFileProvider.FilterMode;
+import group.pals.android.lib.ui.filechooser.services.IFileProvider.SortOrder;
+import group.pals.android.lib.ui.filechooser.services.IFileProvider.SortType;
+import group.pals.android.lib.ui.filechooser.services.LocalFileProvider;
+import group.pals.android.lib.ui.filechooser.utils.ActivityCompat;
+import group.pals.android.lib.ui.filechooser.utils.E;
+import group.pals.android.lib.ui.filechooser.utils.FileComparator;
+import group.pals.android.lib.ui.filechooser.utils.FileUtils;
+import group.pals.android.lib.ui.filechooser.utils.Ui;
+import group.pals.android.lib.ui.filechooser.utils.Utils;
+import group.pals.android.lib.ui.filechooser.utils.history.History;
+import group.pals.android.lib.ui.filechooser.utils.history.HistoryFilter;
+import group.pals.android.lib.ui.filechooser.utils.history.HistoryListener;
+import group.pals.android.lib.ui.filechooser.utils.history.HistoryStore;
+import group.pals.android.lib.ui.filechooser.utils.ui.Dlg;
+import group.pals.android.lib.ui.filechooser.utils.ui.LoadingDialog;
+import group.pals.android.lib.ui.filechooser.utils.ui.TaskListener;
+import group.pals.android.lib.ui.filechooser.utils.ui.ViewFilesContextMenuUtils;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.inputmethod.EditorInfo;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.GridView;
+import android.widget.HorizontalScrollView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+/**
+ * Main activity for this library.
+ *
+ * Notes:
+ *
+ * I. About keys {@link FileChooserActivity#_Rootpath},
+ * {@link FileChooserActivity#_SelectFile} and preference
+ * {@link DisplayPrefs#isRememberLastLocation(Context)}, the priorities of them
+ * are:
+ *
+ *
+ * @since v4.3 beta
+ */
+ public static final String _Theme = _ClassName + ".theme";
+
+ /**
+ * Key to hold the root path.
+ *
+ * If {@link LocalFileProvider} is used, then default is sdcard, if sdcard
+ * is not available, "/" will be used.
+ *
+ * Note: The value of this key is a {@link IFile}
+ */
+ public static final String _Rootpath = _ClassName + ".rootpath";
+
+ /**
+ * Key to hold the service class which implements {@link IFileProvider}.
+ * Default is {@link LocalFileProvider}
+ */
+ public static final String _FileProviderClass = _ClassName + ".file_provider_class";
+
+ // ---------------------------------------------------------
+
+ /**
+ * Key to hold {@link IFileProvider.FilterMode}, default is
+ * {@link IFileProvider.FilterMode#FilesOnly}.
+ */
+ public static final String _FilterMode = IFileProvider.FilterMode.class.getName();
+
+ // flags
+
+ // ---------------------------------------------------------
+
+ /**
+ * Key to hold max file count that's allowed to be listed, default =
+ * {@code 1024}
+ */
+ public static final String _MaxFileCount = _ClassName + ".max_file_count";
+ /**
+ * Key to hold multi-selection mode, default = {@code false}
+ */
+ public static final String _MultiSelection = _ClassName + ".multi_selection";
+ /**
+ * Key to hold regex filename filter, default = {@code null}
+ */
+ public static final String _RegexFilenameFilter = _ClassName + ".regex_filename_filter";
+ /**
+ * Key to hold display-hidden-files, default = {@code false}
+ */
+ public static final String _DisplayHiddenFiles = _ClassName + ".display_hidden_files";
+ /**
+ * Sets this to {@code true} to enable double tapping to choose files/
+ * directories. In older versions, double tapping is default. However, since
+ * v4.7 beta, single tapping is default. So if you want to keep the old way,
+ * please set this key to {@code true}.
+ *
+ * @since v4.7 beta
+ */
+ public static final String _DoubleTapToChooseFiles = _ClassName + ".double_tap_to_choose_files";
+ /**
+ * Sets the file you want to select when starting this activity. The file is
+ * an {@link IFile}.
+ * Notes:
+ *
Currently this key is only used for single selection mode.
+ *
+ *
If you use save dialog mode, this key will override key
+ * {@link #_DefaultFilename}.
+ *
+ * @since v4.7 beta
+ */
+ public static final String _SelectFile = _ClassName + ".select_file";
+
+ // ---------------------------------------------------------
+
+ /**
+ * Key to hold property save-dialog, default = {@code false}
+ */
+ public static final String _SaveDialog = _ClassName + ".save_dialog";
+ public static final String _ActionBar = _ClassName + ".action_bar";
+ /**
+ * Key to hold default filename, default = {@code null}
+ */
+ public static final String _DefaultFilename = _ClassName + ".default_filename";
+ /**
+ * Key to hold results (can be one or multiple files)
+ */
+ public static final String _Results = _ClassName + ".results";
+ public static final String _FileSelectionMode = _ClassName + ".file_selection_mode";
+ public static final String _FolderPath = _ClassName + ".folder_path";
+ public static final String _SaveLastLocation = _ClassName + ".save_last_location";
+
+ /**
+ * This key holds current location (an {@link IFile}), to restore it after
+ * screen orientation changed
+ */
+ static final String _CurrentLocation = _ClassName + ".current_location";
+ /**
+ * This key holds current history (a {@link History}<{@link IFile}>),
+ * to restore it after screen orientation changed
+ */
+ static final String _History = _ClassName + ".history";
+
+ /**
+ * This key holds current full history (a {@link History}< {@link IFile}
+ * >), to restore it after screen orientation changed.
+ */
+ static final String _FullHistory = History.class.getName() + "_full";
+
+ // ====================
+ // "CONSTANT" VARIABLES
+
+ private Class> mFileProviderServiceClass;
+ /**
+ * The file provider service.
+ */
+ private IFileProvider mFileProvider;
+ /**
+ * The service connection.
+ */
+ private ServiceConnection mServiceConnection;
+
+ private IFile mRoot;
+ private boolean mIsMultiSelection;
+ private boolean mIsSaveDialog;
+ private boolean mIsActionBar;
+ private boolean mIsSaveLastLocation;
+ private boolean mDoubleTapToChooseFiles;
+ private Toast mToast = null;
+
+ /**
+ * The history.
+ */
+ private History mHistory;
+
+ /**
+ * The full history, to store and show the users whatever they have been
+ * gone to.
+ */
+ private History mFullHistory;
+
+ /**
+ * The adapter of list view.
+ */
+ private IFileAdapter mFileAdapter;
+
+ /*
+ * controls
+ */
+ private HorizontalScrollView mViewLocationsContainer;
+ private ViewGroup mViewLocations;
+ private ViewGroup mViewFilesContainer;
+ private TextView mTxtFullDirName;
+ private AbsListView mViewFiles;
+ private TextView mFooterView;
+ private Button mBtnSave;
+ private Button mBtnOk;
+ private Button mBtnCancel;
+ private EditText mTxtSaveas;
+ private ImageView mViewGoBack;
+ private ImageView mViewGoForward;
+ private ImageView mViewCreateFolder;
+ private ImageView mViewFoldersView;
+ private ImageView mViewSort;
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ /*
+ * THEME
+ */
+
+ if (getIntent().hasExtra(_Theme)) {
+ int theme;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+ theme = getIntent().getIntExtra(_Theme, android.R.style.Theme_DeviceDefault);
+ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ theme = getIntent().getIntExtra(_Theme, android.R.style.Theme_Holo);
+ else
+ theme = getIntent().getIntExtra(_Theme, android.R.style.Theme);
+ setTheme(theme);
+ }
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.afc_file_chooser);
+
+ initGestureDetector();
+
+ // load configurations
+
+ mFileProviderServiceClass = (Class>) getIntent().getSerializableExtra(_FileProviderClass);
+ if (mFileProviderServiceClass == null)
+ mFileProviderServiceClass = LocalFileProvider.class;
+
+ mIsMultiSelection = getIntent().getBooleanExtra(_MultiSelection, false);
+
+ mIsActionBar = getIntent().getBooleanExtra(_ActionBar, false);
+ mIsSaveDialog = getIntent().getBooleanExtra(_SaveDialog, false);
+ if (mIsSaveDialog)
+ mIsMultiSelection = false;
+
+ mIsSaveLastLocation = getIntent().getBooleanExtra(_SaveLastLocation, true);
+ if(!mIsSaveLastLocation)
+ DisplayPrefs.setRememberLastLocation(this, false);
+ mDoubleTapToChooseFiles = getIntent().getBooleanExtra(_DoubleTapToChooseFiles, false);
+
+ // load controls
+
+ mViewSort = (ImageView) findViewById(R.id.afc_filechooser_activity_button_sort);
+ mViewFoldersView = (ImageView) findViewById(R.id.afc_filechooser_activity_button_folders_view);
+ mViewCreateFolder = (ImageView) findViewById(R.id.afc_filechooser_activity_button_create_folder);
+ mViewGoBack = (ImageView) findViewById(R.id.afc_filechooser_activity_button_go_back);
+ mViewGoForward = (ImageView) findViewById(R.id.afc_filechooser_activity_button_go_forward);
+ mViewLocations = (ViewGroup) findViewById(R.id.afc_filechooser_activity_view_locations);
+ mViewLocationsContainer = (HorizontalScrollView) findViewById(R.id.afc_filechooser_activity_view_locations_container);
+ mTxtFullDirName = (TextView) findViewById(R.id.afc_filechooser_activity_textview_full_dir_name);
+ mViewFilesContainer = (ViewGroup) findViewById(R.id.afc_filechooser_activity_view_files_container);
+ mFooterView = (TextView) findViewById(R.id.afc_filechooser_activity_view_files_footer_view);
+ mTxtSaveas = (EditText) findViewById(R.id.afc_filechooser_activity_textview_saveas_filename);
+ mBtnSave = (Button) findViewById(R.id.afc_filechooser_activity_button_save);
+ mBtnOk = (Button) findViewById(R.id.afc_filechooser_activity_button_ok);
+ mBtnCancel = (Button) findViewById(R.id.afc_filechooser_activity_button_cancel);
+
+ // history
+ if (savedInstanceState != null && savedInstanceState.get(_History) instanceof HistoryStore>)
+ mHistory = savedInstanceState.getParcelable(_History);
+ else
+ mHistory = new HistoryStore(DisplayPrefs._DefHistoryCapacity);
+ mHistory.addListener(new HistoryListener() {
+
+ @Override
+ public void onChanged(History history) {
+ int idx = history.indexOf(getLocation());
+ mViewGoBack.setEnabled(idx > 0);
+ mViewGoForward.setEnabled(idx >= 0 && idx < history.size() - 1);
+ }
+ });
+
+ // full history
+ if (savedInstanceState != null && savedInstanceState.get(_FullHistory) instanceof HistoryStore>)
+ mFullHistory = savedInstanceState.getParcelable(_FullHistory);
+ else
+ mFullHistory = new HistoryStore(DisplayPrefs._DefHistoryCapacity) {
+
+ @Override
+ public void push(IFile newItem) {
+ int i = indexOf(newItem);
+ if (i >= 0) {
+ if (i == size() - 1)
+ return;
+ else
+ remove(newItem);
+ }
+ super.push(newItem);
+ }// push()
+ };
+
+ // make sure RESULT_CANCELED is default
+ setResult(RESULT_CANCELED);
+
+ bindService(savedInstanceState);
+ }// onCreate()
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.afc_file_chooser_activity, menu);
+ return true;
+ }// onCreateOptionsMenu()
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ return true;
+ }// onPrepareOptionsMenu()
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.afc_filechooser_activity_menuitem_home) {
+ doGoHome();
+ } else if (item.getItemId() == R.id.afc_filechooser_activity_menuitem_reload) {
+ doReloadCurrentLocation();
+ }
+
+ return true;
+ }// onOptionsItemSelected()
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ }// onConfigurationChanged()
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ outState.putParcelable(_CurrentLocation, getLocation());
+ outState.putParcelable(_History, mHistory);
+ outState.putParcelable(_FullHistory, mFullHistory);
+ }// onSaveInstanceState()
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ if (!mIsMultiSelection && !mIsSaveDialog && mDoubleTapToChooseFiles)
+ Dlg.toast(this, R.string.afc_hint_double_tap_to_select_file, Dlg._LengthShort);
+ }// onStart()
+
+ @Override
+ public void onBackPressed() {
+ IFile currentLoc = getLocation();
+ IFile preLoc = null;
+ while (currentLoc.equalsToPath(preLoc = mHistory.prevOf(currentLoc)))
+ mHistory.remove(preLoc);
+ if (preLoc != null) {
+ goTo(preLoc);
+ } else {
+ super.onBackPressed();
+ }
+ }
+ @Override
+ protected void onPause() {
+ super.onPause();
+ }
+ @Override
+ protected void onStop() {
+ super.onStop();
+ }
+ @Override
+ protected void onDestroy() {
+ if (mFileProvider != null) {
+ try {
+ unbindService(mServiceConnection);
+ } catch (Throwable t) {
+ /*
+ * due to this error:
+ * https://groups.google.com/d/topic/android-developers
+ * /Gv-80mQnyhc/discussion
+ */
+ Log.e(_ClassName, "onDestroy() - unbindService() - exception: " + t);
+ }
+
+ try {
+ stopService(new Intent(this, mFileProviderServiceClass));
+ } catch (SecurityException e) {
+ /*
+ * we have permission to stop our own service, so this exception
+ * should never be thrown
+ */
+ }
+ }
+
+ super.onDestroy();
+ }
+
+ /**
+ * Connects to file provider service, then loads root directory. If can not,
+ * then finishes this activity with result code =
+ * {@link Activity#RESULT_CANCELED}
+ *
+ * @param savedInstanceState
+ */
+ private void bindService(final Bundle savedInstanceState) {
+ if (startService(new Intent(this, mFileProviderServiceClass)) == null) {
+ doShowCannotConnectToServiceAndFinish();
+ return;
+ }
+
+ mServiceConnection = new ServiceConnection() {
+
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ try {
+ mFileProvider = ((FileProviderService.LocalBinder) service).getService();
+ } catch (Throwable t) {
+ Log.e(_ClassName, "mServiceConnection.onServiceConnected() -> " + t);
+ }
+ }// onServiceConnected()
+
+ public void onServiceDisconnected(ComponentName className) {
+ mFileProvider = null;
+ }// onServiceDisconnected()
+ };
+
+ bindService(new Intent(this, mFileProviderServiceClass), mServiceConnection, Context.BIND_AUTO_CREATE);
+
+ new LoadingDialog(this, R.string.afc_msg_loading, false) {
+
+ private static final int _WaitTime = 200;
+ private static final int _MaxWaitTime = 3000; // 3 seconds
+
+ @Override
+ protected Object doInBackground(Void... params) {
+ int totalWaitTime = 0;
+ while (mFileProvider == null) {
+ try {
+ totalWaitTime += _WaitTime;
+ Thread.sleep(_WaitTime);
+ if (totalWaitTime >= _MaxWaitTime)
+ break;
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Object result) {
+ super.onPostExecute(result);
+
+ if (mFileProvider == null) {
+ doShowCannotConnectToServiceAndFinish();
+ } else {
+ setupService();
+ setupHeader();
+ setupViewFiles();
+ setupFooter();
+
+ /*
+ * Priorities for starting path:
+ *
+ * 1. Current location (in case the activity has been killed
+ * after configurations changed).
+ *
+ * 2. Selected file from key _SelectFile.
+ *
+ * 3. Last location.
+ *
+ * 4. Root path from key _Rootpath.
+ */
+
+ // current location
+ IFile path = savedInstanceState != null ? (IFile) savedInstanceState.get(_CurrentLocation) : null;
+
+ // selected file
+ IFile selectedFile = null;
+ if (path == null) {
+ selectedFile = (IFile) getIntent().getParcelableExtra(_SelectFile);
+ if (selectedFile != null && selectedFile.exists())
+ path = selectedFile.parentFile();
+ if (path == null)
+ selectedFile = null;
+ }
+
+ // last location
+ if (path == null && DisplayPrefs.isRememberLastLocation(FileChooserActivity.this)) {
+ String lastLocation = DisplayPrefs.getLastLocation(FileChooserActivity.this);
+ if (lastLocation != null)
+ path = mFileProvider.fromPath(lastLocation);
+ }
+
+ final IFile _selectedFile = selectedFile;
+
+ // or root path
+ setLocation(path != null && path.isDirectory() ? path : mRoot, new TaskListener() {
+
+ @Override
+ public void onFinish(boolean ok, Object any) {
+ if (ok && _selectedFile != null && _selectedFile.isFile() && mIsSaveDialog)
+ mTxtSaveas.setText(_selectedFile.getName());
+
+ // don't push current location into history
+ boolean isCurrentLocation = savedInstanceState != null
+ && any.equals(savedInstanceState.get(_CurrentLocation));
+ if (isCurrentLocation) {
+ mHistory.notifyHistoryChanged();
+ } else {
+ mHistory.push((IFile) any);
+ mFullHistory.push((IFile) any);
+ }
+ }// onFinish()
+ }, selectedFile);
+ }
+ }// onPostExecute()
+ }.execute();// LoadingDialog
+ }// bindService()
+
+ /**
+ * Setup the file provider:
+ * - filter mode;
+ * - display hidden files;
+ * - max file count;
+ * - ...
+ */
+ private void setupService() {
+ /*
+ * set root path, if not specified, try using
+ * IFileProvider#defaultPath()
+ */
+ if (getIntent().getParcelableExtra(_Rootpath) != null)
+ mRoot = (IFile) getIntent().getSerializableExtra(_Rootpath);
+ if (mRoot == null || !mRoot.isDirectory())
+ mRoot = mFileProvider.defaultPath();
+
+ IFileProvider.FilterMode filterMode = (FilterMode) getIntent().getSerializableExtra(_FilterMode);
+ if (filterMode == null){
+ filterMode = IFileProvider.FilterMode.DirectoriesOnly;
+ }
+
+ IFileProvider.SortType sortType = DisplayPrefs.getSortType(this);
+ boolean sortAscending = DisplayPrefs.isSortAscending(this);
+
+ mFileProvider.setDisplayHiddenFiles(getIntent().getBooleanExtra(_DisplayHiddenFiles, false));
+ mFileProvider.setFilterMode(mIsSaveDialog ? IFileProvider.FilterMode.FilesOnly : filterMode);
+ mFileProvider.setMaxFileCount(getIntent().getIntExtra(_MaxFileCount, 1024));
+ mFileProvider.setRegexFilenameFilter(getIntent().getStringExtra(_RegexFilenameFilter));
+ mFileProvider.setSortOrder(sortAscending ? IFileProvider.SortOrder.Ascending
+ : IFileProvider.SortOrder.Descending);
+ mFileProvider.setSortType(sortType);
+ }// setupService()
+
+ /**
+ * Setup:
+ * - title of activity;
+ * - button go back;
+ * - button location;
+ * - button go forward;
+ */
+ private void setupHeader() {
+ if (mIsSaveDialog) {
+ setTitle(R.string.afc_title_save_as);
+ } else {
+ switch (mFileProvider.getFilterMode()) {
+ case FilesOnly:
+ setTitle(R.string.afc_title_choose_files);
+ break;
+ case FilesAndDirectories:
+ setTitle(R.string.afc_title_choose_files_and_directories);
+ break;
+ case DirectoriesOnly:
+ setTitle(R.string.afc_title_choose_directories);
+ break;
+ }
+ }// title of activity
+
+ mViewSort.setOnClickListener(mBtnSortOnClickListener);
+ if(DisplayPrefs.isSortAscending(this)){
+ mViewSort.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_sort_as));
+ mViewSort.setId(R.drawable.afc_selector_button_sort_as);
+ }else{
+ mViewSort.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_sort_de));
+ mViewSort.setId(R.drawable.afc_selector_button_sort_de);
+ }
+
+ mViewFoldersView.setOnClickListener(mBtnFoldersViewOnClickListener);
+ switch (DisplayPrefs.getViewType(this)) {
+ case List:
+ mViewFoldersView.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_folders_view_grid));
+ mViewFoldersView.setId(R.drawable.afc_selector_button_folders_view_grid);
+ break;
+ case Grid:
+ mViewFoldersView.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_folders_view_list));
+ mViewFoldersView.setId(R.drawable.afc_selector_button_folders_view_list);
+ break;
+ }
+ mViewCreateFolder.setOnClickListener(mBtnCreateFolderOnClickListener);
+
+ mViewGoBack.setEnabled(false);
+ mViewGoBack.setOnClickListener(mBtnGoBackOnClickListener);
+
+ mViewGoForward.setEnabled(false);
+ mViewGoForward.setOnClickListener(mBtnGoForwardOnClickListener);
+
+ for (ImageView v : new ImageView[] { mViewGoBack, mViewGoForward })
+ v.setOnLongClickListener(mBtnGoBackForwardOnLongClickListener);
+ }// setupHeader()
+
+ /**
+ * Setup:
+ * - {@link #mViewFiles}
+ * - {@link #mViewFilesContainer}
+ * - {@link #mFileAdapter}
+ */
+ private void setupViewFiles() {
+ switch (DisplayPrefs.getViewType(this)) {
+ case Grid:
+ mViewFiles = (AbsListView) getLayoutInflater().inflate(R.layout.afc_gridview_files, null);
+ break;
+ case List:
+ mViewFiles = (AbsListView) getLayoutInflater().inflate(R.layout.afc_listview_files, null);
+ break;
+ }
+
+ mViewFilesContainer.removeAllViews();
+ mViewFilesContainer.addView(mViewFiles, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT, 1));
+
+ mViewFiles.setOnItemClickListener(mViewFilesOnItemClickListener);
+ mViewFiles.setOnItemLongClickListener(mViewFilesOnItemLongClickListener);
+ mViewFiles.setOnTouchListener(new View.OnTouchListener() {
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ return mListviewFilesGestureDetector.onTouchEvent(event);
+ }
+ });
+
+ createIFileAdapter();
+
+ // no comments :-D
+ mFooterView.setOnLongClickListener(new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ E.show(FileChooserActivity.this);
+ return false;
+ }
+ });
+ }// setupViewFiles()
+
+ /**
+ * Creates {@link IFileAdapter} and assign it to list view/ grid view of
+ * files.
+ */
+ private void createIFileAdapter() {
+ if (mFileAdapter != null)
+ mFileAdapter.clear();
+
+ mFileAdapter = new IFileAdapter(FileChooserActivity.this, new ArrayList(),
+ mFileProvider.getFilterMode(), mIsMultiSelection);
+ /*
+ * API 13+ does not recognize AbsListView.setAdapter(), so we cast it to
+ * explicit class
+ */
+ if (mViewFiles instanceof ListView)
+ ((ListView) mViewFiles).setAdapter(mFileAdapter);
+ else
+ ((GridView) mViewFiles).setAdapter(mFileAdapter);
+ }// createIFileAdapter()
+
+ /**
+ * Setup:
+ * - button Cancel;
+ * - text field "save as" filename;
+ * - button Ok;
+ */
+ private void setupFooter() {
+ // by default, view group footer and all its child views are hidden
+
+ ViewGroup viewGroupFooterContainer = (ViewGroup) findViewById(R.id.afc_filechooser_activity_viewgroup_footer_container);
+ ViewGroup viewGroupFooter = (ViewGroup) findViewById(R.id.afc_filechooser_activity_viewgroup_footer2);
+ ViewGroup viewGroupFooterBottom = (ViewGroup) findViewById(R.id.afc_filechooser_activity_viewgroup_footer_bottom);
+
+ if (mIsSaveDialog) {
+ viewGroupFooterContainer.setVisibility(View.VISIBLE);
+ viewGroupFooter.setVisibility(View.VISIBLE);
+
+ mTxtSaveas.setVisibility(View.VISIBLE);
+ mTxtSaveas.setText(getIntent().getStringExtra(_DefaultFilename));
+ mTxtSaveas.setOnEditorActionListener(mTxtFilenameOnEditorActionListener);
+
+ mBtnSave.setVisibility(View.VISIBLE);
+ mBtnSave.setOnClickListener(mBtnSave_SaveDialog_OnClickListener);
+ mBtnSave.setBackgroundResource(R.drawable.afc_selector_button_ok_saveas);
+
+ int size = getResources().getDimensionPixelSize(R.dimen.afc_button_ok_saveas_size);
+ LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mBtnSave.getLayoutParams();
+ lp.width = size;
+ lp.height = size;
+ mBtnSave.setLayoutParams(lp);
+ }// this is in save mode
+ if(mIsActionBar){
+ viewGroupFooterContainer.setVisibility(View.VISIBLE);
+ viewGroupFooterBottom.setVisibility(View.VISIBLE);
+ if(mFileProvider.getFilterMode() != IFileProvider.FilterMode.FilesOnly){
+ mBtnOk.setVisibility(View.VISIBLE);
+ mBtnOk.setOnClickListener(mBtnOk_ActionBar_OnClickListener);
+ }else{
+ mBtnOk.setVisibility(View.GONE);
+ }
+ mBtnCancel.setVisibility(View.VISIBLE);
+ mBtnCancel.setOnClickListener(mBtnCancel_ActionBar_OnClickListener);
+ }
+
+ if (mIsMultiSelection) {
+ viewGroupFooterContainer.setVisibility(View.VISIBLE);
+ viewGroupFooter.setVisibility(View.VISIBLE);
+
+ ViewGroup.LayoutParams lp = viewGroupFooter.getLayoutParams();
+ lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+ viewGroupFooter.setLayoutParams(lp);
+
+ mBtnSave.setMinWidth(getResources().getDimensionPixelSize(R.dimen.afc_single_button_min_width));
+ mBtnSave.setText(android.R.string.ok);
+ mBtnSave.setVisibility(View.VISIBLE);
+ mBtnSave.setOnClickListener(mBtnSave_OpenDialog_OnClickListener);
+ }
+ }// setupFooter()
+
+ private void doReloadCurrentLocation() {
+ setLocation(getLocation(), null);
+ }// doReloadCurrentLocation()
+
+ private void doShowCannotConnectToServiceAndFinish() {
+ Dlg.showError(FileChooserActivity.this, R.string.afc_msg_cannot_connect_to_file_provider_service,
+ new DialogInterface.OnCancelListener() {
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+ });
+ }// doShowCannotConnectToServiceAndFinish()
+
+ private void doGoHome() {
+ // TODO explain why?
+ goTo(mRoot.clone());
+ }// doGoHome()
+
+ private static final int[] _BtnSortIds = { R.id.afc_settings_sort_view_button_sort_by_name_asc,
+ R.id.afc_settings_sort_view_button_sort_by_name_desc, R.id.afc_settings_sort_view_button_sort_by_size_asc,
+ R.id.afc_settings_sort_view_button_sort_by_size_desc, R.id.afc_settings_sort_view_button_sort_by_date_asc,
+ R.id.afc_settings_sort_view_button_sort_by_date_desc };
+
+ /**
+ * Show a dialog for sorting options and resort file list after user
+ * selected an option.
+ */
+ private void doResortViewFiles() {
+ final AlertDialog _dialog = Dlg.newDlg(this);
+
+ // get the index of button of current sort type
+ int btnCurrentSortTypeIdx = 0;
+ switch (DisplayPrefs.getSortType(this)) {
+ case SortByName:
+ btnCurrentSortTypeIdx = 0;
+ break;
+ case SortBySize:
+ btnCurrentSortTypeIdx = 2;
+ break;
+ case SortByDate:
+ btnCurrentSortTypeIdx = 4;
+ break;
+ }
+ if (!DisplayPrefs.isSortAscending(this))
+ btnCurrentSortTypeIdx++;
+
+ View.OnClickListener listener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ _dialog.dismiss();
+
+ Context c = FileChooserActivity.this;
+
+ if (v.getId() == R.id.afc_settings_sort_view_button_sort_by_name_asc) {
+ DisplayPrefs.setSortType(c, SortType.SortByName);
+ DisplayPrefs.setSortAscending(c, true);
+ } else if (v.getId() == R.id.afc_settings_sort_view_button_sort_by_name_desc) {
+ DisplayPrefs.setSortType(c, SortType.SortByName);
+ DisplayPrefs.setSortAscending(c, false);
+ } else if (v.getId() == R.id.afc_settings_sort_view_button_sort_by_size_asc) {
+ DisplayPrefs.setSortType(c, SortType.SortBySize);
+ DisplayPrefs.setSortAscending(c, true);
+ } else if (v.getId() == R.id.afc_settings_sort_view_button_sort_by_size_desc) {
+ DisplayPrefs.setSortType(c, SortType.SortBySize);
+ DisplayPrefs.setSortAscending(c, false);
+ } else if (v.getId() == R.id.afc_settings_sort_view_button_sort_by_date_asc) {
+ DisplayPrefs.setSortType(c, SortType.SortByDate);
+ DisplayPrefs.setSortAscending(c, true);
+ } else if (v.getId() == R.id.afc_settings_sort_view_button_sort_by_date_desc) {
+ DisplayPrefs.setSortType(c, SortType.SortByDate);
+ DisplayPrefs.setSortAscending(c, false);
+ }
+
+ resortViewFiles();
+ if(DisplayPrefs.isSortAscending(c)){
+ mViewSort.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_sort_as));
+ mViewSort.setId(R.drawable.afc_selector_button_sort_as);
+ }else{
+ mViewSort.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_sort_de));
+ mViewSort.setId(R.drawable.afc_selector_button_sort_de);
+ }
+ }// onClick()
+ };// listener
+
+ View view = getLayoutInflater().inflate(R.layout.afc_settings_sort_view, null);
+ for (int i = 0; i < _BtnSortIds.length; i++) {
+ Button btn = (Button) view.findViewById(_BtnSortIds[i]);
+ btn.setOnClickListener(listener);
+ if (i == btnCurrentSortTypeIdx) {
+ btn.setEnabled(false);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ btn.setText(R.string.afc_ellipsize);
+ }
+ }
+
+ _dialog.setTitle(R.string.afc_title_sort_by);
+ _dialog.setView(view);
+
+ _dialog.show();
+ }// doResortViewFiles()
+
+ /**
+ * Resort view files.
+ */
+ private void resortViewFiles() {
+ if (mFileProvider.getSortType().equals(DisplayPrefs.getSortType(this))
+ && mFileProvider.getSortOrder().isAsc() == (DisplayPrefs.isSortAscending(this)))
+ return;
+
+ /*
+ * Re-sort the listview by re-loading current location; NOTE: re-sort
+ * the adapter does not repaint the listview, even if we call
+ * notifyDataSetChanged(), invalidateViews()...
+ */
+ mFileProvider.setSortType(DisplayPrefs.getSortType(this));
+ mFileProvider.setSortOrder(DisplayPrefs.isSortAscending(this) ? SortOrder.Ascending : SortOrder.Descending);
+ doReloadCurrentLocation();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ ActivityCompat.invalidateOptionsMenu(this);
+ }// resortViewFiles()
+
+ /**
+ * Switch view type between {@link ViewType#List} and {@link ViewType#Grid}
+ */
+ private void doSwitchViewType() {
+ new LoadingDialog(this, R.string.afc_msg_loading, false) {
+
+ @Override
+ protected void onPreExecute() {
+ // call this first, to let the parent prepare the dialog
+ super.onPreExecute();
+
+ switch (DisplayPrefs.getViewType(FileChooserActivity.this)) {
+ case Grid:
+ DisplayPrefs.setViewType(FileChooserActivity.this, ViewType.List);
+ break;
+ case List:
+ DisplayPrefs.setViewType(FileChooserActivity.this, ViewType.Grid);
+ break;
+ }
+
+ setupViewFiles();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ ActivityCompat.invalidateOptionsMenu(FileChooserActivity.this);
+
+ doReloadCurrentLocation();
+ }// onPreExecute()
+
+ @Override
+ protected Object doInBackground(Void... params) {
+ // do nothing :-)
+ return null;
+ }// doInBackground()
+ }.execute();
+ }// doSwitchViewType()
+
+ /**
+ * Confirms user to create new directory.
+ */
+ private void doCreateNewDir() {
+ if (mFileProvider instanceof LocalFileProvider
+ && !Utils.hasPermissions(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ Dlg.toast(this, R.string.afc_msg_app_doesnot_have_permission_to_create_files, Dlg._LengthShort);
+ return;
+ }
+
+ if ((getLocation() instanceof File)){
+ if(!((File)getLocation()).canWrite()){
+ Dlg.toast(this, R.string.afc_msg_app_cant_create_folder, Dlg._LengthShort);
+ return;
+ }
+ }
+
+ final AlertDialog _dlg = Dlg.newDlg(this);
+
+ View view = getLayoutInflater().inflate(R.layout.afc_simple_text_input_view, null);
+ final EditText _textFile = (EditText) view.findViewById(R.id.afc_simple_text_input_view_text1);
+ _textFile.setHint(R.string.afc_hint_folder_name);
+ _textFile.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ Ui.hideSoftKeyboard(FileChooserActivity.this, _textFile.getWindowToken());
+ _dlg.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ _dlg.setView(view);
+ _dlg.setTitle(R.string.afc_cmd_new_folder);
+ _dlg.setIcon(android.R.drawable.ic_menu_add);
+ _dlg.setButton(DialogInterface.BUTTON_POSITIVE, getString(android.R.string.ok),
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String name = _textFile.getText().toString().trim();
+ if (!FileUtils.isFilenameValid(name)) {
+ Dlg.toast(FileChooserActivity.this, getString(R.string.afc_pmsg_filename_is_invalid, name),
+ Dlg._LengthShort);
+ return;
+ }
+
+ IFile dir = mFileProvider.fromPath(String
+ .format("%s/%s", getLocation().getAbsolutePath(), name));
+ if (dir.mkdir()) {
+ Dlg.toast(FileChooserActivity.this, getString(R.string.afc_msg_done), Dlg._LengthShort);
+ setLocation(getLocation(), null);
+ } else
+ Dlg.toast(FileChooserActivity.this,
+ getString(R.string.afc_pmsg_cannot_create_folder, name), Dlg._LengthShort);
+ }// onClick()
+ });
+ _dlg.show();
+
+ final Button _btnOk = _dlg.getButton(DialogInterface.BUTTON_POSITIVE);
+ _btnOk.setEnabled(false);
+
+ _textFile.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ _btnOk.setEnabled(FileUtils.isFilenameValid(s.toString().trim()));
+ }
+ });
+ }// doCreateNewDir()
+
+ /**
+ * Updates UI that {@code data} will not be deleted.
+ *
+ * @param data
+ * {@link IFileDataModel}
+ */
+ private void notifyDataModelNotDeleted(IFileDataModel data) {
+ data.setTobeDeleted(false);
+ mFileAdapter.notifyDataSetChanged();
+ }// notifyDataModelNotDeleted(()
+
+ /**
+ * Deletes a file.
+ *
+ * @param file
+ * {@link IFile}
+ */
+ private void doDeleteFile(final IFileDataModel data) {
+ if (mFileProvider instanceof LocalFileProvider
+ && !Utils.hasPermissions(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ notifyDataModelNotDeleted(data);
+ Dlg.toast(this, R.string.afc_msg_app_doesnot_have_permission_to_delete_files, Dlg._LengthShort);
+ return;
+ }
+
+ Dlg.confirmYesno(
+ this,
+ getString(R.string.afc_pmsg_confirm_delete_file, data.getFile().isFile() ? getString(R.string.afc_file)
+ : getString(R.string.afc_folder), data.getFile().getName()),
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ new LoadingDialog(FileChooserActivity.this, getString(R.string.afc_pmsg_deleting_file, data
+ .getFile().isFile() ? getString(R.string.afc_file) : getString(R.string.afc_folder),
+ data.getFile().getName()), true) {
+
+ private Thread mThread = FileUtils.createDeleteFileThread(data.getFile(), mFileProvider,
+ true);
+ private final boolean _isFile = data.getFile().isFile();
+
+ private void notifyFileDeleted() {
+ mFileAdapter.remove(data);
+ mFileAdapter.notifyDataSetChanged();
+
+ refreshHistories();
+ // TODO remove all duplicate history items
+
+ Dlg.toast(
+ FileChooserActivity.this,
+ getString(
+ R.string.afc_pmsg_file_has_been_deleted,
+ _isFile ? getString(R.string.afc_file) : getString(R.string.afc_folder),
+ data.getFile().getName()), Dlg._LengthShort);
+ }// notifyFileDeleted()
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ mThread.start();
+ }// onPreExecute()
+
+ @Override
+ protected Object doInBackground(Void... arg0) {
+ while (mThread.isAlive()) {
+ try {
+ mThread.join(DisplayPrefs._DelayTimeWaitingThreads);
+ } catch (InterruptedException e) {
+ mThread.interrupt();
+ }
+ }
+ return null;
+ }// doInBackground()
+
+ @Override
+ protected void onCancelled() {
+ mThread.interrupt();
+
+ if (data.getFile().exists()) {
+ notifyDataModelNotDeleted(data);
+ Dlg.toast(FileChooserActivity.this, R.string.afc_msg_cancelled, Dlg._LengthShort);
+ } else
+ notifyFileDeleted();
+
+ super.onCancelled();
+ }// onCancelled()
+
+ @Override
+ protected void onPostExecute(Object result) {
+ super.onPostExecute(result);
+
+ if (data.getFile().exists()) {
+ notifyDataModelNotDeleted(data);
+ Dlg.toast(
+ FileChooserActivity.this,
+ getString(R.string.afc_pmsg_cannot_delete_file,
+ data.getFile().isFile() ? getString(R.string.afc_file)
+ : getString(R.string.afc_folder), data.getFile().getName()),
+ Dlg._LengthShort);
+ } else
+ notifyFileDeleted();
+ }// onPostExecute()
+ }.execute();// LoadingDialog
+ }// onClick()
+ }, new DialogInterface.OnCancelListener() {
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ notifyDataModelNotDeleted(data);
+ }// onCancel()
+ });
+ }// doDeleteFile()
+
+ /**
+ * As the name means.
+ *
+ * @param filename
+ * @since v1.91
+ */
+ private void doCheckSaveasFilenameAndFinish(String filename) {
+ if (filename.length() == 0) {
+ Dlg.toast(this, R.string.afc_msg_filename_is_empty, Dlg._LengthShort);
+ } else {
+ final IFile _file = mFileProvider.fromPath(getLocation().getAbsolutePath() + File.separator + filename);
+
+ if (!FileUtils.isFilenameValid(filename)) {
+ Dlg.toast(this, getString(R.string.afc_pmsg_filename_is_invalid, filename), Dlg._LengthShort);
+ } else if (_file.isFile()) {
+ Dlg.confirmYesno(FileChooserActivity.this,
+ getString(R.string.afc_pmsg_confirm_replace_file, _file.getName()),
+ new DialogInterface.OnClickListener() {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ doFinish(_file);
+ }
+ });
+ } else if (_file.isDirectory()) {
+ Dlg.toast(this, getString(R.string.afc_pmsg_filename_is_directory, _file.getName()), Dlg._LengthShort);
+ } else
+ doFinish(_file);
+ }
+ }// doCheckSaveasFilenameAndFinish()
+
+ /**
+ * Gets current location.
+ *
+ * @return current location, can be {@code null}.
+ */
+ private IFile getLocation() {
+ return (IFile) mViewLocations.getTag();
+ }// getLocation()
+
+ /**
+ * Sets current location.
+ *
+ * @param path
+ * the path
+ * @param listener
+ * {@link TaskListener}: the second parameter {@code any} in
+ * {@link TaskListener#onFinish(boolean, Object)} will be
+ * {@code path}.
+ */
+ private void setLocation(final IFile path, final TaskListener listener) {
+ setLocation(path, listener, null);
+ }// setLocation()
+
+ /**
+ * Sets current location.
+ *
+ * @param path
+ * the path
+ * @param listener
+ * {@link TaskListener}: the second parameter {@code any} in
+ * {@link TaskListener#onFinish(boolean, Object)} will be
+ * {@code path}.
+ * @param selectedFile
+ * the file should be selected after loading location done. Can
+ * be {@code null}.
+ */
+ private void setLocation(final IFile path, final TaskListener listener, final IFile selectedFile) {
+ new LoadingDialog(this, R.string.afc_msg_loading, true) {
+
+ // IFile[] files = new IFile[0];
+ List files;
+ boolean hasMoreFiles = false;
+ int shouldBeSelectedIdx = -1;
+ /**
+ * Used to focus last directory on list view.
+ */
+ String mLastPath = getLocation() != null ? getLocation().getAbsolutePath() : null;
+
+ @Override
+ protected Object doInBackground(Void... params) {
+ try {
+ if (path.isDirectory() && path.canRead()) {
+ files = new ArrayList();
+ mFileProvider.listAllFiles(path, new IFileFilter() {
+
+ @Override
+ public boolean accept(IFile pathname) {
+ if (mFileProvider.accept(pathname)) {
+ if (files.size() < mFileProvider.getMaxFileCount())
+ files.add(pathname);
+ else
+ hasMoreFiles = true;
+ }
+ return false;
+ }// accept()
+ });
+ } else
+ files = null;
+
+ if (files != null) {
+ Collections.sort(files,
+ new FileComparator(mFileProvider.getSortType(), mFileProvider.getSortOrder()));
+ if (selectedFile != null && selectedFile.exists()
+ && selectedFile.parentFile().equalsToPath(path)) {
+ for (int i = 0; i < files.size(); i++) {
+ if (files.get(i).equalsToPath(selectedFile)) {
+ shouldBeSelectedIdx = i;
+ break;
+ }
+ }
+ } else if (mLastPath != null && mLastPath.length() >= path.getAbsolutePath().length()) {
+ for (int i = 0; i < files.size(); i++) {
+ IFile f = files.get(i);
+ if (f.isDirectory() && mLastPath.startsWith(f.getAbsolutePath())) {
+ shouldBeSelectedIdx = i;
+ break;
+ }
+ }
+ }
+ }// if files != null
+ } catch (Throwable t) {
+ setLastException(t);
+ cancel(false);
+ }
+ return null;
+ }// doInBackground()
+
+ @Override
+ protected void onCancelled() {
+ super.onCancelled();
+ Dlg.toast(FileChooserActivity.this, R.string.afc_msg_cancelled, Dlg._LengthShort);
+ }// onCancelled()
+
+ @Override
+ protected void onPostExecute(Object result) {
+ super.onPostExecute(result);
+
+ if (files == null) {
+ Dlg.toast(FileChooserActivity.this, getString(R.string.afc_pmsg_cannot_access_dir, path.getName()),
+ Dlg._LengthShort);
+ if (listener != null)
+ listener.onFinish(false, path);
+ return;
+ }
+
+ // update list view
+
+ createIFileAdapter();
+ for (IFile f : files)
+ mFileAdapter.add(new IFileDataModel(f));
+ mFileAdapter.notifyDataSetChanged();
+
+ // update footers
+
+ mFooterView.setVisibility(hasMoreFiles || mFileAdapter.isEmpty() ? View.VISIBLE : View.GONE);
+ if (hasMoreFiles)
+ mFooterView.setText(getString(R.string.afc_pmsg_max_file_count_allowed,
+ mFileProvider.getMaxFileCount()));
+ else if (mFileAdapter.isEmpty())
+ mFooterView.setText(R.string.afc_msg_empty);
+
+ /*
+ * We 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() {
+ if (shouldBeSelectedIdx >= 0 && shouldBeSelectedIdx < mFileAdapter.getCount()) {
+ mViewFiles.setSelection(shouldBeSelectedIdx);
+ } else if (!mFileAdapter.isEmpty())
+ mViewFiles.setSelection(0);
+ }// run()
+ });
+
+ /*
+ * navigation buttons
+ */
+ createLocationButtons(path);
+
+ if (listener != null)
+ listener.onFinish(true, path);
+ }// onPostExecute()
+ }.execute();// new LoadingDialog()
+ }// setLocation()
+
+ /**
+ * Goes to a specified location.
+ *
+ * @param dir
+ * a directory, of course.
+ * @return {@code true} if {@code dir} can be browsed to.
+ * @since v4.3 beta
+ */
+ private boolean goTo(final IFile dir) {
+ if (dir.equalsToPath(getLocation()))
+ return false;
+
+ setLocation(dir, new TaskListener() {
+
+ IFile mLastPath = getLocation();
+
+ @Override
+ public void onFinish(boolean ok, Object any) {
+ if (ok) {
+ mHistory.truncateAfter(mLastPath);
+ mHistory.push(dir);
+ mFullHistory.push(dir);
+ if(mFileProvider.getFilterMode() != IFileProvider.FilterMode.AnyDirectories){
+ if(!(((File) dir).canWrite()) ){
+ mBtnOk.setEnabled(false);
+ mViewCreateFolder.setEnabled(false);
+ }else{
+ mBtnOk.setEnabled(true);
+ mViewCreateFolder.setEnabled(true);
+ }
+ }
+ }
+ }
+ });
+ return true;
+ }// goTo()
+
+ private void createLocationButtons(IFile path) {
+ mViewLocations.setTag(path);
+ mViewLocations.removeAllViews();
+
+ LinearLayout.LayoutParams lpBtnLoc = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT);
+ lpBtnLoc.gravity = Gravity.CENTER;
+ LinearLayout.LayoutParams lpDivider = null;
+ LayoutInflater inflater = getLayoutInflater();
+ int count = 0;
+ while (path != null) {
+ TextView btnLoc = (TextView) inflater.inflate(R.layout.afc_button_location, null);
+ btnLoc.setText(path.parentFile() != null ? "/"+path.getName() : getString(R.string.afc_root));
+ btnLoc.setTag(path);
+ btnLoc.setOnClickListener(mBtnLocationOnClickListener);
+ btnLoc.setOnLongClickListener(mBtnLocationOnLongClickListener);
+ mViewLocations.addView(btnLoc, 0, lpBtnLoc);
+
+ if (count++ == 0) {
+ Rect r = new Rect();
+ btnLoc.getPaint().getTextBounds(path.getName(), 0, path.getName().length(), r);
+ if (r.width() >= getResources().getDimensionPixelSize(R.dimen.afc_button_location_max_width)
+ - btnLoc.getPaddingLeft() - btnLoc.getPaddingRight()) {
+ mTxtFullDirName.setText(path.getName());
+ mTxtFullDirName.setVisibility(View.VISIBLE);
+ } else
+ mTxtFullDirName.setVisibility(View.GONE);
+ }
+
+ path = path.parentFile();
+ }
+
+ mViewLocationsContainer.postDelayed(new Runnable() {
+
+ public void run() {
+ mViewLocationsContainer.fullScroll(HorizontalScrollView.FOCUS_RIGHT);
+ }
+ }, 100);
+ }// createLocationButtons()
+
+ /**
+ * Refreshes all the histories. This removes invalid items (which are not
+ * existed anymore).
+ */
+ private void refreshHistories() {
+ HistoryFilter historyFilter = new HistoryFilter() {
+
+ @Override
+ public boolean accept(IFile item) {
+ return !item.isDirectory();
+ }
+ };
+
+ mHistory.removeAll(historyFilter);
+ mFullHistory.removeAll(historyFilter);
+ }// refreshHistories()
+
+ /**
+ * Finishes this activity.
+ *
+ * @param files
+ * list of {@link IFile}
+ */
+ private void doFinish(IFile... files) {
+ List list = new ArrayList();
+ for (IFile f : files)
+ list.add(f);
+ doFinish((ArrayList) list);
+ }
+
+ /**
+ * Finishes this activity.
+ *
+ * @param files
+ * list of {@link IFile}
+ */
+ private void doFinish(ArrayList files) {
+ String returnPath = null;
+ // set results
+ switch(mFileProvider.getFilterMode()){
+ case FilesOnly:
+ if(files == null || files.isEmpty()){
+ setResult(RESULT_CANCELED);
+ finish();
+ return;
+ }
+ break;
+ case DirectoriesOnly:
+ if(((File)getLocation()).canWrite()){
+ returnPath = getLocation().getAbsolutePath();
+ }
+ break;
+ case FilesAndDirectories:
+ if(files == null || files.isEmpty()){
+ returnPath = getLocation().getAbsolutePath();
+ }
+ break;
+ default:
+ returnPath = getLocation().getAbsolutePath();
+ break;
+ }
+
+ Intent intent = new Intent();
+ if(returnPath != null)
+ intent.putExtra(_FolderPath, returnPath);
+
+ if(files != null){
+ intent.putExtra(_Results, files);
+ }else{
+ intent.putExtra(_Results, new ArrayList());
+ }
+
+ // return flags for further use (in case the caller needs)
+ intent.putExtra(_FilterMode, mFileProvider.getFilterMode());
+ intent.putExtra(_SaveDialog, mIsSaveDialog);
+
+ setResult(RESULT_OK, intent);
+
+ if (DisplayPrefs.isRememberLastLocation(this) && getLocation() != null) {
+ DisplayPrefs.setLastLocation(this, getLocation().getAbsolutePath());
+ } else
+ DisplayPrefs.setLastLocation(this, null);
+
+ finish();
+ }// doFinish()
+
+ /**********************************************************
+ * BUTTON LISTENERS
+ */
+ private final View.OnClickListener mBtnSortOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ doResortViewFiles();
+ }
+ };// mBtnSortOnClickListener
+
+
+ private final View.OnClickListener mBtnFoldersViewOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ doSwitchViewType();
+ if(mViewFoldersView.getId() == R.drawable.afc_selector_button_folders_view_list){
+ mViewFoldersView.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_folders_view_grid));
+ mViewFoldersView.setId(R.drawable.afc_selector_button_folders_view_grid);
+ }else{
+ mViewFoldersView.setImageDrawable(getResources().getDrawable(R.drawable.afc_selector_button_folders_view_list));
+ mViewFoldersView.setId(R.drawable.afc_selector_button_folders_view_list);
+ }
+ }
+ };// mBtnFoldersViewOnClickListener
+
+
+ private final View.OnClickListener mBtnCreateFolderOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ doCreateNewDir();
+ }
+ };// mBtnCreateFolderOnClickListener
+
+
+ private final View.OnClickListener mBtnGoBackOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ /*
+ * if user deleted a dir which was one in history, then maybe there
+ * are duplicates, so we check and remove them here
+ */
+ IFile currentLoc = getLocation();
+ IFile preLoc = null;
+ while (currentLoc.equalsToPath(preLoc = mHistory.prevOf(currentLoc)))
+ mHistory.remove(preLoc);
+
+ if (preLoc != null) {
+ setLocation(preLoc, new TaskListener() {
+
+ @Override
+ public void onFinish(boolean ok, Object any) {
+ if (ok) {
+ mViewGoBack.setEnabled(mHistory.prevOf(getLocation()) != null);
+ mViewGoForward.setEnabled(true);
+ mFullHistory.push((IFile) any);
+ }
+ }
+ });
+ } else {
+ mViewGoBack.setEnabled(false);
+ }
+ }
+ };// mBtnGoBackOnClickListener
+
+ private final View.OnClickListener mBtnLocationOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (v.getTag() instanceof IFile)
+ goTo((IFile) v.getTag());
+ }
+ };// mBtnLocationOnClickListener
+
+ private final View.OnLongClickListener mBtnLocationOnLongClickListener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ if (IFileProvider.FilterMode.FilesOnly.equals(mFileProvider.getFilterMode()) || mIsSaveDialog)
+ return false;
+
+ doFinish((IFile) v.getTag());
+
+ return false;
+ }
+
+ };// mBtnLocationOnLongClickListener
+
+ private final View.OnClickListener mBtnGoForwardOnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ /*
+ * if user deleted a dir which was one in history, then maybe there
+ * are duplicates, so we check and remove them here
+ */
+ IFile currentLoc = getLocation();
+ IFile nextLoc = null;
+ while (currentLoc.equalsToPath(nextLoc = mHistory.nextOf(currentLoc)))
+ mHistory.remove(nextLoc);
+
+ if (nextLoc != null) {
+ setLocation(nextLoc, new TaskListener() {
+
+ @Override
+ public void onFinish(boolean ok, Object any) {
+ if (ok) {
+ mViewGoBack.setEnabled(true);
+ mViewGoForward.setEnabled(mHistory.nextOf(getLocation()) != null);
+ mFullHistory.push((IFile) any);
+ }
+ }
+ });
+ } else {
+ mViewGoForward.setEnabled(false);
+ }
+ }
+ };// mBtnGoForwardOnClickListener
+
+ private final View.OnLongClickListener mBtnGoBackForwardOnLongClickListener = new View.OnLongClickListener() {
+
+ @Override
+ public boolean onLongClick(View v) {
+ ViewFilesContextMenuUtils.doShowHistoryContents(FileChooserActivity.this, mFileProvider, mFullHistory,
+ getLocation(), new TaskListener() {
+
+ @Override
+ public void onFinish(boolean ok, Object any) {
+ mHistory.removeAll(new HistoryFilter() {
+
+ @Override
+ public boolean accept(IFile item) {
+ return mFullHistory.indexOf(item) < 0;
+ }
+ });
+
+ if (any instanceof IFile) {
+ setLocation((IFile) any, new TaskListener() {
+
+ @Override
+ public void onFinish(boolean ok, Object any) {
+ if (ok)
+ mHistory.notifyHistoryChanged();
+ }
+ });
+ } else if (mHistory.isEmpty()) {
+ mHistory.push(getLocation());
+ mFullHistory.push(getLocation());
+ }
+ }// onFinish()
+ });
+ return false;
+ }// onLongClick()
+ };// mBtnGoBackForwardOnLongClickListener
+
+ private final TextView.OnEditorActionListener mTxtFilenameOnEditorActionListener = new TextView.OnEditorActionListener() {
+
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ Ui.hideSoftKeyboard(FileChooserActivity.this, mTxtSaveas.getWindowToken());
+ mBtnSave.performClick();
+ return true;
+ }
+ return false;
+ }
+ };// mTxtFilenameOnEditorActionListener
+
+ private final View.OnClickListener mBtnOk_ActionBar_OnClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if ((getLocation() instanceof File)){
+ if(mFileProvider.getFilterMode() != IFileProvider.FilterMode.AnyDirectories){
+ if(!((File)getLocation()).canWrite()){
+ Dlg.toast(FileChooserActivity.this, R.string.afc_msg_app_cant_choose_folder, Dlg._LengthShort);
+ return;
+ }
+ }
+ }
+ doFinish();
+ FileChooserActivity.this.finish();
+ }
+ };// mBtnOk_ActionBar_OnClickListener
+
+ private final View.OnClickListener mBtnCancel_ActionBar_OnClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ FileChooserActivity.this.finish();
+ }
+ };// mBtnOk_ActionBar_OnClickListener
+
+ private final View.OnClickListener mBtnSave_SaveDialog_OnClickListener = new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Ui.hideSoftKeyboard(FileChooserActivity.this, mTxtSaveas.getWindowToken());
+ String filename = mTxtSaveas.getText().toString().trim();
+ doCheckSaveasFilenameAndFinish(filename);
+ }
+ };// mBtnSave_SaveDialog_OnClickListener
+
+ private final View.OnClickListener mBtnSave_OpenDialog_OnClickListener = new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ List list = new ArrayList();
+ for (int i = 0; i < mViewFiles.getAdapter().getCount(); i++) {
+ // NOTE: header and footer don't have data
+ Object obj = mViewFiles.getAdapter().getItem(i);
+ if (obj instanceof IFileDataModel) {
+ IFileDataModel dm = (IFileDataModel) obj;
+ if (dm.isSelected())
+ list.add(dm.getFile());
+ }
+ }
+ doFinish((ArrayList) list);
+ }
+ };// mBtnSave_OpenDialog_OnClickListener
+
+ /*
+ * LIST VIEW HELPER
+ */
+
+ private GestureDetector mListviewFilesGestureDetector;
+
+ private void initGestureDetector() {
+ mListviewFilesGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
+
+ private Object getData(float x, float y) {
+ int i = getSubViewId(x, y);
+ if (i >= 0)
+ return mViewFiles.getItemAtPosition(mViewFiles.getFirstVisiblePosition() + i);
+ return null;
+ }// getSubView()
+
+ /**
+ * Gets {@link IFileDataModel} from {@code e}.
+ *
+ * @param e
+ * {@link MotionEvent}.
+ * @return the data model, or {@code null} if not available.
+ */
+ private IFileDataModel getDataModel(MotionEvent e) {
+ Object o = getData(e.getX(), e.getY());
+ return o instanceof IFileDataModel ? (IFileDataModel) o : null;
+ }// getDataModel()
+
+ private int getSubViewId(float x, float y) {
+ Rect r = new Rect();
+ for (int i = 0; i < mViewFiles.getChildCount(); i++) {
+ mViewFiles.getChildAt(i).getHitRect(r);
+ if (r.contains((int) x, (int) y))
+ return i;
+ }
+
+ return -1;
+ }// getSubViewId()
+
+ @Override
+ public void onLongPress(MotionEvent e) {
+ // do nothing
+ }// onLongPress()
+
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ // do nothing
+ return false;
+ }// onSingleTapConfirmed()
+
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ if (mDoubleTapToChooseFiles) {
+ if (mIsMultiSelection)
+ return false;
+
+ IFileDataModel data = getDataModel(e);
+ if (data == null)
+ return false;
+
+ if (data.getFile().isDirectory()
+ && IFileProvider.FilterMode.FilesOnly.equals(mFileProvider.getFilterMode()))
+ return false;
+
+ // if mFilterMode == DirectoriesOnly, files won't be
+ // shown
+
+ if (mIsSaveDialog) {
+ if (data.getFile().isFile()) {
+ mTxtSaveas.setText(data.getFile().getName());
+ doCheckSaveasFilenameAndFinish(data.getFile().getName());
+ } else
+ return false;
+ } else
+ doFinish(data.getFile());
+ }// double tap to choose files
+ else {
+ // do nothing
+ return false;
+ }// single tap to choose files
+
+ return true;
+ }// onDoubleTap()
+
+ @Override
+ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+ final int _max_y_distance = 19;// 10 is too short :-D
+ final int _min_x_distance = 80;
+ final int _min_x_velocity = 200;
+ if (Math.abs(e1.getY() - e2.getY()) < _max_y_distance
+ && Math.abs(e1.getX() - e2.getX()) > _min_x_distance && Math.abs(velocityX) > _min_x_velocity) {
+ Object o = getData(e1.getX(), e1.getY());
+ if (o instanceof IFileDataModel) {
+ ((IFileDataModel) o).setTobeDeleted(true);
+ mFileAdapter.notifyDataSetChanged();
+ doDeleteFile((IFileDataModel) o);
+ }
+ }
+
+ /*
+ * always return false to let the default handler draw the item
+ * properly
+ */
+ return false;
+ }// onFling()
+ });// mListviewFilesGestureDetector
+ }// initGestureDetector()
+
+ private final AdapterView.OnItemClickListener mViewFilesOnItemClickListener = new AdapterView.OnItemClickListener() {
+
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ IFileDataModel data = mFileAdapter.getItem(position);
+
+ if (data.getFile().isDirectory()) {
+ goTo(data.getFile());
+ return;
+ }
+
+ if (mIsSaveDialog)
+ mTxtSaveas.setText(data.getFile().getName());
+
+ if (mDoubleTapToChooseFiles) {
+ // do nothing
+ return;
+ }// double tap to choose files
+ else {
+ if (mIsMultiSelection)
+ return;
+
+ if (mIsSaveDialog)
+ doCheckSaveasFilenameAndFinish(data.getFile().getName());
+ else
+ doFinish(data.getFile());
+ }// single tap to choose files
+ }// onItemClick()
+ };// mViewFilesOnItemClickListener
+
+ private final AdapterView.OnItemLongClickListener mViewFilesOnItemLongClickListener = new AdapterView.OnItemLongClickListener() {
+
+ @Override
+ public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
+ IFileDataModel data = mFileAdapter.getItem(position);
+
+ if (mDoubleTapToChooseFiles) {
+ // do nothing
+ }// double tap to choose files
+ else {
+ if (!mIsSaveDialog
+ && !mIsMultiSelection
+ && data.getFile().isDirectory()
+ && (IFileProvider.FilterMode.DirectoriesOnly.equals(mFileProvider.getFilterMode()) || IFileProvider.FilterMode.FilesAndDirectories
+ .equals(mFileProvider.getFilterMode()))) {
+ doFinish(data.getFile());
+ }
+ }// single tap to choose files
+
+ // notify that we already handled long click here
+ return true;
+ }// onItemLongClick()
+ };// mViewFilesOnItemLongClickListener
+}
diff --git a/third-party/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/IFileAdapter.java b/third-party/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/IFileAdapter.java
new file mode 100755
index 000000000..c5d742f81
--- /dev/null
+++ b/third-party/android-filechooser/code/src/group/pals/android/lib/ui/filechooser/IFileAdapter.java
@@ -0,0 +1,435 @@
+/*
+ * 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;
+
+import group.pals.android.lib.ui.filechooser.io.IFile;
+import group.pals.android.lib.ui.filechooser.io.IFileFilter;
+import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs;
+import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs.FileTimeDisplay;
+import group.pals.android.lib.ui.filechooser.services.IFileProvider;
+import group.pals.android.lib.ui.filechooser.services.IFileProvider.FilterMode;
+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.FileUtils;
+import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils;
+import group.pals.android.lib.ui.filechooser.utils.ui.LoadingDialog;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.GridView;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * The adapter to be used in {@link android.widget.ListView}
+ *
+ * @author Hai Bison
+ *
+ */
+public class IFileAdapter extends BaseAdapter {
+
+ /**
+ * Used for logging...
+ */
+ public static final String _ClassName = IFileAdapter.class.getName();
+
+ private final Integer[] mAdvancedSelectionOptions;
+ private final IFileProvider.FilterMode mFilterMode;
+ private final Context mContext;
+ private final FileTimeDisplay mFileTimeDisplay;
+
+ private List mData;
+ private LayoutInflater mInflater;
+ private boolean mMultiSelection;
+
+ /**
+ * Creates new {@link IFileAdapter}
+ *
+ * @param context
+ * {@link Context}
+ * @param objects
+ * the data
+ * @param filterMode
+ * see {@link IFileProvider.FilterMode}
+ * @param multiSelection
+ * see {@link FileChooserActivity#_MultiSelection}
+ */
+ public IFileAdapter(Context context, List objects, IFileProvider.FilterMode filterMode,
+ boolean multiSelection) {
+ // DO NOT use getApplicationContext(), due to this bug:
+ // http://stackoverflow.com/questions/2634991/android-1-6-android-view-windowmanagerbadtokenexception-unable-to-add-window
+ // http://code.google.com/p/android/issues/detail?id=11199
+ mContext = context;
+ mData = objects;
+ mInflater = LayoutInflater.from(mContext);
+ mFilterMode = filterMode;
+ mMultiSelection = multiSelection;
+
+ switch (mFilterMode) {
+ case DirectoriesOnly:
+ case FilesOnly:
+ mAdvancedSelectionOptions = new Integer[] { R.string.afc_cmd_advanced_selection_all,
+ R.string.afc_cmd_advanced_selection_none, R.string.afc_cmd_advanced_selection_invert };
+ break;// DirectoriesOnly and FilesOnly
+ default:
+ mAdvancedSelectionOptions = new Integer[] { R.string.afc_cmd_advanced_selection_all,
+ R.string.afc_cmd_advanced_selection_none, R.string.afc_cmd_advanced_selection_invert,
+ R.string.afc_cmd_select_all_files, R.string.afc_cmd_select_all_folders };
+ break;// FilesAndDirectories
+ }
+
+ mFileTimeDisplay = new FileTimeDisplay(DisplayPrefs.isShowTimeForOldDaysThisYear(mContext),
+ DisplayPrefs.isShowTimeForOldDays(mContext));
+ }// IFileAdapter
+
+ @Override
+ public void notifyDataSetChanged() {
+ updateEnvironments();
+ super.notifyDataSetChanged();
+ }// notifyDataSetChanged()
+
+ /**
+ * Updates environments such as file time display... For example, this
+ * method is useful if you have {@link PreferenceActivity} or
+ * {@link PreferenceFragment} to let the user change preferences. So after
+ * the user changed preferences, you just simply call this method and
+ * {@link #notifyDataSetChanged()}, or just call
+ * {@link #notifyDataSetChanged()} (which also calls this method) to update
+ * the UI of this adapter.
+ */
+ public void updateEnvironments() {
+ mFileTimeDisplay.setShowTimeForOldDaysThisYear(DisplayPrefs.isShowTimeForOldDaysThisYear(mContext));
+ mFileTimeDisplay.setShowTimeForOldDays(DisplayPrefs.isShowTimeForOldDays(mContext));
+ }// updateEnvironments()
+
+ @Override
+ public int getCount() {
+ return mData != null ? mData.size() : 0;
+ }
+
+ @Override
+ public IFileDataModel getItem(int position) {
+ return mData != null ? mData.get(position) : null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public boolean isMultiSelection() {
+ return mMultiSelection;
+ }
+
+ /**
+ * Sets multi-selection mode.
+ * Note:
+ *
+ *
If {@code v = true}, this method will also update adapter.
+ *
+ *
If {@code v = false}, this method will iterate all items, set their
+ * selection to {@code false}. So you should consider using a
+ * {@link LoadingDialog}. This will not update adapter, you must do it
+ * yourself.
+ *
+ * @param v
+ * {@code true} if multi-selection is enabled
+ */
+ public void setMultiSelection(boolean v) {
+ if (mMultiSelection != v) {
+ mMultiSelection = v;
+ if (mMultiSelection) {
+ notifyDataSetChanged();
+ } else {
+ if (getCount() > 0) {
+ for (int i = 0; i < mData.size(); i++)
+ mData.get(i).setSelected(false);
+ }
+ }
+ }
+ }// setMultiSelection()
+
+ /**
+ * Gets selected items.
+ *
+ * @return list of selected items, can be empty but never be {@code null}
+ */
+ public ArrayList getSelectedItems() {
+ ArrayList res = new ArrayList();
+
+ for (int i = 0; i < getCount(); i++)
+ if (getItem(i).isSelected())
+ res.add(getItem(i));
+
+ return res;
+ }// getSelectedItems()
+
+ /**
+ * Adds an {@code item}. Note: this does not notify the adapter that
+ * data set has been changed.
+ *
+ * @param item
+ * {@link IFileDataModel}
+ */
+ public void add(IFileDataModel item) {
+ if (mData != null)
+ mData.add(item);
+ }
+
+ /**
+ * Removes {@code item}. Note: this does not notify the adapter that
+ * data set has been changed.
+ *
+ * @param item
+ * {@link IFileDataModel}
+ */
+ public void remove(IFileDataModel item) {
+ if (mData != null) {
+ mData.remove(item);
+ }
+ }// remove()
+
+ /**
+ * Removes all {@code items}. Note: this does not notify the adapter
+ * that data set has been changed.
+ *
+ * @param items
+ * the items you want to remove.
+ */
+ public void removeAll(Collection items) {
+ if (mData != null)
+ mData.removeAll(items);
+ }// removeAll()
+
+ /**
+ * Clears all items.
+ * Note:
+ *
This does not notify the adapter that data set has been changed.