Bookmarks and history removed
This commit is contained in:
		| @@ -23,25 +23,6 @@ | |||||||
|             android:drawableLeft="?attr/afc_button_home" |             android:drawableLeft="?attr/afc_button_home" | ||||||
|             android:text="@string/afc_cmd_home" /> |             android:text="@string/afc_cmd_home" /> | ||||||
|  |  | ||||||
|         <TextView |  | ||||||
|             android:id="@+id/afc_textview_bookmarks" |  | ||||||
|             style="@style/afc_home_button_navigators" |  | ||||||
|             android:layout_below="@id/afc_textview_home" |  | ||||||
|             android:drawableLeft="@drawable/afc_bookmarks_dark" |  | ||||||
|             android:text="@string/afc_title_bookmarks" /> |  | ||||||
|  |  | ||||||
|         <View |  | ||||||
|             android:id="@+id/afc_viewgroup_bookmarks_view_divider" |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="@dimen/afc_viewgroup_button_locations_bottom_divider_height" |  | ||||||
|             android:layout_below="@id/afc_textview_bookmarks" |  | ||||||
|             android:background="@color/afc_border_line_dark" /> |  | ||||||
|  |  | ||||||
|         <FrameLayout |  | ||||||
|             android:id="@+id/afc_fragment_bookmarks" |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="match_parent" |  | ||||||
|             android:layout_below="@id/afc_viewgroup_bookmarks_view_divider" /> |  | ||||||
|     </RelativeLayout> |     </RelativeLayout> | ||||||
|  |  | ||||||
|     <View |     <View | ||||||
| @@ -156,6 +137,7 @@ | |||||||
|                 layout="@layout/afc_view_loading" /> |                 layout="@layout/afc_view_loading" /> | ||||||
|         </RelativeLayout> |         </RelativeLayout> | ||||||
|  |  | ||||||
|  |  | ||||||
|         <LinearLayout |         <LinearLayout | ||||||
|             android:id="@+id/afc_viewgroup_footer_container" |             android:id="@+id/afc_viewgroup_footer_container" | ||||||
|             style="?attr/afc_button_bar_style" |             style="?attr/afc_button_bar_style" | ||||||
|   | |||||||
| @@ -1,26 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <!-- |  | ||||||
|     Copyright (c) 2012 Hai Bison |  | ||||||
|  |  | ||||||
|     See the file LICENSE at the root directory of this project for copying |  | ||||||
|     permission. |  | ||||||
| --> |  | ||||||
|  |  | ||||||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     android:layout_width="match_parent" |  | ||||||
|     android:layout_height="wrap_content" |  | ||||||
|     android:background="?attr/afc_color_list_group_view_background" > |  | ||||||
|  |  | ||||||
|     <TextView |  | ||||||
|         android:id="@+id/afc_textview_header" |  | ||||||
|         android:layout_width="match_parent" |  | ||||||
|         android:layout_height="wrap_content" |  | ||||||
|         android:layout_centerInParent="true" |  | ||||||
|         android:ellipsize="middle" |  | ||||||
|         android:gravity="center" |  | ||||||
|         android:maxLines="@integer/afc_bookmark_filename_max_lines" |  | ||||||
|         android:padding="@dimen/afc_10sp" |  | ||||||
|         android:textIsSelectable="false" |  | ||||||
|         android:textStyle="bold" /> |  | ||||||
|  |  | ||||||
| </RelativeLayout> |  | ||||||
| @@ -1,56 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <!-- |  | ||||||
|     Copyright (c) 2012 Hai Bison |  | ||||||
|  |  | ||||||
|     See the file LICENSE at the root directory of this project for copying |  | ||||||
|     permission. |  | ||||||
| --> |  | ||||||
|  |  | ||||||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     android:layout_width="match_parent" |  | ||||||
|     android:layout_height="wrap_content" |  | ||||||
|     android:orientation="horizontal" > |  | ||||||
|  |  | ||||||
|     <LinearLayout |  | ||||||
|         android:layout_width="0dp" |  | ||||||
|         android:layout_height="match_parent" |  | ||||||
|         android:layout_margin="@dimen/afc_5dp" |  | ||||||
|         android:layout_weight="1" |  | ||||||
|         android:orientation="vertical" > |  | ||||||
|  |  | ||||||
|         <TextView |  | ||||||
|             android:id="@+id/afc_text_name" |  | ||||||
|             android:layout_width="wrap_content" |  | ||||||
|             android:layout_height="wrap_content" |  | ||||||
|             android:layout_gravity="center_vertical" |  | ||||||
|             android:ellipsize="middle" |  | ||||||
|             android:gravity="center_vertical" |  | ||||||
|             android:maxLines="@integer/afc_bookmark_filename_max_lines" |  | ||||||
|             android:textAppearance="?android:attr/textAppearanceMedium" |  | ||||||
|             android:textIsSelectable="false" > |  | ||||||
|         </TextView> |  | ||||||
|  |  | ||||||
|         <TextView |  | ||||||
|             android:id="@+id/afc_text_path" |  | ||||||
|             android:layout_width="wrap_content" |  | ||||||
|             android:layout_height="wrap_content" |  | ||||||
|             android:layout_marginTop="@dimen/afc_2dp" |  | ||||||
|             android:ellipsize="middle" |  | ||||||
|             android:maxLines="@integer/afc_bookmark_pathname_max_lines" |  | ||||||
|             android:textIsSelectable="false" |  | ||||||
|             android:visibility="gone" > |  | ||||||
|         </TextView> |  | ||||||
|     </LinearLayout> |  | ||||||
|  |  | ||||||
|     <CheckBox |  | ||||||
|         android:id="@+id/afc_checkbox" |  | ||||||
|         android:layout_width="wrap_content" |  | ||||||
|         android:layout_height="match_parent" |  | ||||||
|         android:layout_gravity="top" |  | ||||||
|         android:focusable="false" |  | ||||||
|         android:focusableInTouchMode="false" |  | ||||||
|         android:gravity="top" |  | ||||||
|         android:padding="@dimen/afc_5dp" |  | ||||||
|         android:visibility="gone" /> |  | ||||||
|  |  | ||||||
| </LinearLayout> |  | ||||||
| @@ -8,22 +8,11 @@ | |||||||
|  |  | ||||||
| <menu xmlns:android="http://schemas.android.com/apk/res/android" | <menu xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     xmlns:afc="http://schemas.android.com/apk/res-auto" > |     xmlns:afc="http://schemas.android.com/apk/res-auto" > | ||||||
|  |  | ||||||
|     <item |  | ||||||
|         android:id="@+id/afc_menuitem_bookmarks" |  | ||||||
|         afc:showAsAction="ifRoom" |  | ||||||
|         android:icon="?attr/afc_ic_menu_bookmarks" |  | ||||||
|         android:title="@string/afc_title_bookmarks"/> |  | ||||||
|     <item |     <item | ||||||
|         android:id="@+id/afc_menuitem_home" |         android:id="@+id/afc_menuitem_home" | ||||||
|         afc:showAsAction="ifRoom" |         afc:showAsAction="ifRoom" | ||||||
|         android:icon="?attr/afc_ic_menu_home" |         android:icon="?attr/afc_ic_menu_home" | ||||||
|         android:title="@string/afc_cmd_home"/> |         android:title="@string/afc_cmd_home"/> | ||||||
|     <item |  | ||||||
|         android:id="@+id/afc_menuitem_history" |  | ||||||
|         afc:showAsAction="ifRoom" |  | ||||||
|         android:icon="@android:drawable/ic_menu_recent_history" |  | ||||||
|         android:title="@string/afc_history"/> |  | ||||||
|     <item |     <item | ||||||
|         android:id="@+id/afc_menuitem_sort" |         android:id="@+id/afc_menuitem_sort" | ||||||
|         afc:showAsAction="ifRoom" |         afc:showAsAction="ifRoom" | ||||||
|   | |||||||
| @@ -1,17 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <!-- |  | ||||||
|     Copyright (c) 2012 Hai Bison |  | ||||||
|  |  | ||||||
|     See the file LICENSE at the root directory of this project for copying |  | ||||||
|     permission. |  | ||||||
| --> |  | ||||||
|  |  | ||||||
| <menu xmlns:android="http://schemas.android.com/apk/res/android" > |  | ||||||
|  |  | ||||||
|     <item |  | ||||||
|         android:id="@+id/afc_menuitem_clear" |  | ||||||
|         android:icon="@android:drawable/ic_menu_close_clear_cancel" |  | ||||||
|         android:showAsAction="ifRoom|withText" |  | ||||||
|         android:title="@string/afc_cmd_clear"/> |  | ||||||
|  |  | ||||||
| </menu> |  | ||||||
| @@ -14,7 +14,6 @@ | |||||||
|  |  | ||||||
| <resources> | <resources> | ||||||
|  |  | ||||||
|     <string name="afc_cmd_add_to_bookmarks">Añadir a favoritos</string> |  | ||||||
|     <string name="afc_cmd_advanced_selection_all">Todos</string> |     <string name="afc_cmd_advanced_selection_all">Todos</string> | ||||||
|     <string name="afc_cmd_advanced_selection_invert">Invertir selección</string> |     <string name="afc_cmd_advanced_selection_invert">Invertir selección</string> | ||||||
|     <string name="afc_cmd_advanced_selection_none">Ninguno</string> |     <string name="afc_cmd_advanced_selection_none">Ninguno</string> | ||||||
| @@ -43,12 +42,10 @@ | |||||||
|     <string name="afc_history">Historia</string> |     <string name="afc_history">Historia</string> | ||||||
|     <string name="afc_msg_app_doesnot_have_permission_to_create_files">La aplicación no tiene permisos para crear ficheros/directorios</string> |     <string name="afc_msg_app_doesnot_have_permission_to_create_files">La aplicación no tiene permisos para crear ficheros/directorios</string> | ||||||
|     <string name="afc_msg_app_doesnot_have_permission_to_delete_files">La aplicación no tiene permisos para eliminar ficheros/directorios</string> |     <string name="afc_msg_app_doesnot_have_permission_to_delete_files">La aplicación no tiene permisos para eliminar ficheros/directorios</string> | ||||||
|     <string name="afc_msg_bookmark_name_is_invalid">Nombre de favorito no válido</string> |  | ||||||
|     <string name="afc_msg_cancelled">Cancelado</string> |     <string name="afc_msg_cancelled">Cancelado</string> | ||||||
|     <string name="afc_msg_cannot_connect_to_file_provider_service">No se puede conectar con el servicio proveedor de ficheros</string> |     <string name="afc_msg_cannot_connect_to_file_provider_service">No se puede conectar con el servicio proveedor de ficheros</string> | ||||||
|     <string name="afc_msg_cannot_create_new_folder_here">No se puede crear un nuevo directorio aquí</string> |     <string name="afc_msg_cannot_create_new_folder_here">No se puede crear un nuevo directorio aquí</string> | ||||||
|     <string name="afc_msg_cannot_save_a_file_here">No se puede guardar un archivo aquí</string> |     <string name="afc_msg_cannot_save_a_file_here">No se puede guardar un archivo aquí</string> | ||||||
|     <string name="afc_msg_confirm_clear_all_bookmarks">¿Seguro que deseas borrar todos los favoritos?</string> |  | ||||||
|     <string name="afc_msg_confirm_clear_history">¿Está seguro que desea borrar el historial?</string> |     <string name="afc_msg_confirm_clear_history">¿Está seguro que desea borrar el historial?</string> | ||||||
|     <string name="afc_msg_done">Hecho</string> |     <string name="afc_msg_done">Hecho</string> | ||||||
|     <string name="afc_msg_empty">Vacío</string> |     <string name="afc_msg_empty">Vacío</string> | ||||||
| @@ -71,15 +68,11 @@ | |||||||
|     <string name="afc_root">Raiz</string> |     <string name="afc_root">Raiz</string> | ||||||
|     <string name="afc_title_advanced_selection">Seleccionar…</string> |     <string name="afc_title_advanced_selection">Seleccionar…</string> | ||||||
|     <string name="afc_title_alert">Alerta</string> |     <string name="afc_title_alert">Alerta</string> | ||||||
|     <string name="afc_title_bookmark_manager">Administrador de favoritos</string> |  | ||||||
|     <string name="afc_title_bookmarks">Favoritos</string> |  | ||||||
|     <string name="afc_title_confirmation">Confirmación</string> |     <string name="afc_title_confirmation">Confirmación</string> | ||||||
|     <string name="afc_title_date">Fecha</string> |     <string name="afc_title_date">Fecha</string> | ||||||
|     <string name="afc_title_error">Error</string> |     <string name="afc_title_error">Error</string> | ||||||
|     <string name="afc_title_history">Historial</string> |  | ||||||
|     <string name="afc_title_info">Información</string> |     <string name="afc_title_info">Información</string> | ||||||
|     <string name="afc_title_name">Nombre</string> |     <string name="afc_title_name">Nombre</string> | ||||||
|     <string name="afc_title_new_bookmark">Nuevo favorito</string> |  | ||||||
|     <string name="afc_title_rename">Renombrar…</string> |     <string name="afc_title_rename">Renombrar…</string> | ||||||
|     <string name="afc_title_save_as">Guardar como…</string> |     <string name="afc_title_save_as">Guardar como…</string> | ||||||
|     <string name="afc_title_size">Tamaño</string> |     <string name="afc_title_size">Tamaño</string> | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ | |||||||
| <resources xmlns:android="http://schemas.android.com/apk/res/android"> | <resources xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Dark" parent="@style/Afc.BaseTheme.Dark"> |     <style name="Afc.BaseThemeHelper.Dark" parent="@style/Afc.BaseTheme.Dark"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks_light</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> | ||||||
| @@ -33,7 +32,6 @@ | |||||||
|     <style name="Afc.BaseTheme.Dialog.Dark" parent="@android:style/Theme.Holo.Dialog"></style> |     <style name="Afc.BaseTheme.Dialog.Dark" parent="@android:style/Theme.Holo.Dialog"></style> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Dialog.Dark" parent="@style/Afc.BaseTheme.Dialog.Dark"> |     <style name="Afc.BaseThemeHelper.Dialog.Dark" parent="@style/Afc.BaseTheme.Dialog.Dark"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks_light</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> | ||||||
|   | |||||||
| @@ -9,7 +9,6 @@ | |||||||
| <resources xmlns:android="http://schemas.android.com/apk/res/android"> | <resources xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Light" parent="@style/Afc.BaseTheme.Light"> |     <style name="Afc.BaseThemeHelper.Light" parent="@style/Afc.BaseTheme.Light"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks_light</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> | ||||||
| @@ -32,7 +31,6 @@ | |||||||
|     <style name="Afc.BaseTheme.Dialog.Light" parent="@android:style/Theme.Holo.Light.Dialog"></style> |     <style name="Afc.BaseTheme.Dialog.Light" parent="@android:style/Theme.Holo.Light.Dialog"></style> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Dialog.Light" parent="@style/Afc.BaseTheme.Dialog.Light"> |     <style name="Afc.BaseThemeHelper.Dialog.Light" parent="@style/Afc.BaseTheme.Dialog.Light"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks_light</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ | |||||||
|     <style name="Afc.BaseTheme.Dark" parent="@style/Theme.AppCompat"></style> |     <style name="Afc.BaseTheme.Dark" parent="@style/Theme.AppCompat"></style> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Dark" parent="@style/Afc.BaseTheme.Dark"> |     <style name="Afc.BaseThemeHelper.Dark" parent="@style/Afc.BaseTheme.Dark"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks_light</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ | |||||||
|     <style name="Afc.BaseTheme.Light" parent="@style/Theme.AppCompat.Light.DarkActionBar"></style> |     <style name="Afc.BaseTheme.Light" parent="@style/Theme.AppCompat.Light.DarkActionBar"></style> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Light" parent="@style/Afc.BaseTheme.Light"> |     <style name="Afc.BaseThemeHelper.Light" parent="@style/Afc.BaseTheme.Light"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks_light</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home_light</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview_light</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview_light</item> | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ | |||||||
|  |  | ||||||
| <resources> | <resources> | ||||||
|  |  | ||||||
|     <string name="afc_cmd_add_to_bookmarks">Thêm vô danh sách ưa thích…</string> |  | ||||||
|     <string name="afc_cmd_advanced_selection_all">Tất cả</string> |     <string name="afc_cmd_advanced_selection_all">Tất cả</string> | ||||||
|     <string name="afc_cmd_advanced_selection_invert">Đảo lựa chọn</string> |     <string name="afc_cmd_advanced_selection_invert">Đảo lựa chọn</string> | ||||||
|     <string name="afc_cmd_advanced_selection_none">Không chọn</string> |     <string name="afc_cmd_advanced_selection_none">Không chọn</string> | ||||||
| @@ -37,12 +36,10 @@ | |||||||
|     <string name="afc_history">Lịch sử</string> |     <string name="afc_history">Lịch sử</string> | ||||||
|     <string name="afc_msg_app_doesnot_have_permission_to_create_files">Ứng dụng này không có quyền tạo mới tập tin/ thư mục</string> |     <string name="afc_msg_app_doesnot_have_permission_to_create_files">Ứng dụng này không có quyền tạo mới tập tin/ thư mục</string> | ||||||
|     <string name="afc_msg_app_doesnot_have_permission_to_delete_files">Ứng dụng này không có quyền xóa tập tin/ thư mục</string> |     <string name="afc_msg_app_doesnot_have_permission_to_delete_files">Ứng dụng này không có quyền xóa tập tin/ thư mục</string> | ||||||
|     <string name="afc_msg_bookmark_name_is_invalid">Tên không hợp lệ</string> |  | ||||||
|     <string name="afc_msg_cancelled">Hủy bỏ</string> |     <string name="afc_msg_cancelled">Hủy bỏ</string> | ||||||
|     <string name="afc_msg_cannot_connect_to_file_provider_service">Không thể kết nối đến dịch vụ cung cấp tập tin</string> |     <string name="afc_msg_cannot_connect_to_file_provider_service">Không thể kết nối đến dịch vụ cung cấp tập tin</string> | ||||||
|     <string name="afc_msg_cannot_create_new_folder_here">Không thể tạo thư mục mới ở đây</string> |     <string name="afc_msg_cannot_create_new_folder_here">Không thể tạo thư mục mới ở đây</string> | ||||||
|     <string name="afc_msg_cannot_save_a_file_here">Không thể lưu tập tin ở đây</string> |     <string name="afc_msg_cannot_save_a_file_here">Không thể lưu tập tin ở đây</string> | ||||||
|     <string name="afc_msg_confirm_clear_all_bookmarks">Bạn có chắc muốn xóa hết danh sách ưa thích không?</string> |  | ||||||
|     <string name="afc_msg_confirm_clear_history">Bạn có chắc muốn xoá hết lịch sử không?</string> |     <string name="afc_msg_confirm_clear_history">Bạn có chắc muốn xoá hết lịch sử không?</string> | ||||||
|     <string name="afc_msg_done">Xong</string> |     <string name="afc_msg_done">Xong</string> | ||||||
|     <string name="afc_msg_empty">Không có gì</string> |     <string name="afc_msg_empty">Không có gì</string> | ||||||
| @@ -64,15 +61,12 @@ | |||||||
|     <string name="afc_pmsg_xxx_items">%1$,d lựa chọn</string> |     <string name="afc_pmsg_xxx_items">%1$,d lựa chọn</string> | ||||||
|     <string name="afc_title_advanced_selection">Chọn…</string> |     <string name="afc_title_advanced_selection">Chọn…</string> | ||||||
|     <string name="afc_title_alert">Cảnh báo</string> |     <string name="afc_title_alert">Cảnh báo</string> | ||||||
|     <string name="afc_title_bookmark_manager">Quản lý danh sách ưa thích</string> |  | ||||||
|     <string name="afc_title_bookmarks">Ưa thích</string> |  | ||||||
|     <string name="afc_title_confirmation">Xác nhận</string> |     <string name="afc_title_confirmation">Xác nhận</string> | ||||||
|     <string name="afc_title_date">Ngày tháng</string> |     <string name="afc_title_date">Ngày tháng</string> | ||||||
|     <string name="afc_title_error">Lỗi</string> |     <string name="afc_title_error">Lỗi</string> | ||||||
|     <string name="afc_title_history">Lịch sử</string> |     <string name="afc_title_history">Lịch sử</string> | ||||||
|     <string name="afc_title_info">Thông tin</string> |     <string name="afc_title_info">Thông tin</string> | ||||||
|     <string name="afc_title_name">Tên</string> |     <string name="afc_title_name">Tên</string> | ||||||
|     <string name="afc_title_new_bookmark">Thêm thư mục ưa thích</string> |  | ||||||
|     <string name="afc_title_rename">Đổi tên…</string> |     <string name="afc_title_rename">Đổi tên…</string> | ||||||
|     <string name="afc_title_save_as">Lưu…</string> |     <string name="afc_title_save_as">Lưu…</string> | ||||||
|     <string name="afc_title_size">Kích thước</string> |     <string name="afc_title_size">Kích thước</string> | ||||||
|   | |||||||
| @@ -27,7 +27,6 @@ | |||||||
|  |  | ||||||
|     <attr name="afc_theme_dialog" format="reference" /> |     <attr name="afc_theme_dialog" format="reference" /> | ||||||
|     <attr name="afc_button_home" format="reference" /> |     <attr name="afc_button_home" format="reference" /> | ||||||
|     <attr name="afc_ic_menu_bookmarks" format="reference" /> |  | ||||||
|     <attr name="afc_ic_menu_home" format="reference" /> |     <attr name="afc_ic_menu_home" format="reference" /> | ||||||
|     <attr name="afc_ic_menu_gridview" format="reference" /> |     <attr name="afc_ic_menu_gridview" format="reference" /> | ||||||
|     <attr name="afc_ic_menu_listview" format="reference" /> |     <attr name="afc_ic_menu_listview" format="reference" /> | ||||||
|   | |||||||
| @@ -8,11 +8,11 @@ | |||||||
|  |  | ||||||
| <resources> | <resources> | ||||||
|  |  | ||||||
|     <string name="afc_lib_name">android-filechooser</string> |     <string name="afc_lib_name" translatable="false">android-filechooser</string> | ||||||
|  |  | ||||||
|     <integer name="afc_lib_version_code">51</integer> |     <integer name="afc_lib_version_code">51</integer> | ||||||
|  |  | ||||||
|     <string name="afc_lib_version_name">5.4</string> |     <string name="afc_lib_version_name"  translatable="false">5.4</string> | ||||||
|  |  | ||||||
|     <bool name="afc_is_large_screen">false</bool> |     <bool name="afc_is_large_screen">false</bool> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,8 +8,6 @@ | |||||||
|  |  | ||||||
| <resources> | <resources> | ||||||
|  |  | ||||||
|     <integer name="afc_bookmark_filename_max_lines">1</integer> |  | ||||||
|     <integer name="afc_bookmark_pathname_max_lines">3</integer> |  | ||||||
|     <integer name="afc_history_filename_max_lines">2</integer> |     <integer name="afc_history_filename_max_lines">2</integer> | ||||||
|     <integer name="afc_history_pathname_max_lines">3</integer> |     <integer name="afc_history_pathname_max_lines">3</integer> | ||||||
|     <integer name="afc_afc_search_view_delay_time_submission">999</integer> |     <integer name="afc_afc_search_view_delay_time_submission">999</integer> | ||||||
|   | |||||||
| @@ -8,13 +8,13 @@ | |||||||
|  |  | ||||||
| <resources> | <resources> | ||||||
|  |  | ||||||
|     <string name="afc_pkey_display_view_type">afc.display.view_type</string> |     <string name="afc_pkey_display_view_type" translatable="false">afc.display.view_type</string> | ||||||
|     <string name="afc_pkey_display_sort_type">afc.display.sort_type</string> |     <string name="afc_pkey_display_sort_type" translatable="false">afc.display.sort_type</string> | ||||||
|     <string name="afc_pkey_display_sort_ascending">afc.display.sort_ascending</string> |     <string name="afc_pkey_display_sort_ascending" translatable="false">afc.display.sort_ascending</string> | ||||||
|     <string name="afc_pkey_display_show_time_for_old_days_this_year">afc.display.show_time_for_old_days_this_year</string> |     <string name="afc_pkey_display_show_time_for_old_days_this_year" translatable="false">afc.display.show_time_for_old_days_this_year</string> | ||||||
|     <string name="afc_pkey_display_show_time_for_old_days">afc.display.show_time_for_old_days</string> |     <string name="afc_pkey_display_show_time_for_old_days" translatable="false">afc.display.show_time_for_old_days</string> | ||||||
|     <string name="afc_pkey_display_remember_last_location">afc.display.remember_last_location</string> |     <string name="afc_pkey_display_remember_last_location" translatable="false">afc.display.remember_last_location</string> | ||||||
|     <string name="afc_pkey_display_last_location">afc.display.last_location</string> |     <string name="afc_pkey_display_last_location" translatable="false">afc.display.last_location</string> | ||||||
|  |  | ||||||
|     <integer name="afc_pkey_display_view_type_def">0</integer> |     <integer name="afc_pkey_display_view_type_def">0</integer> | ||||||
|     <integer name="afc_pkey_display_sort_type_def">0</integer> |     <integer name="afc_pkey_display_sort_type_def">0</integer> | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ | |||||||
|  |  | ||||||
| <resources> | <resources> | ||||||
|  |  | ||||||
|     <string name="afc_cmd_add_to_bookmarks">Add to bookmarks…</string> |  | ||||||
|     <string name="afc_cmd_advanced_selection_all">All</string> |     <string name="afc_cmd_advanced_selection_all">All</string> | ||||||
|     <string name="afc_cmd_advanced_selection_invert">Invert selection</string> |     <string name="afc_cmd_advanced_selection_invert">Invert selection</string> | ||||||
|     <string name="afc_cmd_advanced_selection_none">None</string> |     <string name="afc_cmd_advanced_selection_none">None</string> | ||||||
| @@ -37,12 +36,10 @@ | |||||||
|     <string name="afc_history">History</string> |     <string name="afc_history">History</string> | ||||||
|     <string name="afc_msg_app_doesnot_have_permission_to_create_files">This application does not have permission to create files/ folders</string> |     <string name="afc_msg_app_doesnot_have_permission_to_create_files">This application does not have permission to create files/ folders</string> | ||||||
|     <string name="afc_msg_app_doesnot_have_permission_to_delete_files">This application does not have permission to delete files/ folders</string> |     <string name="afc_msg_app_doesnot_have_permission_to_delete_files">This application does not have permission to delete files/ folders</string> | ||||||
|     <string name="afc_msg_bookmark_name_is_invalid">Bookmark name is invalid</string> |  | ||||||
|     <string name="afc_msg_cancelled">Cancelled</string> |     <string name="afc_msg_cancelled">Cancelled</string> | ||||||
|     <string name="afc_msg_cannot_connect_to_file_provider_service">Cannot connect to file provider service</string> |     <string name="afc_msg_cannot_connect_to_file_provider_service">Cannot connect to file provider service</string> | ||||||
|     <string name="afc_msg_cannot_create_new_folder_here">Cannot create new folder here</string> |     <string name="afc_msg_cannot_create_new_folder_here">Cannot create new folder here</string> | ||||||
|     <string name="afc_msg_cannot_save_a_file_here">Cannot save a file here</string> |     <string name="afc_msg_cannot_save_a_file_here">Cannot save a file here</string> | ||||||
|     <string name="afc_msg_confirm_clear_all_bookmarks">Do you really want to clear all bookmarks?</string> |  | ||||||
|     <string name="afc_msg_confirm_clear_history">Are you sure you want to clear history?</string> |     <string name="afc_msg_confirm_clear_history">Are you sure you want to clear history?</string> | ||||||
|     <string name="afc_msg_done">Done</string> |     <string name="afc_msg_done">Done</string> | ||||||
|     <string name="afc_msg_empty">Empty</string> |     <string name="afc_msg_empty">Empty</string> | ||||||
| @@ -65,15 +62,11 @@ | |||||||
|     <string name="afc_root">Root</string> |     <string name="afc_root">Root</string> | ||||||
|     <string name="afc_title_advanced_selection">Select…</string> |     <string name="afc_title_advanced_selection">Select…</string> | ||||||
|     <string name="afc_title_alert">Alert</string> |     <string name="afc_title_alert">Alert</string> | ||||||
|     <string name="afc_title_bookmark_manager">Bookmark manager</string> |  | ||||||
|     <string name="afc_title_bookmarks">Bookmarks</string> |  | ||||||
|     <string name="afc_title_confirmation">Confirmation</string> |     <string name="afc_title_confirmation">Confirmation</string> | ||||||
|     <string name="afc_title_date">Date</string> |     <string name="afc_title_date">Date</string> | ||||||
|     <string name="afc_title_error">Error</string> |     <string name="afc_title_error">Error</string> | ||||||
|     <string name="afc_title_history">History</string> |  | ||||||
|     <string name="afc_title_info">Info</string> |     <string name="afc_title_info">Info</string> | ||||||
|     <string name="afc_title_name">Name</string> |     <string name="afc_title_name">Name</string> | ||||||
|     <string name="afc_title_new_bookmark">New bookmark</string> |  | ||||||
|     <string name="afc_title_rename">Rename…</string> |     <string name="afc_title_rename">Rename…</string> | ||||||
|     <string name="afc_title_save_as">Save as…</string> |     <string name="afc_title_save_as">Save as…</string> | ||||||
|     <string name="afc_title_size">Size</string> |     <string name="afc_title_size">Size</string> | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ | |||||||
|     <style name="Afc.BaseTheme.Dark" parent="@android:style/Theme"></style> |     <style name="Afc.BaseTheme.Dark" parent="@android:style/Theme"></style> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Dark" parent="@style/Afc.BaseTheme.Dark"> |     <style name="Afc.BaseThemeHelper.Dark" parent="@style/Afc.BaseTheme.Dark"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> | ||||||
| @@ -60,7 +59,6 @@ | |||||||
|  |  | ||||||
|         <!-- android-filechooser --> |         <!-- android-filechooser --> | ||||||
|  |  | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> | ||||||
|   | |||||||
| @@ -19,7 +19,6 @@ | |||||||
|     <style name="Afc.BaseTheme.Light" parent="@android:style/Theme.Light"></style> |     <style name="Afc.BaseTheme.Light" parent="@android:style/Theme.Light"></style> | ||||||
|  |  | ||||||
|     <style name="Afc.BaseThemeHelper.Light" parent="@style/Afc.BaseTheme.Light"> |     <style name="Afc.BaseThemeHelper.Light" parent="@style/Afc.BaseTheme.Light"> | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> | ||||||
| @@ -59,7 +58,6 @@ | |||||||
|  |  | ||||||
|         <!-- android-filechooser --> |         <!-- android-filechooser --> | ||||||
|  |  | ||||||
|         <item name="afc_ic_menu_bookmarks">@drawable/afc_ic_menu_bookmarks</item> |  | ||||||
|         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> |         <item name="afc_ic_menu_home">@drawable/afc_ic_menu_home</item> | ||||||
|         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> |         <item name="afc_ic_menu_gridview">@drawable/afc_ic_menu_gridview</item> | ||||||
|         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> |         <item name="afc_ic_menu_listview">@drawable/afc_ic_menu_listview</item> | ||||||
|   | |||||||
| @@ -28,8 +28,6 @@ import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils; | |||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Dlg; | 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.LoadingDialog; | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Ui; | import group.pals.android.lib.ui.filechooser.utils.ui.Ui; | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.bookmark.BookmarkFragment; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.history.HistoryFragment; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Calendar; | import java.util.Calendar; | ||||||
| @@ -220,8 +218,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|      */ |      */ | ||||||
|  |  | ||||||
|     private View mBtnGoHome; |     private View mBtnGoHome; | ||||||
|     private View mBtnBookmarkManager; |  | ||||||
|     private BookmarkFragment mBookmarkFragment; |  | ||||||
|     private HorizontalScrollView mViewLocationsContainer; |     private HorizontalScrollView mViewLocationsContainer; | ||||||
|     private ViewGroup mViewLocations; |     private ViewGroup mViewLocations; | ||||||
|     private View mViewGroupFiles; |     private View mViewGroupFiles; | ||||||
| @@ -304,8 +300,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|          */ |          */ | ||||||
|  |  | ||||||
|         mBtnGoHome = rootView.findViewById(R.id.afc_textview_home); |         mBtnGoHome = rootView.findViewById(R.id.afc_textview_home); | ||||||
|         mBtnBookmarkManager = rootView |  | ||||||
|                 .findViewById(R.id.afc_textview_bookmarks); |  | ||||||
|         mViewGoBack = (ImageView) rootView |         mViewGoBack = (ImageView) rootView | ||||||
|                 .findViewById(R.id.afc_button_go_back); |                 .findViewById(R.id.afc_button_go_back); | ||||||
|         mViewGoForward = (ImageView) rootView |         mViewGoForward = (ImageView) rootView | ||||||
| @@ -326,28 +320,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|                 .findViewById(R.id.afc_textview_saveas_filename); |                 .findViewById(R.id.afc_textview_saveas_filename); | ||||||
|         mBtnOk = (Button) rootView.findViewById(R.id.afc_button_ok); |         mBtnOk = (Button) rootView.findViewById(R.id.afc_button_ok); | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * INIT CONTROLS |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Load BookmarkFragment. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         View viewBookmarks = rootView.findViewById(R.id.afc_fragment_bookmarks); |  | ||||||
|         if (viewBookmarks != null) { |  | ||||||
|             mBookmarkFragment = (BookmarkFragment) getChildFragmentManager() |  | ||||||
|                     .findFragmentById(R.id.afc_fragment_bookmarks); |  | ||||||
|             if (mBookmarkFragment == null) { |  | ||||||
|                 mBookmarkFragment = BookmarkFragment.newInstance(false); |  | ||||||
|                 mBookmarkFragment |  | ||||||
|                         .setOnBookmarkItemClickListener(mBookmarkFragmentOnBookmarkItemClickListener); |  | ||||||
|  |  | ||||||
|                 getChildFragmentManager().beginTransaction() |  | ||||||
|                         .add(R.id.afc_fragment_bookmarks, mBookmarkFragment) |  | ||||||
|                         .commit(); |  | ||||||
|             } |  | ||||||
|         }// if |  | ||||||
|  |  | ||||||
|         return rootView; |         return rootView; | ||||||
|     }// onCreateView() |     }// onCreateView() | ||||||
| @@ -441,10 +413,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|             doSwitchViewType(); |             doSwitchViewType(); | ||||||
|         else if (item.getItemId() == R.id.afc_menuitem_home) |         else if (item.getItemId() == R.id.afc_menuitem_home) | ||||||
|             doGoHome(); |             doGoHome(); | ||||||
|         else if (item.getItemId() == R.id.afc_menuitem_history) |  | ||||||
|             doShowHistoryManager(); |  | ||||||
|         else if (item.getItemId() == R.id.afc_menuitem_bookmarks) |  | ||||||
|             doShowBookmarkManager(); |  | ||||||
|         else |         else | ||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
| @@ -693,9 +661,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|     private void setupHeader() { |     private void setupHeader() { | ||||||
|         if (mBtnGoHome != null) |         if (mBtnGoHome != null) | ||||||
|             mBtnGoHome.setOnClickListener(mBtnGoHomeOnClickListener); |             mBtnGoHome.setOnClickListener(mBtnGoHomeOnClickListener); | ||||||
|         if (mBtnBookmarkManager != null) |  | ||||||
|             mBtnBookmarkManager |  | ||||||
|                     .setOnClickListener(mBtnBookmarkManagerOnClickListener); |  | ||||||
|  |  | ||||||
|         if (mIsSaveDialog) { |         if (mIsSaveDialog) { | ||||||
|             getActivity().setTitle(R.string.afc_title_save_as); |             getActivity().setTitle(R.string.afc_title_save_as); | ||||||
| @@ -728,8 +693,7 @@ public class FragmentFiles extends Fragment implements | |||||||
|         mViewGoForward.setEnabled(false); |         mViewGoForward.setEnabled(false); | ||||||
|         mViewGoForward.setOnClickListener(mBtnGoForwardOnClickListener); |         mViewGoForward.setOnClickListener(mBtnGoForwardOnClickListener); | ||||||
|  |  | ||||||
|         for (ImageView v : new ImageView[] { mViewGoBack, mViewGoForward }) |  | ||||||
|             v.setOnLongClickListener(mBtnGoBackForwardOnLongClickListener); |  | ||||||
|     }// setupHeader() |     }// setupHeader() | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -1194,62 +1158,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|         goTo(mRoot); |         goTo(mRoot); | ||||||
|     }// doGoHome() |     }// doGoHome() | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Shows bookmark manager. |  | ||||||
|      */ |  | ||||||
|     private void doShowBookmarkManager() { |  | ||||||
|         BookmarkFragment bf = BookmarkFragment.newInstance(true); |  | ||||||
|         bf.setOnBookmarkItemClickListener(mBookmarkFragmentOnBookmarkItemClickListener); |  | ||||||
|         bf.show(getChildFragmentManager().beginTransaction(), |  | ||||||
|                 BookmarkFragment.class.getName()); |  | ||||||
|     }// doShowBookmarkManager() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Shows history manager. |  | ||||||
|      */ |  | ||||||
|     private void doShowHistoryManager() { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "doShowHistoryManager()"); |  | ||||||
|  |  | ||||||
|         // Create and show the dialog. |  | ||||||
|         final HistoryFragment fragment = HistoryFragment.newInstance(); |  | ||||||
|         fragment.setOnHistoryItemClickListener(new HistoryFragment.OnHistoryItemClickListener() { |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public void onItemClick(String providerId, final Uri uri) { |  | ||||||
|                 /* |  | ||||||
|                  * TODO what to do with `providerId`? |  | ||||||
|                  */ |  | ||||||
|  |  | ||||||
|                 /* |  | ||||||
|                  * Check if `uri` is in internal list, then use it instead of |  | ||||||
|                  * that. |  | ||||||
|                  */ |  | ||||||
|                 if (!mHistory.find(new HistoryFilter<Uri>() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public boolean accept(Uri item) { |  | ||||||
|                         if (uri.equals(item)) { |  | ||||||
|                             goTo(item); |  | ||||||
|                             return true; |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         return false; |  | ||||||
|                     }// accept() |  | ||||||
|                 }, false)) |  | ||||||
|                     goTo(uri); |  | ||||||
|             }// onItemClick() |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * DialogFragment.show() will take care of adding the fragment in a |  | ||||||
|          * transaction. We also want to remove any currently showing dialog, so |  | ||||||
|          * make our own transaction and take care of that here. |  | ||||||
|          */ |  | ||||||
|         fragment.show(getChildFragmentManager().beginTransaction(), |  | ||||||
|                 HistoryFragment.class.getName()); |  | ||||||
|     }// doShowHistoryManager() |  | ||||||
|  |  | ||||||
|     private static final int[] BUTTON_SORT_IDS = { |     private static final int[] BUTTON_SORT_IDS = { | ||||||
|             R.id.afc_button_sort_by_name_asc, |             R.id.afc_button_sort_by_name_asc, | ||||||
|             R.id.afc_button_sort_by_name_desc, |             R.id.afc_button_sort_by_name_desc, | ||||||
| @@ -1948,15 +1856,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|         }// onClick() |         }// onClick() | ||||||
|     };// mBtnGoHomeOnClickListener |     };// mBtnGoHomeOnClickListener | ||||||
|  |  | ||||||
|     private final View.OnClickListener mBtnBookmarkManagerOnClickListener = new View.OnClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onClick(View v) { |  | ||||||
|             if (mBookmarkFragment != null) |  | ||||||
|                 mBookmarkFragment.setEditor(!mBookmarkFragment.isEditor()); |  | ||||||
|         }// onClick() |  | ||||||
|     };// mBtnBookmarkManagerOnClickListener |  | ||||||
|  |  | ||||||
|     private final View.OnClickListener mBtnGoBackOnClickListener = new View.OnClickListener() { |     private final View.OnClickListener mBtnGoBackOnClickListener = new View.OnClickListener() { | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
| @@ -2023,15 +1922,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|         }// onClick() |         }// onClick() | ||||||
|     };// mBtnGoForwardOnClickListener |     };// mBtnGoForwardOnClickListener | ||||||
|  |  | ||||||
|     private final View.OnLongClickListener mBtnGoBackForwardOnLongClickListener = new View.OnLongClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onLongClick(View v) { |  | ||||||
|             doShowHistoryManager(); |  | ||||||
|             return true; |  | ||||||
|         }// onLongClick() |  | ||||||
|     };// mBtnGoBackForwardOnLongClickListener |  | ||||||
|  |  | ||||||
|     private final TextView.OnEditorActionListener mTxtFilenameOnEditorActionListener = new TextView.OnEditorActionListener() { |     private final TextView.OnEditorActionListener mTxtFilenameOnEditorActionListener = new TextView.OnEditorActionListener() { | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
| @@ -2067,32 +1957,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|      * FRAGMENT LISTENERS |      * FRAGMENT LISTENERS | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|     private final BookmarkFragment.OnBookmarkItemClickListener mBookmarkFragmentOnBookmarkItemClickListener = new BookmarkFragment.OnBookmarkItemClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onItemClick(String providerId, final Uri uri) { |  | ||||||
|             /* |  | ||||||
|              * TODO what to do with `providerId`? |  | ||||||
|              */ |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * Check if `uri` is in internal list, then use it instead of that. |  | ||||||
|              */ |  | ||||||
|             if (!mHistory.find(new HistoryFilter<Uri>() { |  | ||||||
|  |  | ||||||
|                 @Override |  | ||||||
|                 public boolean accept(Uri item) { |  | ||||||
|                     if (uri.equals(item)) { |  | ||||||
|                         goTo(item); |  | ||||||
|                         return true; |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     return false; |  | ||||||
|                 }// accept() |  | ||||||
|             }, false)) |  | ||||||
|                 goTo(uri); |  | ||||||
|         }// onItemClick() |  | ||||||
|     };// mBookmarkFragmentOnBookmarkItemClickListener |  | ||||||
|  |  | ||||||
|     /* |     /* | ||||||
|      * LISTVIEW HELPER |      * LISTVIEW HELPER | ||||||
| @@ -2167,22 +2031,6 @@ public class FragmentFiles extends Fragment implements | |||||||
|             final Uri uri = BaseFileProviderUtils.getUri(cursor); |             final Uri uri = BaseFileProviderUtils.getUri(cursor); | ||||||
|             final String name = BaseFileProviderUtils.getFileName(cursor); |             final String name = BaseFileProviderUtils.getFileName(cursor); | ||||||
|  |  | ||||||
|             ContextMenuUtils.showContextMenu(getActivity(), 0, 0, |  | ||||||
|                     new Integer[] { R.string.afc_cmd_add_to_bookmarks }, |  | ||||||
|                     new ContextMenuUtils.OnMenuItemClickListener() { |  | ||||||
|  |  | ||||||
|                         @Override |  | ||||||
|                         public void onClick(final int resId) { |  | ||||||
|                             if (resId == R.string.afc_cmd_add_to_bookmarks) { |  | ||||||
|                                 BookmarkFragment |  | ||||||
|                                         .doEnterNewNameOrRenameBookmark( |  | ||||||
|                                                 getActivity(), |  | ||||||
|                                                 BaseFileProviderUtils.getProviderId(uri |  | ||||||
|                                                         .getAuthority()), -1, |  | ||||||
|                                                 uri, name); |  | ||||||
|                             } |  | ||||||
|                         }// onClick() |  | ||||||
|                     }); |  | ||||||
|         }// onBuildOptionsMenu() |         }// onBuildOptionsMenu() | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
|   | |||||||
| @@ -1,124 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    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.providers.bookmark; |  | ||||||
|  |  | ||||||
| import android.content.Context; |  | ||||||
| import android.net.Uri; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.BaseColumns; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.ProviderUtils; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Bookmark contract. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public final class BookmarkContract implements BaseColumns { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The raw authority. |  | ||||||
|      */ |  | ||||||
|     private static final String AUTHORITY = "android-filechooser.bookmark"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets the authority of this provider. |  | ||||||
|      *  |  | ||||||
|      * @param context |  | ||||||
|      *            the context. |  | ||||||
|      * @return the authority. |  | ||||||
|      */ |  | ||||||
|     public static final String getAuthority(Context context) { |  | ||||||
|         return context.getPackageName() + "." + AUTHORITY; |  | ||||||
|     }// getAuthority() |  | ||||||
|  |  | ||||||
|     // This class cannot be instantiated |  | ||||||
|     private BookmarkContract() { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The table name offered by this provider. |  | ||||||
|      */ |  | ||||||
|     public static final String TABLE_NAME = "bookmarks"; |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * URI definitions. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Path parts for the URIs. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Path part for the Bookmark URI. |  | ||||||
|      */ |  | ||||||
|     public static final String PATH_BOOKMARKS = "bookmarks"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The content:// style URL for this table. |  | ||||||
|      */ |  | ||||||
|     public static final Uri genContentUri(Context context) { |  | ||||||
|         return Uri.parse(ProviderUtils.SCHEME + getAuthority(context) + "/" |  | ||||||
|                 + PATH_BOOKMARKS); |  | ||||||
|     }// genContentUri() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The content URI base for a single Bookmark item. Callers must append a |  | ||||||
|      * numeric Bookmark id to this Uri to retrieve a Bookmark item. |  | ||||||
|      */ |  | ||||||
|     public static final Uri genContentIdUriBase(Context context) { |  | ||||||
|         return Uri.parse(ProviderUtils.SCHEME + getAuthority(context) + "/" |  | ||||||
|                 + PATH_BOOKMARKS + "/"); |  | ||||||
|     }// genContentIdUriBase() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * MIME type definitions |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The MIME type of {@link #_ContentUri} providing a directory of Bookmark |  | ||||||
|      * items. |  | ||||||
|      */ |  | ||||||
|     public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.android-filechooser.bookmarks"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The MIME type of a {@link #_ContentUri} sub-directory of a single |  | ||||||
|      * Bookmark item. |  | ||||||
|      */ |  | ||||||
|     public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.android-filechooser.bookmarks"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The default sort order for this table. |  | ||||||
|      */ |  | ||||||
|     public static final String DEFAULT_SORT_ORDER = COLUMN_MODIFICATION_TIME |  | ||||||
|             + " DESC"; |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * Column definitions |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Column name for the URI of bookmark. |  | ||||||
|      * <p/> |  | ||||||
|      * Type: {@code String} |  | ||||||
|      */ |  | ||||||
|     public static final String COLUMN_URI = "uri"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Column name for the name of bookmark. |  | ||||||
|      * <p/> |  | ||||||
|      * Type: {@code String} |  | ||||||
|      */ |  | ||||||
|     public static final String COLUMN_NAME = "name"; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Column name for the ID of bookmark's provider ID. |  | ||||||
|      * <p/> |  | ||||||
|      * Type: {@code String} |  | ||||||
|      */ |  | ||||||
|     public static final String COLUMN_PROVIDER_ID = "provider_id"; |  | ||||||
| } |  | ||||||
| @@ -1,62 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    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.providers.bookmark; |  | ||||||
|  |  | ||||||
| import group.pals.android.lib.ui.filechooser.prefs.Prefs; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.DbUtils; |  | ||||||
| import android.content.Context; |  | ||||||
| import android.database.sqlite.SQLiteDatabase; |  | ||||||
| import android.database.sqlite.SQLiteOpenHelper; |  | ||||||
| import android.os.Build; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Database for bookmark. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public class BookmarkHelper extends SQLiteOpenHelper { |  | ||||||
|  |  | ||||||
|     @SuppressWarnings("unused") |  | ||||||
|     private static final String CLASSNAME = BookmarkHelper.class.getName(); |  | ||||||
|  |  | ||||||
|     private static final String DB_FILENAME = "Bookmarks.sqlite"; |  | ||||||
|     private static final int DB_VERSION = 1; |  | ||||||
|  |  | ||||||
|     // Database creation SQL statements |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @since v5.1 beta |  | ||||||
|      */ |  | ||||||
|     private static final String PATTERN_DB_CREATOR = String |  | ||||||
|             .format("CREATE VIRTUAL TABLE " + BookmarkContract.TABLE_NAME |  | ||||||
|                     + " USING %%s(" + BookmarkContract.COLUMN_CREATE_TIME + "," |  | ||||||
|                     + BookmarkContract.COLUMN_MODIFICATION_TIME + "," |  | ||||||
|                     + BookmarkContract.COLUMN_PROVIDER_ID + "," |  | ||||||
|                     + BookmarkContract.COLUMN_URI + "," |  | ||||||
|                     + BookmarkContract.COLUMN_NAME + ",tokenize=porter);"); |  | ||||||
|  |  | ||||||
|     public BookmarkHelper(Context context) { |  | ||||||
|         // always use application context |  | ||||||
|         super(context.getApplicationContext(), Prefs.genDatabaseFilename( |  | ||||||
|                 context, DB_FILENAME), null, DB_VERSION); |  | ||||||
|     }// BookmarkHelper() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onCreate(SQLiteDatabase db) { |  | ||||||
|         db.execSQL(String |  | ||||||
|                 .format(PATTERN_DB_CREATOR, |  | ||||||
|                         Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? DbUtils.SQLITE_FTS3 |  | ||||||
|                                 : DbUtils.SQLITE_FTS4)); |  | ||||||
|     }// onCreate() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { |  | ||||||
|         // TODO |  | ||||||
|     }// onUpgrade() |  | ||||||
| } |  | ||||||
| @@ -1,362 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    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.providers.bookmark; |  | ||||||
|  |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.DbUtils; |  | ||||||
|  |  | ||||||
| import java.util.Arrays; |  | ||||||
| import java.util.Date; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Map; |  | ||||||
|  |  | ||||||
| import android.content.ContentProvider; |  | ||||||
| import android.content.ContentUris; |  | ||||||
| import android.content.ContentValues; |  | ||||||
| import android.content.UriMatcher; |  | ||||||
| import android.database.Cursor; |  | ||||||
| import android.database.SQLException; |  | ||||||
| import android.database.sqlite.SQLiteDatabase; |  | ||||||
| import android.database.sqlite.SQLiteQueryBuilder; |  | ||||||
| import android.net.Uri; |  | ||||||
| import android.text.TextUtils; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Bookmark provider. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public class BookmarkProvider extends ContentProvider { |  | ||||||
|  |  | ||||||
|     @SuppressWarnings("unused") |  | ||||||
|     private static final String CLASSNAME = BookmarkProvider.class.getName(); |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * Constants used by the Uri matcher to choose an action based on the |  | ||||||
|      * pattern of the incoming URI. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The incoming URI matches the Bookmark URI pattern. |  | ||||||
|      */ |  | ||||||
|     private static final int URI_BOOKMARKS = 1; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The incoming URI matches the Bookmark ID URI pattern. |  | ||||||
|      */ |  | ||||||
|     private static final int URI_BOOKMARK_ID = 2; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * A {@link UriMatcher} instance. |  | ||||||
|      */ |  | ||||||
|     private static final UriMatcher URI_MATCHER = new UriMatcher( |  | ||||||
|             UriMatcher.NO_MATCH); |  | ||||||
|  |  | ||||||
|     private static final Map<String, String> MAP_COLUMNS = new HashMap<String, String>(); |  | ||||||
|  |  | ||||||
|     static { |  | ||||||
|         MAP_COLUMNS.put(DbUtils.SQLITE_FTS_COLUMN_ROW_ID, |  | ||||||
|                 DbUtils.SQLITE_FTS_COLUMN_ROW_ID + " AS " |  | ||||||
|                         + BookmarkContract._ID); |  | ||||||
|         MAP_COLUMNS.put(BookmarkContract.COLUMN_NAME, |  | ||||||
|                 BookmarkContract.COLUMN_NAME); |  | ||||||
|         MAP_COLUMNS.put(BookmarkContract.COLUMN_PROVIDER_ID, |  | ||||||
|                 BookmarkContract.COLUMN_PROVIDER_ID); |  | ||||||
|         MAP_COLUMNS.put(BookmarkContract.COLUMN_URI, |  | ||||||
|                 BookmarkContract.COLUMN_URI); |  | ||||||
|         MAP_COLUMNS.put(BookmarkContract.COLUMN_CREATE_TIME, |  | ||||||
|                 BookmarkContract.COLUMN_CREATE_TIME); |  | ||||||
|         MAP_COLUMNS.put(BookmarkContract.COLUMN_MODIFICATION_TIME, |  | ||||||
|                 BookmarkContract.COLUMN_MODIFICATION_TIME); |  | ||||||
|     }// static |  | ||||||
|  |  | ||||||
|     private BookmarkHelper mBookmarkHelper; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public boolean onCreate() { |  | ||||||
|         mBookmarkHelper = new BookmarkHelper(getContext()); |  | ||||||
|  |  | ||||||
|         URI_MATCHER.addURI(BookmarkContract.getAuthority(getContext()), |  | ||||||
|                 BookmarkContract.PATH_BOOKMARKS, URI_BOOKMARKS); |  | ||||||
|         URI_MATCHER.addURI(BookmarkContract.getAuthority(getContext()), |  | ||||||
|                 BookmarkContract.PATH_BOOKMARKS + "/#", URI_BOOKMARK_ID); |  | ||||||
|  |  | ||||||
|         return true; |  | ||||||
|     }// onCreate() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public String getType(Uri uri) { |  | ||||||
|         /* |  | ||||||
|          * Chooses the MIME type based on the incoming URI pattern. |  | ||||||
|          */ |  | ||||||
|         switch (URI_MATCHER.match(uri)) { |  | ||||||
|         case URI_BOOKMARKS: |  | ||||||
|             return BookmarkContract.CONTENT_TYPE; |  | ||||||
|  |  | ||||||
|         case URI_BOOKMARK_ID: |  | ||||||
|             return BookmarkContract.CONTENT_ITEM_TYPE; |  | ||||||
|  |  | ||||||
|         default: |  | ||||||
|             throw new IllegalArgumentException("UNKNOWN URI " + uri); |  | ||||||
|         } |  | ||||||
|     }// getType() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public synchronized int delete(Uri uri, String selection, |  | ||||||
|             String[] selectionArgs) { |  | ||||||
|         // Opens the database object in "write" mode. |  | ||||||
|         SQLiteDatabase db = mBookmarkHelper.getWritableDatabase(); |  | ||||||
|         String finalWhere; |  | ||||||
|  |  | ||||||
|         int count; |  | ||||||
|  |  | ||||||
|         // Does the delete based on the incoming URI pattern. |  | ||||||
|         switch (URI_MATCHER.match(uri)) { |  | ||||||
|         /* |  | ||||||
|          * If the incoming pattern matches the general pattern for Bookmark |  | ||||||
|          * items, does a delete based on the incoming "where" columns and |  | ||||||
|          * arguments. |  | ||||||
|          */ |  | ||||||
|         case URI_BOOKMARKS: { |  | ||||||
|             count = db.delete(BookmarkContract.TABLE_NAME, selection, |  | ||||||
|                     selectionArgs); |  | ||||||
|             break; |  | ||||||
|         }// URI_BOOKMARKS |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If the incoming URI matches a single note ID, does the delete based |  | ||||||
|          * on the incoming data, but modifies the where clause to restrict it to |  | ||||||
|          * the particular Bookmark item ID. |  | ||||||
|          */ |  | ||||||
|         case URI_BOOKMARK_ID: { |  | ||||||
|             /* |  | ||||||
|              * Starts a final WHERE clause by restricting it to the desired |  | ||||||
|              * Bookmark item ID. |  | ||||||
|              */ |  | ||||||
|             finalWhere = DbUtils.SQLITE_FTS_COLUMN_ROW_ID + " = " |  | ||||||
|                     + uri.getLastPathSegment(); |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * If there were additional selection criteria, append them to the |  | ||||||
|              * final WHERE clause |  | ||||||
|              */ |  | ||||||
|             if (selection != null) |  | ||||||
|                 finalWhere = finalWhere + " AND " + selection; |  | ||||||
|  |  | ||||||
|             // Performs the delete. |  | ||||||
|             count = db.delete(BookmarkContract.TABLE_NAME, finalWhere, |  | ||||||
|                     selectionArgs); |  | ||||||
|             break; |  | ||||||
|         }// URI_BOOKMARK_ID |  | ||||||
|  |  | ||||||
|         // If the incoming pattern is invalid, throws an exception. |  | ||||||
|         default: |  | ||||||
|             throw new IllegalArgumentException("UNKNOWN URI " + uri); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Gets a handle to the content resolver object for the current context, |  | ||||||
|          * and notifies it that the incoming URI changed. The object passes this |  | ||||||
|          * along to the resolver framework, and observers that have registered |  | ||||||
|          * themselves for the provider are notified. |  | ||||||
|          */ |  | ||||||
|         getContext().getContentResolver().notifyChange(uri, null); |  | ||||||
|  |  | ||||||
|         // Returns the number of rows deleted. |  | ||||||
|         return count; |  | ||||||
|     }// delete() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public synchronized Uri insert(Uri uri, ContentValues values) { |  | ||||||
|         /* |  | ||||||
|          * Validates the incoming URI. Only the full provider URI is allowed for |  | ||||||
|          * inserts. |  | ||||||
|          */ |  | ||||||
|         if (URI_MATCHER.match(uri) != URI_BOOKMARKS) |  | ||||||
|             throw new IllegalArgumentException("UNKNOWN URI " + uri); |  | ||||||
|  |  | ||||||
|         // Gets the current time in milliseconds |  | ||||||
|         long now = new Date().getTime(); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If the values map doesn't contain the creation date/ modification |  | ||||||
|          * date, sets the value to the current time. |  | ||||||
|          */ |  | ||||||
|         for (String col : new String[] { BookmarkContract.COLUMN_CREATE_TIME, |  | ||||||
|                 BookmarkContract.COLUMN_MODIFICATION_TIME }) |  | ||||||
|             if (!values.containsKey(col)) |  | ||||||
|                 values.put(col, DbUtils.formatNumber(now)); |  | ||||||
|  |  | ||||||
|         // Opens the database object in "write" mode. |  | ||||||
|         SQLiteDatabase db = mBookmarkHelper.getWritableDatabase(); |  | ||||||
|  |  | ||||||
|         // Performs the insert and returns the ID of the new note. |  | ||||||
|         long rowId = db.insert(BookmarkContract.TABLE_NAME, null, values); |  | ||||||
|  |  | ||||||
|         // If the insert succeeded, the row ID exists. |  | ||||||
|         if (rowId > 0) { |  | ||||||
|             /* |  | ||||||
|              * Creates a URI with the note ID pattern and the new row ID |  | ||||||
|              * appended to it. |  | ||||||
|              */ |  | ||||||
|             Uri noteUri = ContentUris.withAppendedId( |  | ||||||
|                     BookmarkContract.genContentIdUriBase(getContext()), rowId); |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * Notifies observers registered against this provider that the data |  | ||||||
|              * changed. |  | ||||||
|              */ |  | ||||||
|             getContext().getContentResolver().notifyChange(noteUri, null); |  | ||||||
|             return noteUri; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If the insert didn't succeed, then the rowID is <= 0. Throws an |  | ||||||
|          * exception. |  | ||||||
|          */ |  | ||||||
|         throw new SQLException("Failed to insert row into " + uri); |  | ||||||
|     }// insert() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public synchronized Cursor query(Uri uri, String[] projection, |  | ||||||
|             String selection, String[] selectionArgs, String sortOrder) { |  | ||||||
|         SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); |  | ||||||
|         qb.setTables(BookmarkContract.TABLE_NAME); |  | ||||||
|         qb.setProjectionMap(MAP_COLUMNS); |  | ||||||
|  |  | ||||||
|         SQLiteDatabase db = null; |  | ||||||
|         Cursor cursor = null; |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Choose the projection and adjust the "where" clause based on URI |  | ||||||
|          * pattern-matching. |  | ||||||
|          */ |  | ||||||
|         switch (URI_MATCHER.match(uri)) { |  | ||||||
|         case URI_BOOKMARKS: { |  | ||||||
|             if (Arrays.equals(projection, |  | ||||||
|                     new String[] { BookmarkContract._COUNT })) { |  | ||||||
|                 db = mBookmarkHelper.getReadableDatabase(); |  | ||||||
|                 cursor = db.rawQuery( |  | ||||||
|                         String.format( |  | ||||||
|                                 "SELECT COUNT(*) AS %s FROM %s %s", |  | ||||||
|                                 BookmarkContract._COUNT, |  | ||||||
|                                 BookmarkContract.TABLE_NAME, |  | ||||||
|                                 selection != null ? String.format("WHERE %s", |  | ||||||
|                                         selection) : "").trim(), null); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             break; |  | ||||||
|         }// URI_BOOKMARKS |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If the incoming URI is for a single Bookmark item identified by its |  | ||||||
|          * ID, chooses the Bookmark item ID projection, and appends |  | ||||||
|          * "_ID = <history-item-ID>" to the where clause, so that it selects |  | ||||||
|          * that single Bookmark item. |  | ||||||
|          */ |  | ||||||
|         case URI_BOOKMARK_ID: { |  | ||||||
|             qb.appendWhere(DbUtils.SQLITE_FTS_COLUMN_ROW_ID + " = " |  | ||||||
|                     + uri.getLastPathSegment()); |  | ||||||
|             break; |  | ||||||
|         }// URI_BOOKMARK_ID |  | ||||||
|  |  | ||||||
|         default: |  | ||||||
|             throw new IllegalArgumentException("UNKNOWN URI " + uri); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (TextUtils.isEmpty(sortOrder)) |  | ||||||
|             sortOrder = BookmarkContract.DEFAULT_SORT_ORDER; |  | ||||||
|  |  | ||||||
|         if (db == null) { |  | ||||||
|             /* |  | ||||||
|              * Opens the database object in "read" mode, since no writes need to |  | ||||||
|              * be done. |  | ||||||
|              */ |  | ||||||
|             db = mBookmarkHelper.getReadableDatabase(); |  | ||||||
|             /* |  | ||||||
|              * Performs the query. If no problems occur trying to read the |  | ||||||
|              * database, then a Cursor object is returned; otherwise, the cursor |  | ||||||
|              * variable contains null. If no records were selected, then the |  | ||||||
|              * Cursor object is empty, and Cursor.getCount() returns 0. |  | ||||||
|              */ |  | ||||||
|             cursor = qb.query(db, projection, selection, selectionArgs, null, |  | ||||||
|                     null, sortOrder); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Tells the Cursor what URI to watch, so it knows when its source data |  | ||||||
|          * changes. |  | ||||||
|          */ |  | ||||||
|         cursor.setNotificationUri(getContext().getContentResolver(), uri); |  | ||||||
|         return cursor; |  | ||||||
|     }// query() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public synchronized int update(Uri uri, ContentValues values, |  | ||||||
|             String selection, String[] selectionArgs) { |  | ||||||
|         // Opens the database object in "write" mode. |  | ||||||
|         SQLiteDatabase db = mBookmarkHelper.getWritableDatabase(); |  | ||||||
|         int count; |  | ||||||
|         String finalWhere; |  | ||||||
|  |  | ||||||
|         // Does the update based on the incoming URI pattern |  | ||||||
|         switch (URI_MATCHER.match(uri)) { |  | ||||||
|         /* |  | ||||||
|          * If the incoming URI matches the general Bookmark items pattern, does |  | ||||||
|          * the update based on the incoming data. |  | ||||||
|          */ |  | ||||||
|         case URI_BOOKMARKS: { |  | ||||||
|             // Does the update and returns the number of rows updated. |  | ||||||
|             count = db.update(BookmarkContract.TABLE_NAME, values, selection, |  | ||||||
|                     selectionArgs); |  | ||||||
|             break; |  | ||||||
|         }// URI_BOOKMARKS |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If the incoming URI matches a single Bookmark item ID, does the |  | ||||||
|          * update based on the incoming data, but modifies the where clause to |  | ||||||
|          * restrict it to the particular history item ID. |  | ||||||
|          */ |  | ||||||
|         case URI_BOOKMARK_ID: { |  | ||||||
|             /* |  | ||||||
|              * Starts creating the final WHERE clause by restricting it to the |  | ||||||
|              * incoming item ID. |  | ||||||
|              */ |  | ||||||
|             finalWhere = DbUtils.SQLITE_FTS_COLUMN_ROW_ID + " = " |  | ||||||
|                     + uri.getLastPathSegment(); |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * If there were additional selection criteria, append them to the |  | ||||||
|              * final WHERE clause |  | ||||||
|              */ |  | ||||||
|             if (selection != null) |  | ||||||
|                 finalWhere = finalWhere + " AND " + selection; |  | ||||||
|  |  | ||||||
|             // Does the update and returns the number of rows updated. |  | ||||||
|             count = db.update(BookmarkContract.TABLE_NAME, values, finalWhere, |  | ||||||
|                     selectionArgs); |  | ||||||
|             break; |  | ||||||
|         }// URI_BOOKMARK_ID |  | ||||||
|  |  | ||||||
|         // If the incoming pattern is invalid, throws an exception. |  | ||||||
|         default: |  | ||||||
|             throw new IllegalArgumentException("UNKNOWN URI " + uri); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Gets a handle to the content resolver object for the current context, |  | ||||||
|          * and notifies it that the incoming URI changed. The object passes this |  | ||||||
|          * along to the resolver framework, and observers that have registered |  | ||||||
|          * themselves for the provider are notified. |  | ||||||
|          */ |  | ||||||
|         getContext().getContentResolver().notifyChange(uri, null); |  | ||||||
|  |  | ||||||
|         // Returns the number of rows updated. |  | ||||||
|         return count; |  | ||||||
|     }// update() |  | ||||||
| } |  | ||||||
| @@ -1,569 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    Copyright (c) 2012 Hai Bison |  | ||||||
|  * |  | ||||||
|  *    See the file LICENSE at the root directory of this project for copying |  | ||||||
|  *    permission. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package group.pals.android.lib.ui.filechooser.utils.ui.bookmark; |  | ||||||
|  |  | ||||||
| import group.pals.android.lib.ui.filechooser.BuildConfig; |  | ||||||
| import group.pals.android.lib.ui.filechooser.R; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.bookmark.BookmarkContract; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Ui; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import android.content.Context; |  | ||||||
| import android.database.Cursor; |  | ||||||
| import android.database.MatrixCursor; |  | ||||||
| import android.net.Uri; |  | ||||||
| import android.util.Log; |  | ||||||
| import android.util.SparseArray; |  | ||||||
| import android.view.View; |  | ||||||
| import android.widget.CheckBox; |  | ||||||
| import android.widget.CompoundButton; |  | ||||||
| import android.widget.ResourceCursorTreeAdapter; |  | ||||||
| import android.widget.TextView; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Bookmark cursor adapter. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public class BookmarkCursorAdapter extends ResourceCursorTreeAdapter { |  | ||||||
|  |  | ||||||
|     private static final String CLASSNAME = BookmarkCursorAdapter.class |  | ||||||
|             .getName(); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Advanced selection options: All, None, Invert. |  | ||||||
|      */ |  | ||||||
|     public static final Integer[] ADVANCED_SELECTION_OPTIONS = new Integer[] { |  | ||||||
|             R.string.afc_cmd_advanced_selection_all, |  | ||||||
|             R.string.afc_cmd_advanced_selection_none, |  | ||||||
|             R.string.afc_cmd_advanced_selection_invert }; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The "view holder". |  | ||||||
|      *  |  | ||||||
|      * @author Hai Bison |  | ||||||
|      */ |  | ||||||
|     private static class BagGroup { |  | ||||||
|  |  | ||||||
|         TextView mTextHeader; |  | ||||||
|     }// BagGroup |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * The "view holder". |  | ||||||
|      *  |  | ||||||
|      * @author Hai Bison |  | ||||||
|      */ |  | ||||||
|     private static class BagChild { |  | ||||||
|  |  | ||||||
|         TextView mTextName; |  | ||||||
|         TextView mTextPath; |  | ||||||
|         CheckBox mCheckBox; |  | ||||||
|     }// BagChild |  | ||||||
|  |  | ||||||
|     private static class BagChildInfo { |  | ||||||
|  |  | ||||||
|         boolean mChecked = false; |  | ||||||
|         boolean mMarkedAsDeleted = false; |  | ||||||
|     }// BagChildInfo |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * This column holds the original position of group cursor in original |  | ||||||
|      * cursor. |  | ||||||
|      * <p/> |  | ||||||
|      * Type: {@code Integer} |  | ||||||
|      */ |  | ||||||
|     private static final String COLUMN_ORG_GROUP_POSITION = "org_group_position"; |  | ||||||
|  |  | ||||||
|     private static final String[] GROUP_CURSOR_COLUMNS = { |  | ||||||
|             BookmarkContract._ID, BookmarkContract.COLUMN_PROVIDER_ID, |  | ||||||
|             COLUMN_ORG_GROUP_POSITION }; |  | ||||||
|  |  | ||||||
|     private static final String[] CHILD_CURSOR_COLUMNS = { |  | ||||||
|             BookmarkContract._ID, BookmarkContract.COLUMN_NAME, |  | ||||||
|             BookmarkContract.COLUMN_URI, BookmarkContract.COLUMN_PROVIDER_ID, |  | ||||||
|             BookmarkContract.COLUMN_MODIFICATION_TIME }; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Map of child IDs to {@link BagChildInfo}. |  | ||||||
|      */ |  | ||||||
|     private final SparseArray<BagChildInfo> mSelectedChildrenMap = new SparseArray<BagChildInfo>(); |  | ||||||
|     private boolean mEditor; |  | ||||||
|  |  | ||||||
|     private Cursor mOrgCursor; |  | ||||||
|     private MatrixCursor mGroupCursor; |  | ||||||
|     private SparseArray<MatrixCursor> mChildrenCursor; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Creates new instance. |  | ||||||
|      *  |  | ||||||
|      * @param context |  | ||||||
|      *            {@link Context}. |  | ||||||
|      */ |  | ||||||
|     public BookmarkCursorAdapter(Context context) { |  | ||||||
|         super(context, null, R.layout.afc_view_bookmark_item, |  | ||||||
|                 R.layout.afc_view_bookmark_sub_item); |  | ||||||
|     }// BookmarkCursorAdapter() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Changes new cursor. |  | ||||||
|      * <p/> |  | ||||||
|      * You have to query the items in descending order of modification time. |  | ||||||
|      *  |  | ||||||
|      * @param cursor |  | ||||||
|      *            the cursor. |  | ||||||
|      * @param notificationUri |  | ||||||
|      *            the notification URI. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public synchronized void changeCursor(Cursor cursor) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "changeCursor()"); |  | ||||||
|  |  | ||||||
|         if (mOrgCursor != null) |  | ||||||
|             mOrgCursor.close(); |  | ||||||
|         mOrgCursor = cursor; |  | ||||||
|  |  | ||||||
|         MatrixCursor newGroupCursor = cursor != null ? new MatrixCursor( |  | ||||||
|                 GROUP_CURSOR_COLUMNS) : null; |  | ||||||
|         SparseArray<MatrixCursor> newChildrenCursor = cursor != null ? new SparseArray<MatrixCursor>() |  | ||||||
|                 : null; |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Build new group cursor. |  | ||||||
|          */ |  | ||||||
|         if (cursor != null && cursor.moveToFirst()) { |  | ||||||
|             String lastProviderId = null; |  | ||||||
|             do { |  | ||||||
|                 String providerId = cursor.getString(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)); |  | ||||||
|  |  | ||||||
|                 if (!providerId.equals(lastProviderId)) { |  | ||||||
|                     newGroupCursor |  | ||||||
|                             .addRow(new Object[] { |  | ||||||
|                                     cursor.getInt(cursor |  | ||||||
|                                             .getColumnIndex(BookmarkContract._ID)), |  | ||||||
|                                     cursor.getString(cursor |  | ||||||
|                                             .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)), |  | ||||||
|                                     cursor.getPosition() }); |  | ||||||
|                 } |  | ||||||
|                 lastProviderId = providerId; |  | ||||||
|             } while (cursor.moveToNext()); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Clean up children cursor. |  | ||||||
|          */ |  | ||||||
|         if (mChildrenCursor != null) { |  | ||||||
|             for (int i = 0; i < mChildrenCursor.size(); i++) |  | ||||||
|                 mChildrenCursor.valueAt(i).close(); |  | ||||||
|             mChildrenCursor.clear(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Apply new changes... Note that we don't need to close the old group |  | ||||||
|          * cursor. The call to `super.changeCursor()` will do that. |  | ||||||
|          */ |  | ||||||
|         mGroupCursor = newGroupCursor; |  | ||||||
|         mChildrenCursor = newChildrenCursor; |  | ||||||
|         super.changeCursor(mGroupCursor); |  | ||||||
|     }// changeCursor() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected Cursor getChildrenCursor(Cursor groupCursor) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "getChildrenCursor()"); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Try to find the child cursor in the map. If found then it'd be great |  | ||||||
|          * :-) |  | ||||||
|          */ |  | ||||||
|         int orgGroupPosition = groupCursor.getInt(groupCursor |  | ||||||
|                 .getColumnIndex(COLUMN_ORG_GROUP_POSITION)); |  | ||||||
|         int idx = mChildrenCursor.indexOfKey(orgGroupPosition); |  | ||||||
|         if (idx >= 0) |  | ||||||
|             return mChildrenCursor.valueAt(idx); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If not found, create new cursor. |  | ||||||
|          */ |  | ||||||
|         MatrixCursor childrenCursor = new MatrixCursor(CHILD_CURSOR_COLUMNS); |  | ||||||
|  |  | ||||||
|         mOrgCursor.moveToPosition(orgGroupPosition); |  | ||||||
|         String providerId = groupCursor.getString(groupCursor |  | ||||||
|                 .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)); |  | ||||||
|         do { |  | ||||||
|             childrenCursor |  | ||||||
|                     .addRow(new Object[] { |  | ||||||
|                             mOrgCursor.getInt(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BookmarkContract._ID)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BookmarkContract.COLUMN_NAME)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BookmarkContract.COLUMN_URI)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BookmarkContract.COLUMN_MODIFICATION_TIME)) }); |  | ||||||
|         } while (mOrgCursor.moveToNext() |  | ||||||
|                 && mOrgCursor |  | ||||||
|                         .getString( |  | ||||||
|                                 mOrgCursor |  | ||||||
|                                         .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)) |  | ||||||
|                         .equals(providerId)); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Put it to the map. |  | ||||||
|          */ |  | ||||||
|         mChildrenCursor.put(orgGroupPosition, childrenCursor); |  | ||||||
|         return childrenCursor; |  | ||||||
|     }// getChildrenCursor() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected void bindChildView(View view, Context context, Cursor cursor, |  | ||||||
|             boolean isLastChild) { |  | ||||||
|         final int id = cursor.getInt(cursor |  | ||||||
|                 .getColumnIndex(BookmarkContract._ID)); |  | ||||||
|         Uri uri = Uri.parse(cursor.getString(cursor |  | ||||||
|                 .getColumnIndex(BookmarkContract.COLUMN_URI))); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Child Info |  | ||||||
|          */ |  | ||||||
|         final BagChildInfo childInfo; |  | ||||||
|         if (mSelectedChildrenMap.get(id) == null) { |  | ||||||
|             childInfo = new BagChildInfo(); |  | ||||||
|             mSelectedChildrenMap.put(id, childInfo); |  | ||||||
|         } else |  | ||||||
|             childInfo = mSelectedChildrenMap.get(id); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Child |  | ||||||
|          */ |  | ||||||
|         BagChild bag = (BagChild) view.getTag(); |  | ||||||
|  |  | ||||||
|         if (bag == null) { |  | ||||||
|             bag = new BagChild(); |  | ||||||
|             bag.mTextName = (TextView) view.findViewById(R.id.afc_text_name); |  | ||||||
|             bag.mTextPath = (TextView) view.findViewById(R.id.afc_text_path); |  | ||||||
|             bag.mCheckBox = (CheckBox) view.findViewById(R.id.afc_checkbox); |  | ||||||
|  |  | ||||||
|             view.setTag(bag); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Name. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         bag.mTextName.setText(cursor.getString(cursor |  | ||||||
|                 .getColumnIndex(BookmarkContract.COLUMN_NAME))); |  | ||||||
|         Ui.strikeOutText(bag.mTextName, childInfo.mMarkedAsDeleted); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Path. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         if (isEditor()) { |  | ||||||
|             bag.mTextPath.setVisibility(View.VISIBLE); |  | ||||||
|             bag.mTextPath.setText(BaseFileProviderUtils |  | ||||||
|                     .getRealUri(context, uri).toString()); |  | ||||||
|         } else |  | ||||||
|             bag.mTextPath.setVisibility(View.GONE); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Checkbox. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         bag.mCheckBox.setVisibility(isEditor() ? View.VISIBLE : View.GONE); |  | ||||||
|         bag.mCheckBox.setOnCheckedChangeListener(null); |  | ||||||
|         bag.mCheckBox.setChecked(childInfo.mChecked); |  | ||||||
|         bag.mCheckBox |  | ||||||
|                 .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public void onCheckedChanged(CompoundButton buttonView, |  | ||||||
|                             boolean isChecked) { |  | ||||||
|                         childInfo.mChecked = isChecked; |  | ||||||
|                     }// onCheckedChanged() |  | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|         bag.mCheckBox.setOnLongClickListener(new View.OnLongClickListener() { |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public boolean onLongClick(View v) { |  | ||||||
|                 ContextMenuUtils.showContextMenu(v.getContext(), 0, |  | ||||||
|                         R.string.afc_title_advanced_selection, |  | ||||||
|                         ADVANCED_SELECTION_OPTIONS, |  | ||||||
|                         new ContextMenuUtils.OnMenuItemClickListener() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void onClick(final int resId) { |  | ||||||
|                                 if (resId == R.string.afc_cmd_advanced_selection_all) |  | ||||||
|                                     selectAll(true); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_none) |  | ||||||
|                                     selectAll(false); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_invert) |  | ||||||
|                                     invertSelection(); |  | ||||||
|                             }// onClick() |  | ||||||
|                         }); |  | ||||||
|                 return true; |  | ||||||
|             }// onLongClick() |  | ||||||
|         }); |  | ||||||
|     }// bindChildView() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected void bindGroupView(View view, Context context, |  | ||||||
|             final Cursor cursor, boolean isExpanded) { |  | ||||||
|         BagGroup b; |  | ||||||
|         if (view.getTag() == null) { |  | ||||||
|             b = new BagGroup(); |  | ||||||
|             b.mTextHeader = (TextView) view |  | ||||||
|                     .findViewById(R.id.afc_textview_header); |  | ||||||
|  |  | ||||||
|             view.setTag(b); |  | ||||||
|         } else |  | ||||||
|             b = (BagGroup) view.getTag(); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Provider name. |  | ||||||
|          */ |  | ||||||
|         String providerId = cursor.getString(cursor |  | ||||||
|                 .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)); |  | ||||||
|         b.mTextHeader.setText(BaseFileProviderUtils.getProviderName(context, |  | ||||||
|                 providerId)); |  | ||||||
|         /* |  | ||||||
|          * Provider badge icon. |  | ||||||
|          */ |  | ||||||
|         b.mTextHeader.setCompoundDrawablesWithIntrinsicBounds( |  | ||||||
|                 BaseFileProviderUtils.getProviderIconId(context, providerId), |  | ||||||
|                 0, 0, 0); |  | ||||||
|     }// bindGroupView() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void notifyDataSetChanged(boolean releaseCursors) { |  | ||||||
|         super.notifyDataSetChanged(releaseCursors); |  | ||||||
|         if (releaseCursors) |  | ||||||
|             synchronized (mSelectedChildrenMap) { |  | ||||||
|                 mSelectedChildrenMap.clear(); |  | ||||||
|             } |  | ||||||
|     }// notifyDataSetChanged() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void notifyDataSetInvalidated() { |  | ||||||
|         super.notifyDataSetInvalidated(); |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             mSelectedChildrenMap.clear(); |  | ||||||
|         } |  | ||||||
|     }// notifyDataSetInvalidated() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * UTILITIES |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Checks if this is in editor mode. |  | ||||||
|      *  |  | ||||||
|      * @return {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public boolean isEditor() { |  | ||||||
|         return mEditor; |  | ||||||
|     }// isEditor() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Sets editor mode. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param v |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public void setEditor(boolean v) { |  | ||||||
|         if (mEditor != v) { |  | ||||||
|             mEditor = v; |  | ||||||
|             notifyDataSetChanged(false); |  | ||||||
|         } |  | ||||||
|     }// setEditor() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Selects all items in a specified group. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This will <i>not</i> notify data set for changes after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      * @param selected |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     private void asyncSelectAll(int groupPosition, boolean selected) { |  | ||||||
|         int chidrenCount = getChildrenCount(groupPosition); |  | ||||||
|         for (int iChild = 0; iChild < chidrenCount; iChild++) { |  | ||||||
|             Cursor cursor = getChild(groupPosition, iChild); |  | ||||||
|             final int id = cursor.getInt(cursor |  | ||||||
|                     .getColumnIndex(BookmarkContract._ID)); |  | ||||||
|             BagChildInfo b = mSelectedChildrenMap.get(id); |  | ||||||
|             if (b == null) { |  | ||||||
|                 b = new BagChildInfo(); |  | ||||||
|                 mSelectedChildrenMap.put(id, b); |  | ||||||
|             } |  | ||||||
|             b.mChecked = selected; |  | ||||||
|         }// for children |  | ||||||
|     }// asyncSelectAll() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Selects all items of a specified group. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      * @param selected |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public synchronized void selectAll(int groupPosition, boolean selected) { |  | ||||||
|         asyncSelectAll(groupPosition, selected); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// selectAll() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Selects all items. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param selected |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public synchronized void selectAll(boolean selected) { |  | ||||||
|         for (int iGroup = 0; iGroup < getGroupCount(); iGroup++) |  | ||||||
|             asyncSelectAll(iGroup, selected); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// selectAll() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Inverts selection. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This will <i>not</i> notify data set for changes after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      */ |  | ||||||
|     private void asyncInvertSelection(int groupPosition) { |  | ||||||
|         int chidrenCount = getChildrenCount(groupPosition); |  | ||||||
|         for (int iChild = 0; iChild < chidrenCount; iChild++) { |  | ||||||
|             Cursor cursor = getChild(groupPosition, iChild); |  | ||||||
|             final int id = cursor.getInt(cursor |  | ||||||
|                     .getColumnIndex(BookmarkContract._ID)); |  | ||||||
|             BagChildInfo b = mSelectedChildrenMap.get(id); |  | ||||||
|             if (b == null) { |  | ||||||
|                 b = new BagChildInfo(); |  | ||||||
|                 mSelectedChildrenMap.put(id, b); |  | ||||||
|             } |  | ||||||
|             b.mChecked = !b.mChecked; |  | ||||||
|         }// for children |  | ||||||
|     }// asyncInvertSelection() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Inverts selection of all items of a specified group. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      */ |  | ||||||
|     public synchronized void invertSelection(int groupPosition) { |  | ||||||
|         asyncInvertSelection(groupPosition); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// invertSelection() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Inverts selection of all items. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      */ |  | ||||||
|     public synchronized void invertSelection() { |  | ||||||
|         for (int iGroup = 0; iGroup < getGroupCount(); iGroup++) |  | ||||||
|             asyncInvertSelection(iGroup); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// invertSelection() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Checks if item with {@code id} (the database ID) is selected or not. |  | ||||||
|      *  |  | ||||||
|      * @param id |  | ||||||
|      *            the database ID. |  | ||||||
|      * @return {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public boolean isSelected(int id) { |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             return mSelectedChildrenMap.get(id) != null ? mSelectedChildrenMap |  | ||||||
|                     .get(id).mChecked : false; |  | ||||||
|         } |  | ||||||
|     }// isSelected() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets IDs of selected items. |  | ||||||
|      *  |  | ||||||
|      * @return list of IDs, can be empty. |  | ||||||
|      */ |  | ||||||
|     public List<Integer> getSelectedItemIds() { |  | ||||||
|         List<Integer> res = new ArrayList<Integer>(); |  | ||||||
|  |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             for (int i = 0; i < mSelectedChildrenMap.size(); i++) |  | ||||||
|                 if (mSelectedChildrenMap.get(mSelectedChildrenMap.keyAt(i)).mChecked) |  | ||||||
|                     res.add(mSelectedChildrenMap.keyAt(i)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return res; |  | ||||||
|     }// getSelectedItemIds() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Marks all selected items as deleted. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged()} after done. |  | ||||||
|      *  |  | ||||||
|      * @param deleted |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public void markSelectedItemsAsDeleted(boolean deleted) { |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             for (int i = 0; i < mSelectedChildrenMap.size(); i++) |  | ||||||
|                 if (mSelectedChildrenMap.get(mSelectedChildrenMap.keyAt(i)).mChecked) |  | ||||||
|                     mSelectedChildrenMap.get(mSelectedChildrenMap.keyAt(i)).mMarkedAsDeleted = deleted; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// markSelectedItemsAsDeleted() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Marks specified item as deleted. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged()} after done. |  | ||||||
|      *  |  | ||||||
|      * @param id |  | ||||||
|      *            the database ID of the item. |  | ||||||
|      * @param deleted |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public void markItemAsDeleted(int id, boolean deleted) { |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             if (mSelectedChildrenMap.get(id) != null) { |  | ||||||
|                 mSelectedChildrenMap.get(id).mMarkedAsDeleted = deleted; |  | ||||||
|                 notifyDataSetChanged(false); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }// markItemAsDeleted() |  | ||||||
| } |  | ||||||
| @@ -1,804 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    Copyright (c) 2012 Hai Bison |  | ||||||
|  * |  | ||||||
|  *    See the file LICENSE at the root directory of this project for copying |  | ||||||
|  *    permission. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package group.pals.android.lib.ui.filechooser.utils.ui.bookmark; |  | ||||||
|  |  | ||||||
| import group.pals.android.lib.ui.filechooser.BuildConfig; |  | ||||||
| import group.pals.android.lib.ui.filechooser.R; |  | ||||||
| import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.DbUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.bookmark.BookmarkContract; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.EnvUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.TextUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Dlg; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.GestureUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.GestureUtils.FlingDirection; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Ui; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.history.HistoryFragment; |  | ||||||
|  |  | ||||||
| import java.text.Collator; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collections; |  | ||||||
| import java.util.Comparator; |  | ||||||
| import java.util.Date; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import android.app.AlertDialog; |  | ||||||
| import android.app.Dialog; |  | ||||||
| import android.content.ContentResolver; |  | ||||||
| import android.content.ContentValues; |  | ||||||
| import android.content.Context; |  | ||||||
| import android.content.DialogInterface; |  | ||||||
| import android.database.Cursor; |  | ||||||
| import android.database.DatabaseUtils; |  | ||||||
| import android.net.Uri; |  | ||||||
| import android.os.Bundle; |  | ||||||
| import android.os.Handler; |  | ||||||
| import android.support.v4.app.DialogFragment; |  | ||||||
| import android.support.v4.app.LoaderManager; |  | ||||||
| import android.support.v4.content.CursorLoader; |  | ||||||
| import android.support.v4.content.Loader; |  | ||||||
| import android.text.Editable; |  | ||||||
| import android.text.TextWatcher; |  | ||||||
| import android.util.Log; |  | ||||||
| import android.util.SparseArray; |  | ||||||
| import android.view.KeyEvent; |  | ||||||
| import android.view.LayoutInflater; |  | ||||||
| import android.view.View; |  | ||||||
| import android.view.ViewGroup; |  | ||||||
| import android.view.Window; |  | ||||||
| import android.view.inputmethod.EditorInfo; |  | ||||||
| import android.widget.AdapterView; |  | ||||||
| import android.widget.Button; |  | ||||||
| import android.widget.EditText; |  | ||||||
| import android.widget.ExpandableListView; |  | ||||||
| import android.widget.TextView; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Fragment to manage bookmarks. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public class BookmarkFragment extends DialogFragment implements |  | ||||||
|         LoaderManager.LoaderCallbacks<Cursor> { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * As the name means. |  | ||||||
|      *  |  | ||||||
|      * @author Hai Bison |  | ||||||
|      * @since v5.1 beta |  | ||||||
|      */ |  | ||||||
|     public static interface OnBookmarkItemClickListener { |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * Will be called after the bookmark was clicked. |  | ||||||
|          *  |  | ||||||
|          * @param providerId |  | ||||||
|          *            the original provider ID. |  | ||||||
|          * @param uri |  | ||||||
|          *            the URI to a directory. |  | ||||||
|          */ |  | ||||||
|         void onItemClick(String providerId, Uri uri); |  | ||||||
|     }// OnBookmarkItemClickListener |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Used for debugging or something... |  | ||||||
|      */ |  | ||||||
|     private static final String CLASSNAME = BookmarkFragment.class.getName(); |  | ||||||
|  |  | ||||||
|     private static final String MODE_EDITOR = CLASSNAME + ".mode_editor"; |  | ||||||
|  |  | ||||||
|     private final int mLoaderBookmarkData = EnvUtils.genId(); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Creates a new instance of {@link HistoryFragment}. |  | ||||||
|      *  |  | ||||||
|      * @param editor |  | ||||||
|      *            {@code true} if you want to use this as an editor, and |  | ||||||
|      *            {@code false} as a viewer. |  | ||||||
|      * @return {@link BookmarkFragment}. |  | ||||||
|      */ |  | ||||||
|     public static BookmarkFragment newInstance(boolean editor) { |  | ||||||
|         Bundle args = new Bundle(); |  | ||||||
|         args.putBoolean(MODE_EDITOR, editor); |  | ||||||
|  |  | ||||||
|         BookmarkFragment res = new BookmarkFragment(); |  | ||||||
|         res.setArguments(args); |  | ||||||
|  |  | ||||||
|         return res; |  | ||||||
|     }// newInstance() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * Controls. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     private View mViewGroupControls; |  | ||||||
|     private ExpandableListView mListView; |  | ||||||
|     private ViewGroup mViewFooter; |  | ||||||
|     private Button mBtnClear; |  | ||||||
|     private Button mBtnOk; |  | ||||||
|     private View mViewLoading; |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * Fields. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     private final Handler mHandler = new Handler(); |  | ||||||
|     private boolean mEditor = false; |  | ||||||
|     private BookmarkCursorAdapter mBookmarkCursorAdapter; |  | ||||||
|     private OnBookmarkItemClickListener mOnBookmarkItemClickListener; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onCreate(Bundle savedInstanceState) { |  | ||||||
|         super.onCreate(savedInstanceState); |  | ||||||
|         mEditor = getArguments().getBoolean(MODE_EDITOR); |  | ||||||
|     }// onCreate() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Dialog onCreateDialog(Bundle savedInstanceState) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onCreateDialog()"); |  | ||||||
|  |  | ||||||
|         Dialog dialog = new Dialog(getActivity(), Ui.resolveAttribute( |  | ||||||
|                 getActivity(), R.attr.afc_theme_dialog)); |  | ||||||
|         dialog.setCanceledOnTouchOutside(true); |  | ||||||
|         dialog.requestWindowFeature(Window.FEATURE_LEFT_ICON); |  | ||||||
|         dialog.setTitle(R.string.afc_title_bookmark_manager); |  | ||||||
|         dialog.setContentView(initContentView(dialog.getLayoutInflater(), null)); |  | ||||||
|         dialog.setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, |  | ||||||
|                 R.drawable.afc_bookmarks_dark); |  | ||||||
|  |  | ||||||
|         return dialog; |  | ||||||
|     }// onCreateDialog() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, |  | ||||||
|             Bundle savedInstanceState) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onCreateView()"); |  | ||||||
|         if (getDialog() != null) { |  | ||||||
|             getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() { |  | ||||||
|  |  | ||||||
|                 @Override |  | ||||||
|                 public boolean onKey(DialogInterface dialog, int keyCode, |  | ||||||
|                         KeyEvent event) { |  | ||||||
|                     /* |  | ||||||
|                      * Don't let the Search key dismiss this dialog. |  | ||||||
|                      */ |  | ||||||
|                     return keyCode == KeyEvent.KEYCODE_SEARCH; |  | ||||||
|                 }// onKey() |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return initContentView(inflater, container); |  | ||||||
|     }// onCreateView() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onActivityCreated(Bundle savedInstanceState) { |  | ||||||
|         super.onActivityCreated(savedInstanceState); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Prepare the loader. Either re-connect with an existing one, or start |  | ||||||
|          * a new one. |  | ||||||
|          */ |  | ||||||
|         getLoaderManager().initLoader(mLoaderBookmarkData, null, this); |  | ||||||
|     }// onActivityCreated() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * LOADERMANAGER.LOADERCALLBACKS |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Loader<Cursor> onCreateLoader(int id, Bundle args) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onCreateLoader()"); |  | ||||||
|         if (id == mLoaderBookmarkData) { |  | ||||||
|             mHandler.removeCallbacksAndMessages(null); |  | ||||||
|             mHandler.postDelayed(mViewLoadingShower, |  | ||||||
|                     DisplayPrefs.DELAY_TIME_FOR_SIMPLE_ANIMATION); |  | ||||||
|  |  | ||||||
|             mBookmarkCursorAdapter.changeCursor(null); |  | ||||||
|  |  | ||||||
|             return new CursorLoader(getActivity(), |  | ||||||
|                     BookmarkContract.genContentUri(getActivity()), null, null, |  | ||||||
|                     null, String.format("%s, %s DESC", |  | ||||||
|                             BookmarkContract.COLUMN_PROVIDER_ID, |  | ||||||
|                             BookmarkContract.COLUMN_MODIFICATION_TIME)); |  | ||||||
|         }// mLoaderBookmarkData |  | ||||||
|  |  | ||||||
|         return null; |  | ||||||
|     }// onCreateLoader() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onLoadFinished(Loader<Cursor> loader, Cursor data) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onLoadFinished() -- data = " + data); |  | ||||||
|  |  | ||||||
|         if (loader.getId() == mLoaderBookmarkData) { |  | ||||||
|             mBookmarkCursorAdapter.changeCursor(data); |  | ||||||
|  |  | ||||||
|             for (int i = 0; i < mBookmarkCursorAdapter.getGroupCount(); i++) |  | ||||||
|                 mListView.expandGroup(i); |  | ||||||
|             updateUI(); |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * Views visibilities. Always call these to make sure all views are |  | ||||||
|              * in right visibilities. |  | ||||||
|              */ |  | ||||||
|             mHandler.removeCallbacksAndMessages(null); |  | ||||||
|             mViewLoading.setVisibility(View.GONE); |  | ||||||
|             mViewGroupControls.setVisibility(View.VISIBLE); |  | ||||||
|  |  | ||||||
|             mListView.post(new Runnable() { |  | ||||||
|  |  | ||||||
|                 @Override |  | ||||||
|                 public void run() { |  | ||||||
|                     mListView.setSelection(-1); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         }// mLoaderBookmarkData |  | ||||||
|     }// onLoadFinished() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onLoaderReset(Loader<Cursor> loader) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onLoaderReset()"); |  | ||||||
|  |  | ||||||
|         if (loader.getId() == mLoaderBookmarkData) { |  | ||||||
|             mBookmarkCursorAdapter.changeCursor(null); |  | ||||||
|             mViewLoading.setVisibility(View.VISIBLE); |  | ||||||
|         }// mLoaderBookmarkData |  | ||||||
|     }// onLoaderReset() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Loads content view from XML and init controls. |  | ||||||
|      */ |  | ||||||
|     private View initContentView(LayoutInflater inflater, ViewGroup container) { |  | ||||||
|         View mainView = inflater.inflate(R.layout.afc_viewgroup_bookmarks, |  | ||||||
|                 container, false); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Maps controls. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         mViewGroupControls = mainView.findViewById(R.id.afc_viewgroup_controls); |  | ||||||
|         mListView = (ExpandableListView) mainView |  | ||||||
|                 .findViewById(R.id.afc_listview_bookmarks); |  | ||||||
|         mViewFooter = (ViewGroup) mainView |  | ||||||
|                 .findViewById(R.id.afc_viewgroup_footer); |  | ||||||
|         mBtnClear = (Button) mainView.findViewById(R.id.afc_button_clear); |  | ||||||
|         mBtnOk = (Button) mainView.findViewById(R.id.afc_button_ok); |  | ||||||
|         mViewLoading = mainView.findViewById(R.id.afc_view_loading); |  | ||||||
|  |  | ||||||
|         if (mEditor) { |  | ||||||
|             mViewFooter.setVisibility(View.VISIBLE); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Listview. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         mListView.setEmptyView(mainView.findViewById(R.id.afc_empty_view)); |  | ||||||
|         mListView.setOnChildClickListener(mListViewOnChildClickListener); |  | ||||||
|         mListView.setOnItemLongClickListener(mListViewOnItemLongClickListener); |  | ||||||
|         initListViewGestureListener(); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Adapter. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         mBookmarkCursorAdapter = new BookmarkCursorAdapter(getActivity()); |  | ||||||
|         mBookmarkCursorAdapter.setEditor(mEditor); |  | ||||||
|         mListView.setAdapter(mBookmarkCursorAdapter); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Events. |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         mBtnClear.setOnClickListener(mBtnClearOnClickListener); |  | ||||||
|         mBtnOk.setOnClickListener(mBtnOkOnClickListener); |  | ||||||
|  |  | ||||||
|         return mainView; |  | ||||||
|     }// initContentView() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * As the name means. |  | ||||||
|      */ |  | ||||||
|     private void initListViewGestureListener() { |  | ||||||
|         GestureUtils.setupGestureDetector(mListView, |  | ||||||
|                 new GestureUtils.SimpleOnGestureListener() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public boolean onFling(View view, Object data, |  | ||||||
|                             FlingDirection flingDirection) { |  | ||||||
|                         if (!isEditor() || !(data instanceof Cursor)) |  | ||||||
|                             return false; |  | ||||||
|  |  | ||||||
|                         List<Integer> ids = new ArrayList<Integer>(); |  | ||||||
|  |  | ||||||
|                         final int bookmarkId = ((Cursor) data) |  | ||||||
|                                 .getInt(((Cursor) data) |  | ||||||
|                                         .getColumnIndex(BookmarkContract._ID)); |  | ||||||
|                         if (mBookmarkCursorAdapter.isSelected(bookmarkId)) |  | ||||||
|                             ids.addAll(mBookmarkCursorAdapter |  | ||||||
|                                     .getSelectedItemIds()); |  | ||||||
|                         else |  | ||||||
|                             ids.add(bookmarkId); |  | ||||||
|  |  | ||||||
|                         if (ids.size() <= 1) |  | ||||||
|                             mBookmarkCursorAdapter.markItemAsDeleted( |  | ||||||
|                                     bookmarkId, true); |  | ||||||
|                         else |  | ||||||
|                             mBookmarkCursorAdapter |  | ||||||
|                                     .markSelectedItemsAsDeleted(true); |  | ||||||
|  |  | ||||||
|                         final StringBuilder sb = new StringBuilder(String |  | ||||||
|                                 .format("%s in (", |  | ||||||
|                                         DbUtils.SQLITE_FTS_COLUMN_ROW_ID)); |  | ||||||
|                         for (int id : ids) |  | ||||||
|                             sb.append(Integer.toString(id)).append(','); |  | ||||||
|                         sb.setCharAt(sb.length() - 1, ')'); |  | ||||||
|  |  | ||||||
|                         new Handler().postDelayed(new Runnable() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void run() { |  | ||||||
|                                 getActivity().getContentResolver().delete( |  | ||||||
|                                         BookmarkContract |  | ||||||
|                                                 .genContentUri(getActivity()), |  | ||||||
|                                         sb.toString(), null); |  | ||||||
|                             }// run() |  | ||||||
|                         }, DisplayPrefs.DELAY_TIME_FOR_VERY_SHORT_ANIMATION); |  | ||||||
|  |  | ||||||
|                         return true; |  | ||||||
|                     }// onFling() |  | ||||||
|                 }); |  | ||||||
|     }// initListViewGestureListener() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Updates UI. |  | ||||||
|      */ |  | ||||||
|     private void updateUI() { |  | ||||||
|         mViewFooter.setVisibility(isEditor() ? View.VISIBLE : View.GONE); |  | ||||||
|         mBtnClear.setEnabled(mBookmarkCursorAdapter.getGroupCount() > 0); |  | ||||||
|     }// updateUI() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * UTILITIES |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Enables or disables editor mode. |  | ||||||
|      *  |  | ||||||
|      * @param editor |  | ||||||
|      *            {@code true} to enable, {@code false} to disable. |  | ||||||
|      */ |  | ||||||
|     public void setEditor(boolean editor) { |  | ||||||
|         if (mEditor != editor) { |  | ||||||
|             mEditor = editor; |  | ||||||
|             if (mBookmarkCursorAdapter != null) |  | ||||||
|                 mBookmarkCursorAdapter.setEditor(mEditor); |  | ||||||
|  |  | ||||||
|             updateUI(); |  | ||||||
|         } |  | ||||||
|     }// setEditor() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Checks if current mode is editor or not. |  | ||||||
|      *  |  | ||||||
|      * @return {@code true} if current mode is editor. |  | ||||||
|      */ |  | ||||||
|     public boolean isEditor() { |  | ||||||
|         return mEditor; |  | ||||||
|     }// isEditor() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Sets a listener to {@link OnBookmarkItemClickListener}. |  | ||||||
|      *  |  | ||||||
|      * @param listener |  | ||||||
|      *            the listener. |  | ||||||
|      */ |  | ||||||
|     public void setOnBookmarkItemClickListener( |  | ||||||
|             OnBookmarkItemClickListener listener) { |  | ||||||
|         mOnBookmarkItemClickListener = listener; |  | ||||||
|     }// setOnBookmarkItemClickListener() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets the listener of {@link OnBookmarkItemClickListener}. |  | ||||||
|      *  |  | ||||||
|      * @return the listener. |  | ||||||
|      */ |  | ||||||
|     public OnBookmarkItemClickListener getOnBookmarkItemClickListener() { |  | ||||||
|         return mOnBookmarkItemClickListener; |  | ||||||
|     }// getOnBookmarkItemClickListener() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * LISTENERS |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     private final Runnable mViewLoadingShower = new Runnable() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void run() { |  | ||||||
|             if (isAdded()) { |  | ||||||
|                 mViewGroupControls.setVisibility(View.GONE); |  | ||||||
|                 mViewLoading.setVisibility(View.VISIBLE); |  | ||||||
|             } |  | ||||||
|         }// run() |  | ||||||
|     };// mViewLoadingShower |  | ||||||
|  |  | ||||||
|     private final ExpandableListView.OnChildClickListener mListViewOnChildClickListener = new ExpandableListView.OnChildClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onChildClick(ExpandableListView parent, View v, |  | ||||||
|                 int groupPosition, int childPosition, long id) { |  | ||||||
|             if (getOnBookmarkItemClickListener() != null) { |  | ||||||
|                 Cursor cursor = mBookmarkCursorAdapter.getChild(groupPosition, |  | ||||||
|                         childPosition); |  | ||||||
|                 getOnBookmarkItemClickListener() |  | ||||||
|                         .onItemClick( |  | ||||||
|                                 cursor.getString(cursor |  | ||||||
|                                         .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)), |  | ||||||
|                                 Uri.parse(cursor.getString(cursor |  | ||||||
|                                         .getColumnIndex(BookmarkContract.COLUMN_URI)))); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (getDialog() != null) |  | ||||||
|                 dismiss(); |  | ||||||
|  |  | ||||||
|             return false; |  | ||||||
|         }// onChildClick() |  | ||||||
|     };// mListViewOnChildClickListener |  | ||||||
|  |  | ||||||
|     private final AdapterView.OnItemLongClickListener mListViewOnItemLongClickListener = new AdapterView.OnItemLongClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onItemLongClick(AdapterView<?> parent, View view, |  | ||||||
|                 int position, long id) { |  | ||||||
|             final int iGroup = ExpandableListView |  | ||||||
|                     .getPackedPositionGroup(mListView |  | ||||||
|                             .getExpandableListPosition(position)); |  | ||||||
|             final int iChild = ExpandableListView |  | ||||||
|                     .getPackedPositionChild(mListView |  | ||||||
|                             .getExpandableListPosition(position)); |  | ||||||
|  |  | ||||||
|             switch (ExpandableListView.getPackedPositionType(id)) { |  | ||||||
|             case ExpandableListView.PACKED_POSITION_TYPE_GROUP: |  | ||||||
|                 if (!isEditor()) |  | ||||||
|                     return false; |  | ||||||
|  |  | ||||||
|                 if (!mListView.isGroupExpanded(iGroup)) |  | ||||||
|                     return false; |  | ||||||
|  |  | ||||||
|                 if (BuildConfig.DEBUG) |  | ||||||
|                     Log.d(CLASSNAME, String.format( |  | ||||||
|                             "onItemLongClick() -- group = %,d", iGroup)); |  | ||||||
|                 ContextMenuUtils.showContextMenu(getActivity(), 0, |  | ||||||
|                         R.string.afc_title_advanced_selection, |  | ||||||
|                         BookmarkCursorAdapter.ADVANCED_SELECTION_OPTIONS, |  | ||||||
|                         new ContextMenuUtils.OnMenuItemClickListener() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void onClick(final int resId) { |  | ||||||
|                                 if (resId == R.string.afc_cmd_advanced_selection_all) |  | ||||||
|                                     mBookmarkCursorAdapter.selectAll(iGroup, |  | ||||||
|                                             true); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_none) |  | ||||||
|                                     mBookmarkCursorAdapter.selectAll(iGroup, |  | ||||||
|                                             false); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_invert) |  | ||||||
|                                     mBookmarkCursorAdapter |  | ||||||
|                                             .invertSelection(iGroup); |  | ||||||
|                             }// onClick() |  | ||||||
|                         }); |  | ||||||
|  |  | ||||||
|                 return true;// PACKED_POSITION_TYPE_GROUP |  | ||||||
|  |  | ||||||
|             case ExpandableListView.PACKED_POSITION_TYPE_CHILD: |  | ||||||
|                 Cursor cursor = mBookmarkCursorAdapter.getChild(iGroup, iChild); |  | ||||||
|                 final String providerId = cursor.getString(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract.COLUMN_PROVIDER_ID)); |  | ||||||
|                 final int bookmarkId = cursor.getInt(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract._ID)); |  | ||||||
|                 final Uri uri = Uri.parse(cursor.getString(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract.COLUMN_URI))); |  | ||||||
|                 final String name = cursor.getString(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract.COLUMN_NAME)); |  | ||||||
|  |  | ||||||
|                 ContextMenuUtils.showContextMenu(getActivity(), |  | ||||||
|                         R.drawable.afc_bookmarks_dark, TextUtils.quote(name), |  | ||||||
|                         new Integer[] { R.string.afc_cmd_rename, |  | ||||||
|                                 R.string.afc_cmd_sort_by_name }, |  | ||||||
|                         new ContextMenuUtils.OnMenuItemClickListener() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void onClick(int resId) { |  | ||||||
|                                 if (resId == R.string.afc_cmd_rename) { |  | ||||||
|                                     doEnterNewNameOrRenameBookmark( |  | ||||||
|                                             getActivity(), providerId, |  | ||||||
|                                             bookmarkId, uri, name); |  | ||||||
|                                 } else if (resId == R.string.afc_cmd_sort_by_name) { |  | ||||||
|                                     sortBookmarks(iGroup); |  | ||||||
|                                 } |  | ||||||
|                             }// onClick() |  | ||||||
|                         }); |  | ||||||
|                 return true;// PACKED_POSITION_TYPE_CHILD |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return false; |  | ||||||
|         }// onItemLongClick() |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * Sorts bookmarks. |  | ||||||
|          *  |  | ||||||
|          * @param groupPosition |  | ||||||
|          *            the group position. |  | ||||||
|          */ |  | ||||||
|         private void sortBookmarks(int groupPosition) { |  | ||||||
|             SparseArray<String> bookmarks = new SparseArray<String>(); |  | ||||||
|             List<String> names = new ArrayList<String>(); |  | ||||||
|             for (int i = 0; i < mBookmarkCursorAdapter |  | ||||||
|                     .getChildrenCount(groupPosition); i++) { |  | ||||||
|                 Cursor cursor = mBookmarkCursorAdapter.getChild(groupPosition, |  | ||||||
|                         i); |  | ||||||
|                 names.add(cursor.getString(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract.COLUMN_NAME))); |  | ||||||
|                 bookmarks.put(cursor.getInt(cursor |  | ||||||
|                         .getColumnIndex(BookmarkContract._ID)), names.get(i)); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             Collections.sort(names, new Comparator<String>() { |  | ||||||
|  |  | ||||||
|                 final Collator mCollator = Collator.getInstance(); |  | ||||||
|  |  | ||||||
|                 @Override |  | ||||||
|                 public int compare(String lhs, String rhs) { |  | ||||||
|                     return mCollator.compare(lhs, rhs); |  | ||||||
|                 }// compare() |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             ContentResolver contentResolver = getActivity() |  | ||||||
|                     .getContentResolver(); |  | ||||||
|             /* |  | ||||||
|              * The list was sorted ascending by name (A-Z), now we add "i" to |  | ||||||
|              * timestamp (last modified), so the list will be obtained ascending |  | ||||||
|              * by name (A-Z) as it will be obtained from DB descending by last |  | ||||||
|              * modified. |  | ||||||
|              */ |  | ||||||
|             ContentValues values = new ContentValues(); |  | ||||||
|             while (names.size() > 0) { |  | ||||||
|                 values.put( |  | ||||||
|                         BookmarkContract.COLUMN_MODIFICATION_TIME, |  | ||||||
|                         DbUtils.formatNumber(new Date().getTime() |  | ||||||
|                                 + bookmarks.size() - names.size())); |  | ||||||
|                 contentResolver.update(BookmarkContract |  | ||||||
|                         .genContentUri(getActivity()), values, String.format( |  | ||||||
|                         "%s = %d", DbUtils.SQLITE_FTS_COLUMN_ROW_ID, bookmarks |  | ||||||
|                                 .keyAt(bookmarks.indexOfValue(names |  | ||||||
|                                         .remove(names.size() - 1)))), null); |  | ||||||
|             } |  | ||||||
|         }// sortBookmarks() |  | ||||||
|     };// mListViewOnItemLongClickListener |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Shows a dialog to let the user enter new name or change current name of a |  | ||||||
|      * bookmark. |  | ||||||
|      *  |  | ||||||
|      * @param context |  | ||||||
|      *            {@link Context} |  | ||||||
|      * @param providerId |  | ||||||
|      *            the provider ID. |  | ||||||
|      * @param id |  | ||||||
|      *            the bookmark ID. |  | ||||||
|      * @param uri |  | ||||||
|      *            the URI to the bookmark. |  | ||||||
|      * @param name |  | ||||||
|      *            the name. To enter new name, this is the suggested name you |  | ||||||
|      *            provide. To rename, this is the old name. |  | ||||||
|      */ |  | ||||||
|     public static void doEnterNewNameOrRenameBookmark(final Context context, |  | ||||||
|             final String providerId, final int id, final Uri uri, |  | ||||||
|             final String name) { |  | ||||||
|         final AlertDialog dialog = Dlg.newAlertDlg(context); |  | ||||||
|  |  | ||||||
|         View view = LayoutInflater.from(context).inflate( |  | ||||||
|                 R.layout.afc_simple_text_input_view, null); |  | ||||||
|         final EditText textName = (EditText) view.findViewById(R.id.afc_text1); |  | ||||||
|         textName.setText(name); |  | ||||||
|         textName.selectAll(); |  | ||||||
|         textName.setHint(R.string.afc_hint_new_name); |  | ||||||
|         textName.setOnEditorActionListener(new TextView.OnEditorActionListener() { |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public boolean onEditorAction(TextView v, int actionId, |  | ||||||
|                     KeyEvent event) { |  | ||||||
|                 if (actionId == EditorInfo.IME_ACTION_DONE) { |  | ||||||
|                     Ui.showSoftKeyboard(textName, false); |  | ||||||
|                     Button btn = dialog |  | ||||||
|                             .getButton(DialogInterface.BUTTON_POSITIVE); |  | ||||||
|                     if (btn.isEnabled()) |  | ||||||
|                         btn.performClick(); |  | ||||||
|                     return true; |  | ||||||
|                 } |  | ||||||
|                 return false; |  | ||||||
|             }// onEditorAction() |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         dialog.setView(view); |  | ||||||
|         dialog.setIcon(R.drawable.afc_bookmarks_dark); |  | ||||||
|         dialog.setTitle(id < 0 ? R.string.afc_title_new_bookmark |  | ||||||
|                 : R.string.afc_title_rename); |  | ||||||
|         dialog.setButton(DialogInterface.BUTTON_POSITIVE, |  | ||||||
|                 context.getString(android.R.string.ok), |  | ||||||
|                 new DialogInterface.OnClickListener() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public void onClick(DialogInterface dialog, int which) { |  | ||||||
|                         String newName = textName.getText().toString().trim(); |  | ||||||
|                         if (android.text.TextUtils.isEmpty(newName)) { |  | ||||||
|                             Dlg.toast(context, |  | ||||||
|                                     R.string.afc_msg_bookmark_name_is_invalid, |  | ||||||
|                                     Dlg.LENGTH_SHORT); |  | ||||||
|                             return; |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         Ui.showSoftKeyboard(textName, false); |  | ||||||
|  |  | ||||||
|                         ContentValues values = new ContentValues(); |  | ||||||
|                         values.put(BookmarkContract.COLUMN_NAME, newName); |  | ||||||
|  |  | ||||||
|                         if (id >= 0) { |  | ||||||
|                             values.put( |  | ||||||
|                                     BookmarkContract.COLUMN_MODIFICATION_TIME, |  | ||||||
|                                     DbUtils.formatNumber(new Date().getTime())); |  | ||||||
|                             context.getContentResolver().update( |  | ||||||
|                                     Uri.withAppendedPath(BookmarkContract |  | ||||||
|                                             .genContentIdUriBase(context), Uri |  | ||||||
|                                             .encode(Integer.toString(id))), |  | ||||||
|                                     values, null, null); |  | ||||||
|                         } else { |  | ||||||
|                             /* |  | ||||||
|                              * Check if the URI exists or doesn't. If it exists, |  | ||||||
|                              * update it instead of inserting the new one. |  | ||||||
|                              */ |  | ||||||
|                             Cursor cursor = context |  | ||||||
|                                     .getContentResolver() |  | ||||||
|                                     .query(BookmarkContract |  | ||||||
|                                             .genContentUri(context), |  | ||||||
|                                             null, |  | ||||||
|                                             String.format( |  | ||||||
|                                                     "%s = %s AND %s LIKE %s", |  | ||||||
|                                                     BookmarkContract.COLUMN_PROVIDER_ID, |  | ||||||
|                                                     DatabaseUtils |  | ||||||
|                                                             .sqlEscapeString(providerId), |  | ||||||
|                                                     BookmarkContract.COLUMN_URI, |  | ||||||
|                                                     DatabaseUtils |  | ||||||
|                                                             .sqlEscapeString(uri |  | ||||||
|                                                                     .toString())), |  | ||||||
|                                             null, null); |  | ||||||
|                             try { |  | ||||||
|                                 if (cursor != null && cursor.moveToFirst()) { |  | ||||||
|                                     values.put( |  | ||||||
|                                             BookmarkContract.COLUMN_MODIFICATION_TIME, |  | ||||||
|                                             DbUtils.formatNumber(new Date() |  | ||||||
|                                                     .getTime())); |  | ||||||
|                                     context.getContentResolver() |  | ||||||
|                                             .update(Uri |  | ||||||
|                                                     .withAppendedPath( |  | ||||||
|                                                             BookmarkContract |  | ||||||
|                                                                     .genContentIdUriBase(context), |  | ||||||
|                                                             Uri.encode(cursor |  | ||||||
|                                                                     .getString(cursor |  | ||||||
|                                                                             .getColumnIndex(BookmarkContract._ID)))), |  | ||||||
|                                                     values, null, null); |  | ||||||
|                                 } else { |  | ||||||
|                                     values.put( |  | ||||||
|                                             BookmarkContract.COLUMN_PROVIDER_ID, |  | ||||||
|                                             providerId); |  | ||||||
|                                     values.put(BookmarkContract.COLUMN_URI, |  | ||||||
|                                             uri.toString()); |  | ||||||
|  |  | ||||||
|                                     context.getContentResolver().insert( |  | ||||||
|                                             BookmarkContract |  | ||||||
|                                                     .genContentUri(context), |  | ||||||
|                                             values); |  | ||||||
|                                 } |  | ||||||
|                             } finally { |  | ||||||
|                                 if (cursor != null) |  | ||||||
|                                     cursor.close(); |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         Dlg.toast(context, |  | ||||||
|                                 context.getString(R.string.afc_msg_done), |  | ||||||
|                                 Dlg.LENGTH_SHORT); |  | ||||||
|                     }// onClick() |  | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|         dialog.show(); |  | ||||||
|         Ui.showSoftKeyboard(textName, true); |  | ||||||
|  |  | ||||||
|         final Button buttonOk = dialog |  | ||||||
|                 .getButton(DialogInterface.BUTTON_POSITIVE); |  | ||||||
|         buttonOk.setEnabled(id < 0); |  | ||||||
|  |  | ||||||
|         textName.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) { |  | ||||||
|                 String newName = s.toString().trim(); |  | ||||||
|                 boolean enabled = !android.text.TextUtils.isEmpty(newName); |  | ||||||
|                 buttonOk.setEnabled(enabled); |  | ||||||
|  |  | ||||||
|                 /* |  | ||||||
|                  * If renaming, only enable button OK if new name is not equal |  | ||||||
|                  * to the old one. |  | ||||||
|                  */ |  | ||||||
|                 if (enabled && id >= 0) |  | ||||||
|                     buttonOk.setEnabled(!newName.equals(name)); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     }// doEnterNewNameOrRenameBookmark() |  | ||||||
|  |  | ||||||
|     private final View.OnClickListener mBtnClearOnClickListener = new View.OnClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onClick(View v) { |  | ||||||
|             if (mBookmarkCursorAdapter.getGroupCount() == 1 |  | ||||||
|                     && mBookmarkCursorAdapter.getChildrenCount(0) == 1) { |  | ||||||
|                 clearBookmarksAndDismiss(); |  | ||||||
|             } else { |  | ||||||
|                 Dlg.confirmYesno( |  | ||||||
|                         getActivity(), |  | ||||||
|                         getString(R.string.afc_msg_confirm_clear_all_bookmarks), |  | ||||||
|                         new DialogInterface.OnClickListener() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void onClick(DialogInterface dialog, |  | ||||||
|                                     int which) { |  | ||||||
|                                 clearBookmarksAndDismiss(); |  | ||||||
|                             }// onClick() |  | ||||||
|                         }); |  | ||||||
|             } |  | ||||||
|         }// onClick() |  | ||||||
|  |  | ||||||
|         private void clearBookmarksAndDismiss() { |  | ||||||
|             getActivity().getContentResolver().delete( |  | ||||||
|                     BookmarkContract.genContentUri(getActivity()), null, null); |  | ||||||
|             updateUI(); |  | ||||||
|             if (getDialog() != null) |  | ||||||
|                 dismiss(); |  | ||||||
|         }// clearBookmarks() |  | ||||||
|     };// mBtnClearOnClickListener |  | ||||||
|  |  | ||||||
|     private final View.OnClickListener mBtnOkOnClickListener = new View.OnClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onClick(View v) { |  | ||||||
|             if (getDialog() != null) |  | ||||||
|                 dismiss(); |  | ||||||
|             else |  | ||||||
|                 setEditor(false); |  | ||||||
|         }// onClick() |  | ||||||
|     };// mBtnOkOnClickListener |  | ||||||
| } |  | ||||||
| @@ -1,613 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    Copyright (c) 2012 Hai Bison |  | ||||||
|  * |  | ||||||
|  *    See the file LICENSE at the root directory of this project for copying |  | ||||||
|  *    permission. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package group.pals.android.lib.ui.filechooser.utils.ui.history; |  | ||||||
|  |  | ||||||
| import group.pals.android.lib.ui.filechooser.BuildConfig; |  | ||||||
| import group.pals.android.lib.ui.filechooser.R; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.basefile.BaseFileContract.BaseFile; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.history.HistoryContract; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.DateUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Ui; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Calendar; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.TimeZone; |  | ||||||
|  |  | ||||||
| import android.content.Context; |  | ||||||
| import android.database.Cursor; |  | ||||||
| import android.database.MatrixCursor; |  | ||||||
| import android.util.Log; |  | ||||||
| import android.util.SparseArray; |  | ||||||
| import android.view.View; |  | ||||||
| import android.widget.CheckBox; |  | ||||||
| import android.widget.CompoundButton; |  | ||||||
| import android.widget.ResourceCursorTreeAdapter; |  | ||||||
| import android.widget.TextView; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * History cursor adapter. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public class HistoryCursorAdapter extends ResourceCursorTreeAdapter { |  | ||||||
|  |  | ||||||
|     private static final String CLASSNAME = HistoryCursorAdapter.class |  | ||||||
|             .getName(); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @see android.text.format.DateUtils#DAY_IN_MILLIS |  | ||||||
|      */ |  | ||||||
|     private static final long DAY_IN_MILLIS = android.text.format.DateUtils.DAY_IN_MILLIS; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Advanced selection options: All, None, Invert. |  | ||||||
|      */ |  | ||||||
|     public static final Integer[] ADVANCED_SELECTION_OPTIONS = new Integer[] { |  | ||||||
|             R.string.afc_cmd_advanced_selection_all, |  | ||||||
|             R.string.afc_cmd_advanced_selection_none, |  | ||||||
|             R.string.afc_cmd_advanced_selection_invert }; |  | ||||||
|  |  | ||||||
|     private static class BagGroup { |  | ||||||
|  |  | ||||||
|         TextView mTextViewHeader; |  | ||||||
|     }// BagGroup |  | ||||||
|  |  | ||||||
|     private static class BagChild { |  | ||||||
|  |  | ||||||
|         TextView mTextViewTime; |  | ||||||
|         TextView mTextViewName; |  | ||||||
|         TextView mTextViewPath; |  | ||||||
|         CheckBox mCheckBox; |  | ||||||
|     }// BagChild |  | ||||||
|  |  | ||||||
|     private static class BagChildInfo { |  | ||||||
|  |  | ||||||
|         boolean mChecked = false; |  | ||||||
|         boolean mMarkedAsDeleted = false; |  | ||||||
|     }// BagChildInfo |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * This column holds the original position of group cursor in original |  | ||||||
|      * cursor. |  | ||||||
|      * <p/> |  | ||||||
|      * Type: {@code Integer} |  | ||||||
|      */ |  | ||||||
|     private static final String COLUMN_ORG_GROUP_POSITION = "org_group_position"; |  | ||||||
|  |  | ||||||
|     private static final String[] GROUP_CURSOR_COLUMNS = { HistoryContract._ID, |  | ||||||
|             HistoryContract.COLUMN_MODIFICATION_TIME, COLUMN_ORG_GROUP_POSITION }; |  | ||||||
|  |  | ||||||
|     private static final String[] CHILD_CURSOR_COLUMNS = { HistoryContract._ID, |  | ||||||
|             HistoryContract.COLUMN_URI, HistoryContract.COLUMN_PROVIDER_ID, |  | ||||||
|             HistoryContract.COLUMN_MODIFICATION_TIME, BaseFile.COLUMN_NAME, |  | ||||||
|             BaseFile.COLUMN_REAL_URI }; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Map of child IDs to {@link BagChildInfo}. |  | ||||||
|      */ |  | ||||||
|     private final SparseArray<BagChildInfo> mSelectedChildrenMap = new SparseArray<BagChildInfo>(); |  | ||||||
|  |  | ||||||
|     private Cursor mOrgCursor; |  | ||||||
|     private MatrixCursor mGroupCursor; |  | ||||||
|     private SparseArray<MatrixCursor> mChildrenCursor; |  | ||||||
|     private CharSequence mSearchText; |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Creates new instance. |  | ||||||
|      *  |  | ||||||
|      * @param context |  | ||||||
|      *            {@link Context}. |  | ||||||
|      */ |  | ||||||
|     public HistoryCursorAdapter(Context context) { |  | ||||||
|         super(context, null, R.layout.afc_view_history_item, |  | ||||||
|                 R.layout.afc_view_history_sub_item); |  | ||||||
|     }// BookmarkCursorAdapter() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Changes new cursor. |  | ||||||
|      * <p/> |  | ||||||
|      * You have to query the items in descending order of modification time. |  | ||||||
|      *  |  | ||||||
|      * @param cursor |  | ||||||
|      *            the cursor. |  | ||||||
|      * @param notificationUri |  | ||||||
|      *            the notification URI. |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public synchronized void changeCursor(Cursor cursor) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "changeCursor()"); |  | ||||||
|  |  | ||||||
|         if (mOrgCursor != null) |  | ||||||
|             mOrgCursor.close(); |  | ||||||
|         mOrgCursor = cursor; |  | ||||||
|  |  | ||||||
|         MatrixCursor newGroupCursor = cursor != null ? new MatrixCursor( |  | ||||||
|                 GROUP_CURSOR_COLUMNS) : null; |  | ||||||
|         SparseArray<MatrixCursor> newChildrenCursor = cursor != null ? new SparseArray<MatrixCursor>() |  | ||||||
|                 : null; |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Build new group cursor. |  | ||||||
|          */ |  | ||||||
|         if (cursor != null && cursor.moveToFirst()) { |  | ||||||
|             long lastDayCount = 0; |  | ||||||
|             do { |  | ||||||
|                 long dayCount = (long) Math |  | ||||||
|                         .floor((Long.parseLong(cursor.getString(cursor |  | ||||||
|                                 .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME))) + TimeZone |  | ||||||
|                                 .getDefault().getRawOffset()) |  | ||||||
|                                 / DAY_IN_MILLIS); |  | ||||||
|  |  | ||||||
|                 if (dayCount != lastDayCount || newGroupCursor.getCount() == 0) { |  | ||||||
|                     newGroupCursor |  | ||||||
|                             .addRow(new Object[] { |  | ||||||
|                                     cursor.getInt(cursor |  | ||||||
|                                             .getColumnIndex(HistoryContract._ID)), |  | ||||||
|                                     cursor.getString(cursor |  | ||||||
|                                             .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME)), |  | ||||||
|                                     cursor.getPosition() }); |  | ||||||
|                 } |  | ||||||
|                 lastDayCount = dayCount; |  | ||||||
|             } while (cursor.moveToNext()); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Clean up children cursor. |  | ||||||
|          */ |  | ||||||
|         if (mChildrenCursor != null) { |  | ||||||
|             for (int i = 0; i < mChildrenCursor.size(); i++) |  | ||||||
|                 mChildrenCursor.valueAt(i).close(); |  | ||||||
|             mChildrenCursor.clear(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Apply new changes... Note that we don't need to close the old group |  | ||||||
|          * cursor. The call to `super.changeCursor()` will do that. |  | ||||||
|          */ |  | ||||||
|         mGroupCursor = newGroupCursor; |  | ||||||
|         mChildrenCursor = newChildrenCursor; |  | ||||||
|         super.changeCursor(mGroupCursor); |  | ||||||
|     }// changeCursor() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected Cursor getChildrenCursor(Cursor groupCursor) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "getChildrenCursor()"); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Try to find the child cursor in the map. If found then it'd be great |  | ||||||
|          * :-) |  | ||||||
|          */ |  | ||||||
|         int orgGroupPosition = groupCursor.getInt(groupCursor |  | ||||||
|                 .getColumnIndex(COLUMN_ORG_GROUP_POSITION)); |  | ||||||
|         int idx = mChildrenCursor.indexOfKey(orgGroupPosition); |  | ||||||
|         if (idx >= 0) |  | ||||||
|             return mChildrenCursor.valueAt(idx); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * If not found, create new cursor. |  | ||||||
|          */ |  | ||||||
|         MatrixCursor childrenCursor = new MatrixCursor(CHILD_CURSOR_COLUMNS); |  | ||||||
|  |  | ||||||
|         mOrgCursor.moveToPosition(orgGroupPosition); |  | ||||||
|         long startOfDay = Long.parseLong(groupCursor.getString(groupCursor |  | ||||||
|                 .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME))) |  | ||||||
|                 + TimeZone.getDefault().getRawOffset(); |  | ||||||
|         startOfDay -= startOfDay % DAY_IN_MILLIS; |  | ||||||
|         do { |  | ||||||
|             childrenCursor |  | ||||||
|                     .addRow(new Object[] { |  | ||||||
|                             mOrgCursor.getInt(mOrgCursor |  | ||||||
|                                     .getColumnIndex(HistoryContract._ID)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(HistoryContract.COLUMN_URI)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(HistoryContract.COLUMN_PROVIDER_ID)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BaseFile.COLUMN_NAME)), |  | ||||||
|                             mOrgCursor.getString(mOrgCursor |  | ||||||
|                                     .getColumnIndex(BaseFile.COLUMN_REAL_URI)) }); |  | ||||||
|         } while (mOrgCursor.moveToNext() |  | ||||||
|                 && Long.parseLong(mOrgCursor.getString(mOrgCursor |  | ||||||
|                         .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME))) |  | ||||||
|                         + TimeZone.getDefault().getRawOffset() >= startOfDay); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Put it to the map. |  | ||||||
|          */ |  | ||||||
|         mChildrenCursor.put(orgGroupPosition, childrenCursor); |  | ||||||
|         return childrenCursor; |  | ||||||
|     }// getChildrenCursor() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected void bindChildView(View view, Context context, Cursor cursor, |  | ||||||
|             boolean isLastChild) { |  | ||||||
|         final int id = cursor |  | ||||||
|                 .getInt(cursor.getColumnIndex(HistoryContract._ID)); |  | ||||||
|         final BagChild child; |  | ||||||
|  |  | ||||||
|         if (view.getTag() == null) { |  | ||||||
|             child = new BagChild(); |  | ||||||
|             child.mTextViewTime = (TextView) view |  | ||||||
|                     .findViewById(R.id.afc_textview_time); |  | ||||||
|             child.mTextViewName = (TextView) view |  | ||||||
|                     .findViewById(R.id.afc_textview_name); |  | ||||||
|             child.mTextViewPath = (TextView) view |  | ||||||
|                     .findViewById(R.id.afc_textview_path); |  | ||||||
|             child.mCheckBox = (CheckBox) view.findViewById(R.id.afc_checkbox); |  | ||||||
|  |  | ||||||
|             view.setTag(child); |  | ||||||
|         } else |  | ||||||
|             child = (BagChild) view.getTag(); |  | ||||||
|  |  | ||||||
|         final BagChildInfo childInfo; |  | ||||||
|         if (mSelectedChildrenMap.get(id) == null) { |  | ||||||
|             childInfo = new BagChildInfo(); |  | ||||||
|             mSelectedChildrenMap.put(id, childInfo); |  | ||||||
|         } else |  | ||||||
|             childInfo = mSelectedChildrenMap.get(id); |  | ||||||
|  |  | ||||||
|         String fileName = null; |  | ||||||
|         String fileUri = null; |  | ||||||
|         int col = -1; |  | ||||||
|         if ((col = cursor.getColumnIndex(BaseFile.COLUMN_NAME)) >= 0) |  | ||||||
|             fileName = cursor.getString(col); |  | ||||||
|         if ((col = cursor.getColumnIndex(BaseFile.COLUMN_REAL_URI)) >= 0) |  | ||||||
|             fileUri = cursor.getString(col); |  | ||||||
|  |  | ||||||
|         child.mTextViewTime |  | ||||||
|                 .setText(formatTime( |  | ||||||
|                         view.getContext(), |  | ||||||
|                         Long.parseLong(cursor.getString(cursor |  | ||||||
|                                 .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME))))); |  | ||||||
|         child.mTextViewName.setText(fileName); |  | ||||||
|         Ui.strikeOutText(child.mTextViewName, childInfo.mMarkedAsDeleted); |  | ||||||
|         child.mTextViewPath.setText(fileUri); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Provider ID. |  | ||||||
|          */ |  | ||||||
|         String providerId = cursor.getString(cursor |  | ||||||
|                 .getColumnIndex(HistoryContract.COLUMN_PROVIDER_ID)); |  | ||||||
|         /* |  | ||||||
|          * Provider badge icon. |  | ||||||
|          */ |  | ||||||
|         child.mTextViewTime.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, |  | ||||||
|                 BaseFileProviderUtils.getProviderIconId(context, providerId)); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Check box. |  | ||||||
|          */ |  | ||||||
|         child.mCheckBox.setOnCheckedChangeListener(null); |  | ||||||
|         child.mCheckBox.setChecked(childInfo.mChecked); |  | ||||||
|         child.mCheckBox |  | ||||||
|                 .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public void onCheckedChanged(CompoundButton buttonView, |  | ||||||
|                             boolean isChecked) { |  | ||||||
|                         if (BuildConfig.DEBUG) |  | ||||||
|                             Log.d(CLASSNAME, "onCheckedChanged() >> id = " + id); |  | ||||||
|                         childInfo.mChecked = isChecked; |  | ||||||
|                     }// onCheckedChanged() |  | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|         child.mCheckBox.setOnLongClickListener(new View.OnLongClickListener() { |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public boolean onLongClick(View v) { |  | ||||||
|                 ContextMenuUtils.showContextMenu(v.getContext(), 0, |  | ||||||
|                         R.string.afc_title_advanced_selection, |  | ||||||
|                         ADVANCED_SELECTION_OPTIONS, |  | ||||||
|                         new ContextMenuUtils.OnMenuItemClickListener() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void onClick(final int resId) { |  | ||||||
|                                 if (resId == R.string.afc_cmd_advanced_selection_all) |  | ||||||
|                                     selectAll(true); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_none) |  | ||||||
|                                     selectAll(false); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_invert) |  | ||||||
|                                     invertSelection(); |  | ||||||
|                             }// onClick() |  | ||||||
|                         }); |  | ||||||
|                 return true; |  | ||||||
|             }// onLongClick() |  | ||||||
|         }); |  | ||||||
|     }// bindChildView() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     protected void bindGroupView(View view, Context context, |  | ||||||
|             final Cursor cursor, boolean isExpanded) { |  | ||||||
|         BagGroup b; |  | ||||||
|         if (view.getTag() == null) { |  | ||||||
|             b = new BagGroup(); |  | ||||||
|             b.mTextViewHeader = (TextView) view |  | ||||||
|                     .findViewById(R.id.afc_textview_header); |  | ||||||
|  |  | ||||||
|             view.setTag(b); |  | ||||||
|         } else |  | ||||||
|             b = (BagGroup) view.getTag(); |  | ||||||
|  |  | ||||||
|         b.mTextViewHeader |  | ||||||
|                 .setText(formatDate( |  | ||||||
|                         view.getContext(), |  | ||||||
|                         Long.parseLong(cursor.getString(cursor |  | ||||||
|                                 .getColumnIndex(HistoryContract.COLUMN_MODIFICATION_TIME))))); |  | ||||||
|     }// bindGroupView() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void notifyDataSetChanged(boolean releaseCursors) { |  | ||||||
|         super.notifyDataSetChanged(releaseCursors); |  | ||||||
|         if (releaseCursors) |  | ||||||
|             synchronized (mSelectedChildrenMap) { |  | ||||||
|                 mSelectedChildrenMap.clear(); |  | ||||||
|             } |  | ||||||
|     }// notifyDataSetChanged() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void notifyDataSetInvalidated() { |  | ||||||
|         super.notifyDataSetInvalidated(); |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             mSelectedChildrenMap.clear(); |  | ||||||
|         } |  | ||||||
|     }// notifyDataSetInvalidated() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * UTILITIES |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets the search text. |  | ||||||
|      *  |  | ||||||
|      * @return the search text, can be {@code null}. |  | ||||||
|      */ |  | ||||||
|     public CharSequence getSearchText() { |  | ||||||
|         return mSearchText; |  | ||||||
|     }// getSearchText() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Sets search text. |  | ||||||
|      *  |  | ||||||
|      * @param searchText |  | ||||||
|      *            the search text. |  | ||||||
|      */ |  | ||||||
|     public void setSearchText(CharSequence searchText) { |  | ||||||
|         mSearchText = searchText; |  | ||||||
|     }// setSearchText() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Selects all items in a specified group. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This will <i>not</i> notify data set for changes after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      * @param selected |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     private void asyncSelectAll(int groupPosition, boolean selected) { |  | ||||||
|         int chidrenCount = getChildrenCount(groupPosition); |  | ||||||
|         for (int iChild = 0; iChild < chidrenCount; iChild++) { |  | ||||||
|             Cursor cursor = getChild(groupPosition, iChild); |  | ||||||
|             final int id = cursor.getInt(cursor |  | ||||||
|                     .getColumnIndex(HistoryContract._ID)); |  | ||||||
|             BagChildInfo childInfo = mSelectedChildrenMap.get(id); |  | ||||||
|             if (childInfo == null) { |  | ||||||
|                 childInfo = new BagChildInfo(); |  | ||||||
|                 mSelectedChildrenMap.put(id, childInfo); |  | ||||||
|             } |  | ||||||
|             childInfo.mChecked = selected; |  | ||||||
|         }// for children |  | ||||||
|     }// asyncSelectAll() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Selects all items of a specified group. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      * @param selected |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public synchronized void selectAll(int groupPosition, boolean selected) { |  | ||||||
|         asyncSelectAll(groupPosition, selected); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// selectAll() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Selects all items. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param selected |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public synchronized void selectAll(boolean selected) { |  | ||||||
|         for (int iGroup = 0; iGroup < getGroupCount(); iGroup++) |  | ||||||
|             asyncSelectAll(iGroup, selected); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// selectAll() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Inverts selection. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This will <i>not</i> notify data set for changes after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      */ |  | ||||||
|     private void asyncInvertSelection(int groupPosition) { |  | ||||||
|         int chidrenCount = getChildrenCount(groupPosition); |  | ||||||
|         for (int iChild = 0; iChild < chidrenCount; iChild++) { |  | ||||||
|             Cursor cursor = getChild(groupPosition, iChild); |  | ||||||
|             final int id = cursor.getInt(cursor |  | ||||||
|                     .getColumnIndex(HistoryContract._ID)); |  | ||||||
|             BagChildInfo childInfo = mSelectedChildrenMap.get(id); |  | ||||||
|             if (childInfo == null) { |  | ||||||
|                 childInfo = new BagChildInfo(); |  | ||||||
|                 mSelectedChildrenMap.put(id, childInfo); |  | ||||||
|             } |  | ||||||
|             childInfo.mChecked = !childInfo.mChecked; |  | ||||||
|         }// for children |  | ||||||
|     }// asyncInvertSelection() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Inverts selection of all items of a specified group. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      *  |  | ||||||
|      * @param groupPosition |  | ||||||
|      *            the group position. |  | ||||||
|      */ |  | ||||||
|     public synchronized void invertSelection(int groupPosition) { |  | ||||||
|         asyncInvertSelection(groupPosition); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// invertSelection() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Inverts selection of all items. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged(boolean)} (with |  | ||||||
|      * {@code false}) after done. |  | ||||||
|      */ |  | ||||||
|     public synchronized void invertSelection() { |  | ||||||
|         for (int iGroup = 0; iGroup < getGroupCount(); iGroup++) |  | ||||||
|             asyncInvertSelection(iGroup); |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// invertSelection() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Checks if item with {@code id} (the database ID) is selected or not. |  | ||||||
|      *  |  | ||||||
|      * @param id |  | ||||||
|      *            the database ID. |  | ||||||
|      * @return {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public boolean isSelected(int id) { |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             return mSelectedChildrenMap.get(id) != null ? mSelectedChildrenMap |  | ||||||
|                     .get(id).mChecked : false; |  | ||||||
|         } |  | ||||||
|     }// isSelected() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets IDs of selected items. |  | ||||||
|      *  |  | ||||||
|      * @return list of IDs, can be empty. |  | ||||||
|      */ |  | ||||||
|     public List<Integer> getSelectedItemIds() { |  | ||||||
|         List<Integer> res = new ArrayList<Integer>(); |  | ||||||
|  |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             for (int i = 0; i < mSelectedChildrenMap.size(); i++) |  | ||||||
|                 if (mSelectedChildrenMap.get(mSelectedChildrenMap.keyAt(i)).mChecked) |  | ||||||
|                     res.add(mSelectedChildrenMap.keyAt(i)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return res; |  | ||||||
|     }// getSelectedItemIds() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Marks all selected items as deleted. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged()} after done. |  | ||||||
|      *  |  | ||||||
|      * @param deleted |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public void markSelectedItemsAsDeleted(boolean deleted) { |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             for (int i = 0; i < mSelectedChildrenMap.size(); i++) |  | ||||||
|                 if (mSelectedChildrenMap.get(mSelectedChildrenMap.keyAt(i)).mChecked) |  | ||||||
|                     mSelectedChildrenMap.get(mSelectedChildrenMap.keyAt(i)).mMarkedAsDeleted = deleted; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         notifyDataSetChanged(false); |  | ||||||
|     }// markSelectedItemsAsDeleted() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Marks specified item as deleted. |  | ||||||
|      * <p/> |  | ||||||
|      * <b>Note:</b> This calls {@link #notifyDataSetChanged()} after done. |  | ||||||
|      *  |  | ||||||
|      * @param id |  | ||||||
|      *            the database ID of the item. |  | ||||||
|      * @param deleted |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     public void markItemAsDeleted(int id, boolean deleted) { |  | ||||||
|         synchronized (mSelectedChildrenMap) { |  | ||||||
|             if (mSelectedChildrenMap.get(id) != null) { |  | ||||||
|                 mSelectedChildrenMap.get(id).mMarkedAsDeleted = deleted; |  | ||||||
|                 notifyDataSetChanged(false); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     }// markItemAsDeleted() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * STATIC UTILITIES |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Formats {@code millis} to time. |  | ||||||
|      *  |  | ||||||
|      * @param c |  | ||||||
|      *            {@link Context}. |  | ||||||
|      * @param millis |  | ||||||
|      *            the time in milliseconds. |  | ||||||
|      * @return the formatted time. |  | ||||||
|      */ |  | ||||||
|     private static String formatDate(Context c, long millis) { |  | ||||||
|         if (android.text.format.DateUtils.isToday(millis)) |  | ||||||
|             return c.getString(R.string.afc_today); |  | ||||||
|  |  | ||||||
|         Calendar cal = Calendar.getInstance(); |  | ||||||
|         cal.setTimeInMillis(millis); |  | ||||||
|  |  | ||||||
|         final Calendar yesterday = Calendar.getInstance(); |  | ||||||
|         yesterday.add(Calendar.DAY_OF_YEAR, -1); |  | ||||||
|  |  | ||||||
|         if (cal.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR)) { |  | ||||||
|             if (cal.get(Calendar.DAY_OF_YEAR) == yesterday |  | ||||||
|                     .get(Calendar.DAY_OF_YEAR)) |  | ||||||
|                 return c.getString(R.string.afc_yesterday); |  | ||||||
|             else |  | ||||||
|                 return android.text.format.DateUtils.formatDateTime(c, millis, |  | ||||||
|                         DateUtils.FORMAT_MONTH_AND_DAY); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return android.text.format.DateUtils.formatDateTime(c, millis, |  | ||||||
|                 DateUtils.FORMAT_MONTH_AND_DAY | DateUtils.FORMAT_YEAR); |  | ||||||
|     }// formatDate() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Formats {@code millis} to short time. E.g: "10:01am". |  | ||||||
|      *  |  | ||||||
|      * @param c |  | ||||||
|      *            {@link Context}. |  | ||||||
|      * @param millis |  | ||||||
|      *            time in milliseconds. |  | ||||||
|      * @return the formatted time. |  | ||||||
|      */ |  | ||||||
|     private static String formatTime(Context c, long millis) { |  | ||||||
|         return android.text.format.DateUtils.formatDateTime(c, millis, |  | ||||||
|                 DateUtils.FORMAT_SHORT_TIME); |  | ||||||
|     }// formatTime() |  | ||||||
| } |  | ||||||
| @@ -1,774 +0,0 @@ | |||||||
| /* |  | ||||||
|  *    Copyright (c) 2012 Hai Bison |  | ||||||
|  * |  | ||||||
|  *    See the file LICENSE at the root directory of this project for copying |  | ||||||
|  *    permission. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| package group.pals.android.lib.ui.filechooser.utils.ui.history; |  | ||||||
|  |  | ||||||
| import group.pals.android.lib.ui.filechooser.BuildConfig; |  | ||||||
| import group.pals.android.lib.ui.filechooser.R; |  | ||||||
| import group.pals.android.lib.ui.filechooser.prefs.DisplayPrefs; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.DbUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.providers.history.HistoryContract; |  | ||||||
| import group.pals.android.lib.ui.filechooser.ui.widget.AfcSearchView; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.EnvUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.ContextMenuUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Dlg; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.GestureUtils; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.GestureUtils.FlingDirection; |  | ||||||
| import group.pals.android.lib.ui.filechooser.utils.ui.Ui; |  | ||||||
|  |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import android.app.Dialog; |  | ||||||
| import android.content.DialogInterface; |  | ||||||
| import android.content.res.Configuration; |  | ||||||
| import android.database.Cursor; |  | ||||||
| import android.net.Uri; |  | ||||||
| import android.os.Bundle; |  | ||||||
| import android.os.Handler; |  | ||||||
| import android.support.v4.app.DialogFragment; |  | ||||||
| import android.support.v4.app.LoaderManager; |  | ||||||
| import android.support.v4.content.CursorLoader; |  | ||||||
| import android.support.v4.content.Loader; |  | ||||||
| import android.text.TextUtils; |  | ||||||
| import android.util.Log; |  | ||||||
| import android.view.KeyEvent; |  | ||||||
| import android.view.LayoutInflater; |  | ||||||
| import android.view.Menu; |  | ||||||
| import android.view.MenuItem; |  | ||||||
| import android.view.MotionEvent; |  | ||||||
| import android.view.View; |  | ||||||
| import android.view.ViewGroup; |  | ||||||
| import android.view.Window; |  | ||||||
| import android.widget.AdapterView; |  | ||||||
| import android.widget.ExpandableListView; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Fragment used to manage history. |  | ||||||
|  *  |  | ||||||
|  * @author Hai Bison |  | ||||||
|  * @since v5.1 beta |  | ||||||
|  */ |  | ||||||
| public class HistoryFragment extends DialogFragment implements |  | ||||||
|         LoaderManager.LoaderCallbacks<Cursor> { |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Used for debugging or something... |  | ||||||
|      */ |  | ||||||
|     private static final String CLASSNAME = HistoryFragment.class.getName(); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * As the name means. |  | ||||||
|      *  |  | ||||||
|      * @author Hai Bison |  | ||||||
|      * @since v5.1 beta |  | ||||||
|      */ |  | ||||||
|     public static interface OnHistoryItemClickListener { |  | ||||||
|  |  | ||||||
|         /** |  | ||||||
|          * Will be called after history item was clicked. |  | ||||||
|          *  |  | ||||||
|          * @param providerId |  | ||||||
|          *            the original provider ID. |  | ||||||
|          * @param uri |  | ||||||
|          *            the URI to a directory or a file. |  | ||||||
|          */ |  | ||||||
|         void onItemClick(String providerId, Uri uri); |  | ||||||
|     }// OnHistoryItemClickListener |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Creates a new instance of {@link HistoryFragment}. |  | ||||||
|      */ |  | ||||||
|     public static HistoryFragment newInstance() { |  | ||||||
|         return new HistoryFragment(); |  | ||||||
|     }// newInstance() |  | ||||||
|  |  | ||||||
|     private final int mLoaderIdHistoryData = EnvUtils.genId(); |  | ||||||
|     private final int mLoaderIdHistoryCounter = EnvUtils.genId(); |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * Fields. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     private OnHistoryItemClickListener mOnHistoryItemClickListener; |  | ||||||
|  |  | ||||||
|     private final Handler mHandler = new Handler(); |  | ||||||
|     private int mLastScreenOrientation; |  | ||||||
|     private int mMaxItemsPerPage; |  | ||||||
|     private int mItemCount = 0; |  | ||||||
|     private int mPageCount = 1; |  | ||||||
|     private int mCurrentPage = 0; |  | ||||||
|  |  | ||||||
|     private Cursor mCursorCounter; |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * Controls. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     private View mBtnSearch; |  | ||||||
|     private View mViewGroupListView; |  | ||||||
|     private ExpandableListView mListView; |  | ||||||
|     private HistoryCursorAdapter mHistoryCursorAdapter; |  | ||||||
|     private AfcSearchView mSearchView; |  | ||||||
|     private View mBtnNext; |  | ||||||
|     private View mBtnPrev; |  | ||||||
|     private View mViewLoading; |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onCreate(Bundle savedInstanceState) { |  | ||||||
|         super.onCreate(savedInstanceState); |  | ||||||
|  |  | ||||||
|         mMaxItemsPerPage = getResources().getInteger( |  | ||||||
|                 R.integer.afc_pkey_history_manager_display_items_per_page); |  | ||||||
|     }// onCreate() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Dialog onCreateDialog(Bundle savedInstanceState) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onCreateDialog()"); |  | ||||||
|         Dialog dialog = new Dialog(getActivity(), Ui.resolveAttribute( |  | ||||||
|                 getActivity(), R.attr.afc_theme_dialog)) { |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public boolean onCreateOptionsMenu(Menu menu) { |  | ||||||
|                 getActivity().getMenuInflater().inflate( |  | ||||||
|                         R.menu.afc_viewgroup_history, menu); |  | ||||||
|                 return super.onCreateOptionsMenu(menu); |  | ||||||
|             }// onCreateOptionsMenu() |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public boolean onPrepareOptionsMenu(Menu menu) { |  | ||||||
|                 menu.findItem(R.id.afc_menuitem_clear).setEnabled( |  | ||||||
|                         mHistoryCursorAdapter != null |  | ||||||
|                                 && mHistoryCursorAdapter.getGroupCount() > 0); |  | ||||||
|                 return true; |  | ||||||
|             }// onPrepareOptionsMenu() |  | ||||||
|  |  | ||||||
|             @Override |  | ||||||
|             public boolean onMenuItemSelected(int featureId, MenuItem item) { |  | ||||||
|                 if (BuildConfig.DEBUG) |  | ||||||
|                     Log.d(CLASSNAME, "onMenuItemSelected() in Dialog"); |  | ||||||
|  |  | ||||||
|                 Ui.showSoftKeyboard(mSearchView, false); |  | ||||||
|  |  | ||||||
|                 if (item.getItemId() == R.id.afc_menuitem_clear) |  | ||||||
|                     doConfirmClearHistory(); |  | ||||||
|  |  | ||||||
|                 return true; |  | ||||||
|             }// onMenuItemSelected() |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); |  | ||||||
|         dialog.setCanceledOnTouchOutside(true); |  | ||||||
|         dialog.setContentView(initContentView(dialog.getLayoutInflater(), null)); |  | ||||||
|         dialog.setOnKeyListener(mDialogOnKeyListener); |  | ||||||
|  |  | ||||||
|         Ui.adjustDialogSizeForLargeScreen(dialog); |  | ||||||
|  |  | ||||||
|         return dialog; |  | ||||||
|     }// onCreateDialog() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public View onCreateView(LayoutInflater inflater, ViewGroup container, |  | ||||||
|             Bundle savedInstanceState) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onCreateView() -- getDialog() = " + getDialog()); |  | ||||||
|         return getDialog() != null ? null |  | ||||||
|                 : initContentView(inflater, container); |  | ||||||
|     }// onCreateView() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onActivityCreated(Bundle savedInstanceState) { |  | ||||||
|         super.onActivityCreated(savedInstanceState); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Prepare the loaders. Either re-connect with the existing ones, or |  | ||||||
|          * start the new ones. |  | ||||||
|          */ |  | ||||||
|         getLoaderManager().initLoader(mLoaderIdHistoryCounter, null, this); |  | ||||||
|         getLoaderManager().initLoader(mLoaderIdHistoryData, null, this); |  | ||||||
|     }// onActivityCreated() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onResume() { |  | ||||||
|         super.onResume(); |  | ||||||
|         if (mLastScreenOrientation != getResources().getConfiguration().orientation) { |  | ||||||
|             mLastScreenOrientation = getResources().getConfiguration().orientation; |  | ||||||
|             Ui.adjustDialogSizeForLargeScreen(getDialog()); |  | ||||||
|         } |  | ||||||
|     }// onResume() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onPause() { |  | ||||||
|         super.onPause(); |  | ||||||
|         mLastScreenOrientation = getResources().getConfiguration().orientation; |  | ||||||
|     }// onPause() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onConfigurationChanged(Configuration newConfig) { |  | ||||||
|         super.onConfigurationChanged(newConfig); |  | ||||||
|         if (getDialog() != null) |  | ||||||
|             Ui.adjustDialogSizeForLargeScreen(getDialog()); |  | ||||||
|     }// onConfigurationChanged() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * LOADERMANAGER.LOADERCALLBACKS |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public Loader<Cursor> onCreateLoader(int id, Bundle args) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onCreateLoader()"); |  | ||||||
|  |  | ||||||
|         enableControls(false); |  | ||||||
|  |  | ||||||
|         String selection = null; |  | ||||||
|         if (!TextUtils.isEmpty(mHistoryCursorAdapter.getSearchText())) { |  | ||||||
|             selection = DbUtils.rawSqlEscapeString(Uri |  | ||||||
|                     .encode(mHistoryCursorAdapter.getSearchText().toString())); |  | ||||||
|             selection = String.format("%s LIKE '%%://%%%s%%'", |  | ||||||
|                     HistoryContract.COLUMN_URI, selection); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (id == mLoaderIdHistoryData) { |  | ||||||
|             mHandler.removeCallbacksAndMessages(null); |  | ||||||
|             mHandler.postDelayed(mViewLoadingShower, |  | ||||||
|                     DisplayPrefs.DELAY_TIME_FOR_SIMPLE_ANIMATION); |  | ||||||
|  |  | ||||||
|             mHistoryCursorAdapter.changeCursor(null); |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * Offset. |  | ||||||
|              */ |  | ||||||
|             if (mCurrentPage >= mPageCount) |  | ||||||
|                 mCurrentPage = mPageCount - 1; |  | ||||||
|             if (mCurrentPage < 0) |  | ||||||
|                 mCurrentPage = 0; |  | ||||||
|             int offset = mCurrentPage * mMaxItemsPerPage; |  | ||||||
|  |  | ||||||
|             return new CursorLoader(getActivity(), |  | ||||||
|                     HistoryContract.genContentUri(getActivity()), null, |  | ||||||
|                     selection, null, String.format( |  | ||||||
|                             "%s DESC LIMIT %s OFFSET %s", |  | ||||||
|                             HistoryContract.COLUMN_MODIFICATION_TIME, |  | ||||||
|                             mMaxItemsPerPage, offset)); |  | ||||||
|         } // mLoaderIdHistoryData |  | ||||||
|         else if (id == mLoaderIdHistoryCounter) { |  | ||||||
|             mPageCount = 1; |  | ||||||
|             mCurrentPage = 0; |  | ||||||
|  |  | ||||||
|             if (mCursorCounter != null) { |  | ||||||
|                 mCursorCounter.close(); |  | ||||||
|                 mCursorCounter = null; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return new CursorLoader(getActivity(), |  | ||||||
|                     HistoryContract.genContentUri(getActivity()), |  | ||||||
|                     new String[] { HistoryContract._COUNT }, selection, null, |  | ||||||
|                     null); |  | ||||||
|         }// mLoaderIdHistoryCounter |  | ||||||
|  |  | ||||||
|         return null; |  | ||||||
|     }// onCreateLoader() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onLoadFinished(Loader<Cursor> loader, Cursor data) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onLoadFinished() -- data = " + data); |  | ||||||
|  |  | ||||||
|         if (loader.getId() == mLoaderIdHistoryData) { |  | ||||||
|             mSearchView.setEnabled(true); |  | ||||||
|  |  | ||||||
|             mHistoryCursorAdapter.changeCursor(data); |  | ||||||
|  |  | ||||||
|             for (int i = 0; i < mHistoryCursorAdapter.getGroupCount(); i++) |  | ||||||
|                 mListView.expandGroup(i); |  | ||||||
|  |  | ||||||
|             /* |  | ||||||
|              * Views visibilities. Always call these to make sure all views are |  | ||||||
|              * in right visibilities. |  | ||||||
|              */ |  | ||||||
|             mHandler.removeCallbacksAndMessages(null); |  | ||||||
|             mViewLoading.setVisibility(View.GONE); |  | ||||||
|             mViewGroupListView.setVisibility(View.VISIBLE); |  | ||||||
|  |  | ||||||
|             mListView.post(new Runnable() { |  | ||||||
|  |  | ||||||
|                 @Override |  | ||||||
|                 public void run() { |  | ||||||
|                     mListView.setSelection(-1); |  | ||||||
|                 } |  | ||||||
|             }); |  | ||||||
|         }// mLoaderIdHistoryData |  | ||||||
|         else if (loader.getId() == mLoaderIdHistoryCounter) { |  | ||||||
|             if (mCursorCounter != null) |  | ||||||
|                 mCursorCounter.close(); |  | ||||||
|  |  | ||||||
|             mCursorCounter = data; |  | ||||||
|             if (mCursorCounter.moveToFirst()) { |  | ||||||
|                 if (mItemCount < 0) |  | ||||||
|                     getLoaderManager().restartLoader(mLoaderIdHistoryData, |  | ||||||
|                             null, this); |  | ||||||
|                 mItemCount = mCursorCounter.getInt(mCursorCounter |  | ||||||
|                         .getColumnIndex(HistoryContract._COUNT)); |  | ||||||
|                 mPageCount = (int) Math.ceil((float) mItemCount |  | ||||||
|                         / mMaxItemsPerPage); |  | ||||||
|                 mBtnNext.setEnabled(mCurrentPage < mPageCount - 1); |  | ||||||
|                 mBtnPrev.setEnabled(mCurrentPage > 0); |  | ||||||
|             } else { |  | ||||||
|                 mBtnNext.setEnabled(false); |  | ||||||
|                 mBtnPrev.setEnabled(false); |  | ||||||
|             } |  | ||||||
|         }// mLoaderIdHistoryCounter |  | ||||||
|  |  | ||||||
|         enableControls(true); |  | ||||||
|     }// onLoadFinished() |  | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void onLoaderReset(Loader<Cursor> loader) { |  | ||||||
|         if (BuildConfig.DEBUG) |  | ||||||
|             Log.d(CLASSNAME, "onLoaderReset()"); |  | ||||||
|  |  | ||||||
|         if (loader.getId() == mLoaderIdHistoryData) { |  | ||||||
|             mHistoryCursorAdapter.changeCursor(null); |  | ||||||
|             mViewLoading.setVisibility(View.VISIBLE); |  | ||||||
|         }// mLoaderIdHistoryData |  | ||||||
|         else if (loader.getId() == mLoaderIdHistoryCounter) { |  | ||||||
|             /* |  | ||||||
|              * NOTE: if using an adapter, set its cursor to null to release |  | ||||||
|              * memory. |  | ||||||
|              */ |  | ||||||
|             if (mCursorCounter != null) { |  | ||||||
|                 mCursorCounter.close(); |  | ||||||
|                 mCursorCounter = null; |  | ||||||
|             } |  | ||||||
|         }// mLoaderIdHistoryCounter |  | ||||||
|     }// onLoaderReset() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Loads content view from XML and init controls. |  | ||||||
|      *  |  | ||||||
|      * @param inflater |  | ||||||
|      *            {@link LayoutInflater}. |  | ||||||
|      * @param container |  | ||||||
|      *            {@link ViewGroup}. |  | ||||||
|      */ |  | ||||||
|     private View initContentView(LayoutInflater inflater, ViewGroup container) { |  | ||||||
|         /* |  | ||||||
|          * LOADS CONTROLS |  | ||||||
|          */ |  | ||||||
|         View mainView = inflater.inflate(R.layout.afc_viewgroup_history, |  | ||||||
|                 container, false); |  | ||||||
|  |  | ||||||
|         mBtnSearch = mainView.findViewById(R.id.afc_button_search); |  | ||||||
|         mViewGroupListView = mainView.findViewById(R.id.afc_viewgroup_listview); |  | ||||||
|         mListView = (ExpandableListView) mainView |  | ||||||
|                 .findViewById(R.id.afc_listview); |  | ||||||
|         mSearchView = (AfcSearchView) mainView |  | ||||||
|                 .findViewById(R.id.afc_afc_search_view); |  | ||||||
|         mBtnNext = mainView.findViewById(R.id.afc_button_go_forward); |  | ||||||
|         mBtnPrev = mainView.findViewById(R.id.afc_button_go_back); |  | ||||||
|         mViewLoading = mainView.findViewById(R.id.afc_view_loading); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * INITIALIZES CONTROLS |  | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         if (mBtnSearch != null) { |  | ||||||
|             mBtnSearch.setOnClickListener(mBtnSearchOnClickListener); |  | ||||||
|             mBtnSearch.setVisibility(View.VISIBLE); |  | ||||||
|         } |  | ||||||
|         mSearchView.setOnQueryTextListener(mSearchViewOnQueryTextListener); |  | ||||||
|         mSearchView.setOnStateChangeListener(mSearchViewOnStateChangeListener); |  | ||||||
|  |  | ||||||
|         mListView.setEmptyView(mainView.findViewById(R.id.afc_empty_view)); |  | ||||||
|         mListView.setOnChildClickListener(mListViewOnChildClickListener); |  | ||||||
|         mListView.setOnItemLongClickListener(mListViewOnItemLongClickListener); |  | ||||||
|         initListViewGestureListener(); |  | ||||||
|  |  | ||||||
|         mHistoryCursorAdapter = new HistoryCursorAdapter(getActivity()); |  | ||||||
|         mListView.setAdapter(mHistoryCursorAdapter); |  | ||||||
|  |  | ||||||
|         /* |  | ||||||
|          * Default states of button navigators in XML are disabled, so we just |  | ||||||
|          * set their listeners here. |  | ||||||
|          */ |  | ||||||
|         for (View v : new View[] { mBtnNext, mBtnPrev }) |  | ||||||
|             v.setOnTouchListener(mBtnNextPrevOnTouchListener); |  | ||||||
|  |  | ||||||
|         return mainView; |  | ||||||
|     }// initContentView() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * As the name means. |  | ||||||
|      */ |  | ||||||
|     private void initListViewGestureListener() { |  | ||||||
|         GestureUtils.setupGestureDetector(mListView, |  | ||||||
|                 new GestureUtils.SimpleOnGestureListener() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public boolean onFling(View view, Object data, |  | ||||||
|                             FlingDirection flingDirection) { |  | ||||||
|                         if (!(data instanceof Cursor)) |  | ||||||
|                             return false; |  | ||||||
|  |  | ||||||
|                         List<Integer> ids = new ArrayList<Integer>(); |  | ||||||
|  |  | ||||||
|                         final int historyId = ((Cursor) data) |  | ||||||
|                                 .getInt(((Cursor) data) |  | ||||||
|                                         .getColumnIndex(HistoryContract._ID)); |  | ||||||
|                         if (mHistoryCursorAdapter.isSelected(historyId)) |  | ||||||
|                             ids.addAll(mHistoryCursorAdapter |  | ||||||
|                                     .getSelectedItemIds()); |  | ||||||
|                         else |  | ||||||
|                             ids.add(historyId); |  | ||||||
|  |  | ||||||
|                         if (ids.size() <= 1) |  | ||||||
|                             mHistoryCursorAdapter.markItemAsDeleted(historyId, |  | ||||||
|                                     true); |  | ||||||
|                         else |  | ||||||
|                             mHistoryCursorAdapter |  | ||||||
|                                     .markSelectedItemsAsDeleted(true); |  | ||||||
|  |  | ||||||
|                         final StringBuilder sb = new StringBuilder(String |  | ||||||
|                                 .format("%s in (", |  | ||||||
|                                         DbUtils.SQLITE_FTS_COLUMN_ROW_ID)); |  | ||||||
|                         for (int id : ids) |  | ||||||
|                             sb.append(Integer.toString(id)).append(','); |  | ||||||
|                         sb.setCharAt(sb.length() - 1, ')'); |  | ||||||
|  |  | ||||||
|                         new Handler().postDelayed(new Runnable() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void run() { |  | ||||||
|                                 getActivity().getContentResolver().delete( |  | ||||||
|                                         HistoryContract |  | ||||||
|                                                 .genContentUri(getActivity()), |  | ||||||
|                                         sb.toString(), null); |  | ||||||
|                             } |  | ||||||
|                         }, DisplayPrefs.DELAY_TIME_FOR_VERY_SHORT_ANIMATION); |  | ||||||
|  |  | ||||||
|                         return true; |  | ||||||
|                     }// onFling() |  | ||||||
|                 }); |  | ||||||
|     }// initListViewGestureListener() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Enables/ disables search view, button navigators' listeners (the |  | ||||||
|      * listeners are DB querying related)... |  | ||||||
|      *  |  | ||||||
|      * @param enabled |  | ||||||
|      *            {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     private void enableControls(boolean enabled) { |  | ||||||
|         /* |  | ||||||
|          * If the user is typing, disabling search view will turn off the |  | ||||||
|          * keyboard. So don't do that. |  | ||||||
|          */ |  | ||||||
|         // mSearchView.setEnabled(enabled); |  | ||||||
|  |  | ||||||
|         for (View v : new View[] { mBtnNext, mBtnPrev }) { |  | ||||||
|             v.setOnClickListener(enabled ? mBtnNextPrevOnClickListener : null); |  | ||||||
|             v.setOnLongClickListener(enabled ? mBtnNextPrevOnLongClickListener |  | ||||||
|                     : null); |  | ||||||
|         } |  | ||||||
|     }// enableButtonNavigatorsListeners() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Asks user to confirm to clear history. |  | ||||||
|      */ |  | ||||||
|     private void doConfirmClearHistory() { |  | ||||||
|         Dlg.confirmYesno(getActivity(), |  | ||||||
|                 getString(R.string.afc_msg_confirm_clear_history), |  | ||||||
|                 new DialogInterface.OnClickListener() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public void onClick(DialogInterface arg0, int arg1) { |  | ||||||
|                         getActivity().getContentResolver().delete( |  | ||||||
|                                 HistoryContract.genContentUri(getActivity()), |  | ||||||
|                                 null, null); |  | ||||||
|                         if (getDialog() != null) |  | ||||||
|                             getDialog().dismiss(); |  | ||||||
|                     }// onClick() |  | ||||||
|                 }); |  | ||||||
|     }// doConfirmClearHistory() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Checks if the search view is on or off. |  | ||||||
|      *  |  | ||||||
|      * @return {@code true} or {@code false}. |  | ||||||
|      */ |  | ||||||
|     private boolean isSearchViewOn() { |  | ||||||
|         return mSearchView.getVisibility() == View.VISIBLE |  | ||||||
|                 && !mSearchView.isIconified(); |  | ||||||
|     }// isSearchViewShowing() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Shows search view and opens up search components. |  | ||||||
|      */ |  | ||||||
|     private void switchOnSearchView() { |  | ||||||
|         if (mBtnSearch != null) |  | ||||||
|             mBtnSearch.setVisibility(View.GONE); |  | ||||||
|  |  | ||||||
|         mSearchView.setVisibility(View.VISIBLE); |  | ||||||
|         if (mSearchView.isIconified()) |  | ||||||
|             mSearchView.open(); |  | ||||||
|     }// switchOnSearchView() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Hides the search view and closes its components. |  | ||||||
|      */ |  | ||||||
|     private void switchOffSearchView() { |  | ||||||
|         if (mBtnSearch != null) |  | ||||||
|             mBtnSearch.setVisibility(View.VISIBLE); |  | ||||||
|  |  | ||||||
|         mSearchView.setVisibility(View.GONE); |  | ||||||
|         if (!mSearchView.isIconified()) |  | ||||||
|             mSearchView.close(); |  | ||||||
|     }// switchOffSearchView() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * LISTENERS |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     private final Runnable mViewLoadingShower = new Runnable() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void run() { |  | ||||||
|             if (isAdded()) { |  | ||||||
|                 mViewGroupListView.setVisibility(View.GONE); |  | ||||||
|                 mViewLoading.setVisibility(View.VISIBLE); |  | ||||||
|             } |  | ||||||
|         }// run() |  | ||||||
|     };// mViewLoadingShower |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Sets {@code listener}. |  | ||||||
|      *  |  | ||||||
|      * @param listener |  | ||||||
|      *            {@link OnHistoryItemClickListener}. |  | ||||||
|      */ |  | ||||||
|     public void setOnHistoryItemClickListener( |  | ||||||
|             OnHistoryItemClickListener listener) { |  | ||||||
|         mOnHistoryItemClickListener = listener; |  | ||||||
|     }// setOnHistoryItemClickListener() |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Gets an {@link OnHistoryItemClickListener}. |  | ||||||
|      *  |  | ||||||
|      * @return the listener. |  | ||||||
|      */ |  | ||||||
|     public OnHistoryItemClickListener getOnHistoryItemClickListener() { |  | ||||||
|         return mOnHistoryItemClickListener; |  | ||||||
|     }// getOnHistoryItemClickListener() |  | ||||||
|  |  | ||||||
|     /* |  | ||||||
|      * CONTROLS' LISTENERS. |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Handles when user presses the search key, then opens up search view. |  | ||||||
|      */ |  | ||||||
|     private final DialogInterface.OnKeyListener mDialogOnKeyListener = new DialogInterface.OnKeyListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { |  | ||||||
|             if (keyCode == KeyEvent.KEYCODE_SEARCH) { |  | ||||||
|                 if (event.getAction() == KeyEvent.ACTION_UP) { |  | ||||||
|                     if (isSearchViewOn()) |  | ||||||
|                         switchOffSearchView(); |  | ||||||
|                     else |  | ||||||
|                         switchOnSearchView(); |  | ||||||
|                 } |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return false; |  | ||||||
|         }// onKey() |  | ||||||
|     };// mDialogOnKeyListener |  | ||||||
|  |  | ||||||
|     private final View.OnClickListener mBtnSearchOnClickListener = new View.OnClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onClick(View v) { |  | ||||||
|             switchOnSearchView(); |  | ||||||
|         }// onClick() |  | ||||||
|     };// mBtnSearchOnClickListener |  | ||||||
|  |  | ||||||
|     private final AfcSearchView.OnQueryTextListener mSearchViewOnQueryTextListener = new AfcSearchView.OnQueryTextListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onQueryTextSubmit(String query) { |  | ||||||
|             if (!isAdded()) |  | ||||||
|                 return; |  | ||||||
|  |  | ||||||
|             try { |  | ||||||
|                 mHistoryCursorAdapter.setSearchText(query != null ? query |  | ||||||
|                         .trim() : null); |  | ||||||
|                 /* |  | ||||||
|                  * Sets total item count to -1, then restarts the counter, it |  | ||||||
|                  * will restart the data loader. |  | ||||||
|                  */ |  | ||||||
|                 mItemCount = -1; |  | ||||||
|                 getLoaderManager().restartLoader(mLoaderIdHistoryCounter, null, |  | ||||||
|                         HistoryFragment.this); |  | ||||||
|             } catch (Throwable t) { |  | ||||||
|                 Log.e(CLASSNAME, "onQueryTextSubmit() >> " + t); |  | ||||||
|                 t.printStackTrace(); |  | ||||||
|             } |  | ||||||
|         }// onQueryTextSubmit() |  | ||||||
|     };// mSearchViewOnQueryTextListener |  | ||||||
|  |  | ||||||
|     private final AfcSearchView.OnStateChangeListener mSearchViewOnStateChangeListener = new AfcSearchView.OnStateChangeListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onOpen() { |  | ||||||
|             // do nothing |  | ||||||
|         }// onOpen() |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onClose() { |  | ||||||
|             switchOffSearchView(); |  | ||||||
|  |  | ||||||
|             if (!TextUtils.isEmpty(mHistoryCursorAdapter.getSearchText()) |  | ||||||
|                     || !TextUtils.isEmpty(mSearchView.getSearchText())) { |  | ||||||
|                 mHistoryCursorAdapter.setSearchText(null); |  | ||||||
|                 /* |  | ||||||
|                  * Sets total item count to -1, then restarts the counter, it |  | ||||||
|                  * will restart the data loader. |  | ||||||
|                  */ |  | ||||||
|                 mItemCount = -1; |  | ||||||
|                 getLoaderManager().restartLoader(mLoaderIdHistoryCounter, null, |  | ||||||
|                         HistoryFragment.this); |  | ||||||
|             } |  | ||||||
|         }// onClose() |  | ||||||
|     };// mSearchViewOnStateChangeListener |  | ||||||
|  |  | ||||||
|     private final View.OnClickListener mBtnNextPrevOnClickListener = new View.OnClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public void onClick(View v) { |  | ||||||
|             Ui.showSoftKeyboard(mSearchView, false); |  | ||||||
|  |  | ||||||
|             if (v.getId() == R.id.afc_button_go_forward) |  | ||||||
|                 mCurrentPage++; |  | ||||||
|             else if (v.getId() == R.id.afc_button_go_back) |  | ||||||
|                 mCurrentPage--; |  | ||||||
|             getLoaderManager().restartLoader(mLoaderIdHistoryData, null, |  | ||||||
|                     HistoryFragment.this); |  | ||||||
|         }// onClick() |  | ||||||
|     };// mBtnNextPrevOnClickListener |  | ||||||
|  |  | ||||||
|     private final View.OnLongClickListener mBtnNextPrevOnLongClickListener = new View.OnLongClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onLongClick(View v) { |  | ||||||
|             Ui.showSoftKeyboard(mSearchView, false); |  | ||||||
|  |  | ||||||
|             if (v.getId() == R.id.afc_button_go_forward) |  | ||||||
|                 mCurrentPage = Integer.MAX_VALUE; |  | ||||||
|             else if (v.getId() == R.id.afc_button_go_back) |  | ||||||
|                 mCurrentPage = 0; |  | ||||||
|  |  | ||||||
|             getLoaderManager().restartLoader(mLoaderIdHistoryData, null, |  | ||||||
|                     HistoryFragment.this); |  | ||||||
|  |  | ||||||
|             return true; |  | ||||||
|         }// onLongClick() |  | ||||||
|     };// mBtnNextPrevOnLongClickListener |  | ||||||
|  |  | ||||||
|     private final View.OnTouchListener mBtnNextPrevOnTouchListener = new View.OnTouchListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onTouch(View v, MotionEvent event) { |  | ||||||
|             if (event.getAction() == MotionEvent.ACTION_UP) { |  | ||||||
|                 v.postDelayed(new Runnable() { |  | ||||||
|  |  | ||||||
|                     @Override |  | ||||||
|                     public void run() { |  | ||||||
|                         if (BuildConfig.DEBUG) |  | ||||||
|                             Log.d(CLASSNAME, "BtnNextPrev -- TOUCH ACTION_UP"); |  | ||||||
|                         if (isAdded()) { |  | ||||||
|                             mBtnNext.setEnabled(mCurrentPage < mPageCount - 1); |  | ||||||
|                             mBtnPrev.setEnabled(mCurrentPage > 0); |  | ||||||
|                         } |  | ||||||
|                     }// run() |  | ||||||
|                 }, DisplayPrefs.DELAY_TIME_FOR_VERY_SHORT_ANIMATION); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return false; |  | ||||||
|         }// onTouch() |  | ||||||
|     };// mBtnNextPrevOnTouchListener |  | ||||||
|  |  | ||||||
|     private final ExpandableListView.OnChildClickListener mListViewOnChildClickListener = new ExpandableListView.OnChildClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onChildClick(ExpandableListView parent, View v, |  | ||||||
|                 int groupPosition, int childPosition, long id) { |  | ||||||
|             if (getOnHistoryItemClickListener() != null) { |  | ||||||
|                 Cursor cursor = mHistoryCursorAdapter.getChild(groupPosition, |  | ||||||
|                         childPosition); |  | ||||||
|                 getOnHistoryItemClickListener() |  | ||||||
|                         .onItemClick( |  | ||||||
|                                 cursor.getString(cursor |  | ||||||
|                                         .getColumnIndex(HistoryContract.COLUMN_PROVIDER_ID)), |  | ||||||
|                                 Uri.parse(cursor.getString(cursor |  | ||||||
|                                         .getColumnIndex(HistoryContract.COLUMN_URI)))); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (getDialog() != null) |  | ||||||
|                 getDialog().dismiss(); |  | ||||||
|  |  | ||||||
|             return true; |  | ||||||
|         }// onChildClick() |  | ||||||
|     };// mListViewOnChildClickListener |  | ||||||
|  |  | ||||||
|     private final AdapterView.OnItemLongClickListener mListViewOnItemLongClickListener = new AdapterView.OnItemLongClickListener() { |  | ||||||
|  |  | ||||||
|         @Override |  | ||||||
|         public boolean onItemLongClick(AdapterView<?> parent, View view, |  | ||||||
|                 int position, long id) { |  | ||||||
|             switch (ExpandableListView.getPackedPositionType(id)) { |  | ||||||
|             case ExpandableListView.PACKED_POSITION_TYPE_GROUP: |  | ||||||
|                 final int iGroup = ExpandableListView |  | ||||||
|                         .getPackedPositionGroup(mListView |  | ||||||
|                                 .getExpandableListPosition(position)); |  | ||||||
|                 if (!mListView.isGroupExpanded(iGroup)) |  | ||||||
|                     return false; |  | ||||||
|  |  | ||||||
|                 if (BuildConfig.DEBUG) |  | ||||||
|                     Log.d(CLASSNAME, String.format( |  | ||||||
|                             "onItemLongClick() -- group = %,d", iGroup)); |  | ||||||
|                 ContextMenuUtils.showContextMenu(getActivity(), 0, |  | ||||||
|                         R.string.afc_title_advanced_selection, |  | ||||||
|                         HistoryCursorAdapter.ADVANCED_SELECTION_OPTIONS, |  | ||||||
|                         new ContextMenuUtils.OnMenuItemClickListener() { |  | ||||||
|  |  | ||||||
|                             @Override |  | ||||||
|                             public void onClick(final int resId) { |  | ||||||
|                                 if (resId == R.string.afc_cmd_advanced_selection_all) |  | ||||||
|                                     mHistoryCursorAdapter.selectAll(iGroup, |  | ||||||
|                                             true); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_none) |  | ||||||
|                                     mHistoryCursorAdapter.selectAll(iGroup, |  | ||||||
|                                             false); |  | ||||||
|                                 else if (resId == R.string.afc_cmd_advanced_selection_invert) |  | ||||||
|                                     mHistoryCursorAdapter |  | ||||||
|                                             .invertSelection(iGroup); |  | ||||||
|                             }// onClick() |  | ||||||
|                         }); |  | ||||||
|  |  | ||||||
|                 return true;// PACKED_POSITION_TYPE_GROUP |  | ||||||
|  |  | ||||||
|             case ExpandableListView.PACKED_POSITION_TYPE_CHILD: |  | ||||||
|                 return false;// PACKED_POSITION_TYPE_CHILD |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return false; |  | ||||||
|         }// onItemLongClick() |  | ||||||
|     };// mListViewOnItemLongClickListener |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll