diff --git a/bin/EhViewer.apk b/bin/EhViewer.apk index 93b1693d1..09ef88835 100644 Binary files a/bin/EhViewer.apk and b/bin/EhViewer.apk differ diff --git a/bin/R.txt b/bin/R.txt index 39a5d1ccf..ec15aefcd 100644 --- a/bin/R.txt +++ b/bin/R.txt @@ -60,6 +60,12 @@ int color unknown_bg 0x7f08000e int color western_bg 0x7f080008 int dimen activity_horizontal_margin 0x7f090000 int dimen activity_vertical_margin 0x7f090001 +int dimen button_size 0x7f09000b +int dimen button_small_padding_x 0x7f09000d +int dimen button_small_padding_y 0x7f09000e +int dimen button_small_size 0x7f09000c +int dimen button_tag_padding_x 0x7f09000f +int dimen button_tag_padding_y 0x7f090010 int dimen detail_subtitle_size 0x7f09000a int dimen detail_thumb_height 0x7f090008 int dimen detail_thumb_width 0x7f090007 @@ -118,193 +124,196 @@ int drawable unknown 0x7f02002d int drawable welcome 0x7f02002e int drawable western 0x7f02002f int drawable white_bn_bg 0x7f020030 -int id action 0x7f060034 -int id action_download 0x7f060084 -int id action_favourite 0x7f060083 -int id action_jump 0x7f060087 -int id action_refresh 0x7f060086 -int id action_search 0x7f060085 -int id action_settings 0x7f060088 -int id app_start_view 0x7f060081 -int id autoCompleteTextView1 0x7f06007d +int id action 0x7f060036 +int id action_download 0x7f060086 +int id action_favourite 0x7f060085 +int id action_jump 0x7f060089 +int id action_refresh 0x7f060088 +int id action_search 0x7f060087 +int id action_settings 0x7f06008a +int id app_start_view 0x7f060083 +int id autoCompleteTextView1 0x7f06007f int id bottom 0x7f06000f -int id bottom_panel 0x7f06006f -int id button_artistcg 0x7f060038 -int id button_asianporn 0x7f06003e -int id button_check_login 0x7f060067 -int id button_cosplay 0x7f06003d -int id button_doujinshi 0x7f060036 -int id button_gamecg 0x7f060039 -int id button_imageset 0x7f06003c -int id button_login 0x7f060066 -int id button_manga 0x7f060037 -int id button_misc 0x7f06003f -int id button_non_h 0x7f06003b -int id button_western 0x7f06003a -int id category 0x7f06005c +int id bottom_panel 0x7f060071 +int id button_artistcg 0x7f06003a +int id button_asianporn 0x7f060040 +int id button_check_login 0x7f060069 +int id button_cosplay 0x7f06003f +int id button_doujinshi 0x7f060038 +int id button_gamecg 0x7f06003b +int id button_imageset 0x7f06003e +int id button_login 0x7f060068 +int id button_manga 0x7f060039 +int id button_misc 0x7f060041 +int id button_non_h 0x7f06003d +int id button_root 0x7f060011 +int id button_western 0x7f06003c +int id category 0x7f06005e int id center 0x7f06000b int id centerCrop 0x7f06000c int id centerInside 0x7f06000d -int id checkbox_advance 0x7f060041 -int id checkbox_sdesc 0x7f060045 -int id checkbox_sdt1 0x7f060048 -int id checkbox_sdt2 0x7f060049 -int id checkbox_sh 0x7f06004a -int id checkbox_sname 0x7f060043 -int id checkbox_sr 0x7f06004b -int id checkbox_stags 0x7f060044 -int id checkbox_sto 0x7f060047 -int id checkbox_storr 0x7f060046 -int id cover 0x7f060058 -int id custom 0x7f06002b -int id detail_average_people 0x7f06001e -int id detail_button_cancel 0x7f060024 -int id detail_button_every 0x7f060026 -int id detail_button_known 0x7f060027 -int id detail_button_once 0x7f060025 -int id detail_category 0x7f060015 -int id detail_cover 0x7f060012 -int id detail_do_rate 0x7f060016 -int id detail_language 0x7f060020 -int id detail_pages_size 0x7f060021 -int id detail_posted 0x7f06001f -int id detail_rate 0x7f06001d -int id detail_read 0x7f060017 -int id detail_refresh 0x7f06001c -int id detail_title 0x7f060013 -int id detail_uploader 0x7f060014 -int id detail_wait 0x7f06001b -int id download 0x7f060030 -int id drawer_login 0x7f060060 -int id drawer_login_over 0x7f060061 -int id favourite 0x7f060035 -int id filter_advance 0x7f060042 +int id checkbox_advance 0x7f060043 +int id checkbox_sdesc 0x7f060047 +int id checkbox_sdt1 0x7f06004a +int id checkbox_sdt2 0x7f06004b +int id checkbox_sh 0x7f06004c +int id checkbox_sname 0x7f060045 +int id checkbox_sr 0x7f06004d +int id checkbox_stags 0x7f060046 +int id checkbox_sto 0x7f060049 +int id checkbox_storr 0x7f060048 +int id cover 0x7f06005a +int id custom 0x7f06002d +int id detail_average_people 0x7f060020 +int id detail_average_people_bak 0x7f060021 +int id detail_button_cancel 0x7f060027 +int id detail_button_every 0x7f060029 +int id detail_button_known 0x7f06002a +int id detail_button_once 0x7f060028 +int id detail_category 0x7f060017 +int id detail_cover 0x7f060014 +int id detail_do_rate 0x7f060018 +int id detail_language 0x7f060023 +int id detail_pages_size 0x7f060024 +int id detail_posted 0x7f060022 +int id detail_rate 0x7f06001f +int id detail_read 0x7f060019 +int id detail_refresh 0x7f06001e +int id detail_title 0x7f060015 +int id detail_uploader 0x7f060016 +int id detail_wait 0x7f06001d +int id download 0x7f060032 +int id drawer_login 0x7f060062 +int id drawer_login_over 0x7f060063 +int id favourite 0x7f060037 +int id filter_advance 0x7f060044 int id fitCenter 0x7f060009 int id fitEnd 0x7f06000a int id fitStart 0x7f060008 int id fitXY 0x7f060007 -int id footer_progressBar 0x7f060073 -int id footer_tip_text 0x7f060074 +int id footer_progressBar 0x7f060075 +int id footer_tip_text 0x7f060076 int id fullscreen 0x7f060003 -int id gl_root_view 0x7f06004e -int id head_arrowImageView 0x7f060079 -int id head_contentLayout 0x7f060078 -int id head_progressBar 0x7f06007a -int id head_tipsTextView 0x7f06007b -int id header 0x7f060071 -int id header_arrow_image 0x7f060075 -int id header_progressBar 0x7f060076 -int id header_tip_text 0x7f060077 -int id info 0x7f060033 -int id is_exhentai 0x7f060062 +int id gl_root_view 0x7f060050 +int id head_arrowImageView 0x7f06007b +int id head_contentLayout 0x7f06007a +int id head_progressBar 0x7f06007c +int id head_tipsTextView 0x7f06007d +int id header 0x7f060073 +int id header_arrow_image 0x7f060077 +int id header_progressBar 0x7f060078 +int id header_tip_text 0x7f060079 +int id info 0x7f060035 +int id is_exhentai 0x7f060064 int id left 0x7f060000 -int id list 0x7f06002c -int id list_button_logout 0x7f06006a -int id list_jump_edit 0x7f060051 -int id list_jump_sum 0x7f06004f -int id list_jump_to 0x7f060050 -int id list_list 0x7f060053 -int id list_main 0x7f060052 -int id list_menu_list 0x7f06005e -int id list_menu_login 0x7f06005f -int id list_no_found 0x7f060057 -int id list_refresh 0x7f060055 -int id list_view 0x7f060072 -int id list_wait_first 0x7f060054 -int id list_wait_login 0x7f060068 -int id list_wait_logout 0x7f06006b -int id main 0x7f06004d -int id manga_detail 0x7f060011 -int id manga_detail_normal 0x7f060018 -int id manga_detail_offensive 0x7f060019 -int id manga_detail_pining 0x7f06001a -int id manga_detail_scrollview 0x7f060010 +int id list 0x7f06002e +int id list_button_logout 0x7f06006c +int id list_jump_edit 0x7f060053 +int id list_jump_sum 0x7f060051 +int id list_jump_to 0x7f060052 +int id list_list 0x7f060055 +int id list_main 0x7f060054 +int id list_menu_list 0x7f060060 +int id list_menu_login 0x7f060061 +int id list_no_found 0x7f060059 +int id list_refresh 0x7f060057 +int id list_view 0x7f060074 +int id list_wait_first 0x7f060056 +int id list_wait_login 0x7f06006a +int id list_wait_logout 0x7f06006d +int id main 0x7f06004f +int id manga_detail 0x7f060013 +int id manga_detail_normal 0x7f06001a +int id manga_detail_offensive 0x7f06001b +int id manga_detail_pining 0x7f06001c +int id manga_detail_scrollview 0x7f060012 int id margin 0x7f060002 int id matrix 0x7f060006 -int id message 0x7f06002a -int id name 0x7f060059 -int id negative_button 0x7f06002d -int id neutral_button 0x7f06002e +int id message 0x7f06002c +int id name 0x7f06005b +int id negative_button 0x7f06002f +int id neutral_button 0x7f060030 int id none 0x7f060004 -int id page_list 0x7f060023 -int id pager 0x7f060065 -int id paper_list_layout 0x7f06006c -int id paper_list_wait 0x7f06006d -int id password 0x7f060064 -int id positive_button 0x7f06002f -int id posted 0x7f06005d -int id preview_button_refresh 0x7f06006e -int id preview_num 0x7f060070 -int id progressBar 0x7f060032 -int id rate 0x7f06005b -int id remove 0x7f06007e +int id page_list 0x7f060026 +int id pager 0x7f060067 +int id paper_list_layout 0x7f06006e +int id paper_list_wait 0x7f06006f +int id password 0x7f060066 +int id positive_button 0x7f060031 +int id posted 0x7f06005f +int id preview_button_refresh 0x7f060070 +int id preview_num 0x7f060072 +int id progressBar 0x7f060034 +int id rate 0x7f06005d +int id remove 0x7f060080 int id right 0x7f060001 -int id sadpanda 0x7f060056 -int id scroll_view 0x7f060029 -int id search_bar 0x7f06007c -int id search_text 0x7f060040 +int id sadpanda 0x7f060058 +int id scroll_view 0x7f06002b +int id search_bar 0x7f06007e +int id search_text 0x7f060042 int id selected_view 0x7f060005 -int id set_name_edit 0x7f06007f -int id slidingmenumain 0x7f060080 -int id spinner_min_rating 0x7f06004c -int id tags_layout 0x7f060022 -int id text_username 0x7f060069 -int id thumb 0x7f060031 -int id title 0x7f060028 +int id set_name_edit 0x7f060081 +int id slidingmenumain 0x7f060082 +int id spinner_min_rating 0x7f06004e +int id tags_layout 0x7f060025 +int id text_username 0x7f06006b +int id thumb 0x7f060033 +int id title 0x7f060010 int id top 0x7f06000e -int id uploader 0x7f06005a -int id username 0x7f060063 -int id wait_message 0x7f060082 -int layout detail 0x7f030000 -int layout detail_normal 0x7f030001 -int layout detail_offensive 0x7f030002 -int layout detail_pining 0x7f030003 -int layout dialog 0x7f030004 -int layout download 0x7f030005 -int layout download_item 0x7f030006 -int layout favourite 0x7f030007 -int layout filter 0x7f030008 -int layout gl_root_group 0x7f030009 -int layout jump 0x7f03000a -int layout list 0x7f03000b -int layout list_item 0x7f03000c -int layout list_item_text 0x7f03000d -int layout list_menu_list 0x7f03000e -int layout list_menu_login 0x7f03000f -int layout login 0x7f030010 -int layout manga 0x7f030011 -int layout menu_item 0x7f030012 -int layout menu_login 0x7f030013 -int layout menu_login_over 0x7f030014 -int layout page_list 0x7f030015 -int layout page_list_panel 0x7f030016 -int layout pull_list_view 0x7f030017 -int layout pull_list_view_footer 0x7f030018 -int layout pull_list_view_header 0x7f030019 -int layout pull_to_refresh_head 0x7f03001a -int layout search_view 0x7f03001b -int layout set_name 0x7f03001c -int layout slidingmenumain 0x7f03001d -int layout start 0x7f03001e -int layout wait 0x7f03001f +int id uploader 0x7f06005c +int id username 0x7f060065 +int id wait_message 0x7f060084 +int layout buttons_dialog 0x7f030000 +int layout detail 0x7f030001 +int layout detail_normal 0x7f030002 +int layout detail_offensive 0x7f030003 +int layout detail_pining 0x7f030004 +int layout dialog 0x7f030005 +int layout download 0x7f030006 +int layout download_item 0x7f030007 +int layout favourite 0x7f030008 +int layout filter 0x7f030009 +int layout gl_root_group 0x7f03000a +int layout jump 0x7f03000b +int layout list 0x7f03000c +int layout list_item 0x7f03000d +int layout list_item_text 0x7f03000e +int layout list_menu_list 0x7f03000f +int layout list_menu_login 0x7f030010 +int layout login 0x7f030011 +int layout manga 0x7f030012 +int layout menu_item 0x7f030013 +int layout menu_login 0x7f030014 +int layout menu_login_over 0x7f030015 +int layout page_list 0x7f030016 +int layout page_list_panel 0x7f030017 +int layout pull_list_view 0x7f030018 +int layout pull_list_view_footer 0x7f030019 +int layout pull_list_view_header 0x7f03001a +int layout pull_to_refresh_head 0x7f03001b +int layout search_view 0x7f03001c +int layout set_name 0x7f03001d +int layout slidingmenumain 0x7f03001e +int layout start 0x7f03001f +int layout wait 0x7f030020 int menu detail 0x7f0c0000 int menu main 0x7f0c0001 int raw change_log 0x7f050000 int raw thanks 0x7f050001 -int string _default 0x7f0a00b0 -int string action_refresh 0x7f0a005c -int string action_settings 0x7f0a005d -int string actual_size 0x7f0a00b8 -int string add 0x7f0a00ac -int string add_tag 0x7f0a0079 -int string add_to_favourite 0x7f0a00c2 -int string advance_search_left 0x7f0a00c8 +int string _default 0x7f0a00b3 +int string action_refresh 0x7f0a005f +int string action_settings 0x7f0a0060 +int string actual_size 0x7f0a00bb +int string add 0x7f0a00af +int string add_tag 0x7f0a007c +int string add_to_favourite 0x7f0a00c5 +int string advance_search_left 0x7f0a00cb int string app_name 0x7f0a0000 -int string bottom_left 0x7f0a00bf -int string bottom_right 0x7f0a00c0 -int string cache_large 0x7f0a0073 -int string center 0x7f0a00c1 -int string changelog 0x7f0a00a5 +int string bottom_left 0x7f0a00c2 +int string bottom_right 0x7f0a00c3 +int string cache_large 0x7f0a0076 +int string center 0x7f0a00c4 +int string changelog 0x7f0a00a8 int string check_login 0x7f0a000c int string checkbox_advance 0x7f0a0015 int string checkbox_sdesc 0x7f0a0018 @@ -317,7 +326,7 @@ int string checkbox_stags 0x7f0a0017 int string checkbox_sto 0x7f0a001a int string checkbox_storr 0x7f0a0019 int string checking_update 0x7f0a002c -int string create_cache_error 0x7f0a0075 +int string create_cache_error 0x7f0a0078 int string dailog_check_network 0x7f0a0007 int string dailog_network_error_no 0x7f0a0009 int string dailog_network_error_yes 0x7f0a0008 @@ -325,7 +334,7 @@ int string dailog_waring_no 0x7f0a0006 int string dailog_waring_plain 0x7f0a0004 int string dailog_waring_title 0x7f0a0003 int string dailog_waring_yes 0x7f0a0005 -int string detail_average 0x7f0a00c9 +int string detail_average 0x7f0a00cc int string detail_button_cancel 0x7f0a0036 int string detail_button_every 0x7f0a0038 int string detail_button_known 0x7f0a003a @@ -335,10 +344,10 @@ int string detail_not_rated 0x7f0a003c int string detail_offensive 0x7f0a0035 int string detail_offensive_title 0x7f0a0034 int string detail_pages_size 0x7f0a0032 -int string detail_people 0x7f0a00ca +int string detail_people 0x7f0a00cd int string detail_pining 0x7f0a0039 int string detail_preview_error 0x7f0a003b -int string develop 0x7f0a00c7 +int string develop 0x7f0a00ca int string dialog_messgae_login_or_not 0x7f0a0010 int string dialog_send_crash_no 0x7f0a0025 int string dialog_send_crash_plain 0x7f0a0023 @@ -346,131 +355,132 @@ int string dialog_send_crash_title 0x7f0a0022 int string dialog_send_crash_yes 0x7f0a0024 int string dialog_title_login_or_not 0x7f0a000f int string dialog_wait_send_crash_msg 0x7f0a000a -int string download 0x7f0a00b3 -int string download_successfully 0x7f0a0094 -int string download_task_finished 0x7f0a0092 -int string download_unsuccessfully 0x7f0a0095 +int string download 0x7f0a00b6 +int string download_successfully 0x7f0a0097 +int string download_task_finished 0x7f0a0095 +int string download_unsuccessfully 0x7f0a0098 int string download_update 0x7f0a0030 -int string downloading 0x7f0a0093 +int string downloading 0x7f0a0096 int string drawer_close 0x7f0a0002 int string drawer_open 0x7f0a0001 -int string em_can_not_reach 0x7f0a0053 -int string em_check_login_error 0x7f0a004c -int string em_client_protocol 0x7f0a0048 -int string em_host_error 0x7f0a0059 -int string em_invalid_request 0x7f0a005a -int string em_login_error 0x7f0a004b -int string em_logout_error 0x7f0a004d -int string em_network_error 0x7f0a0042 -int string em_no_network 0x7f0a0052 -int string em_no_network_2 0x7f0a0054 -int string em_no_sdcard 0x7f0a005b -int string em_open_input_stream_error 0x7f0a0046 -int string em_parser_error 0x7f0a0045 -int string em_put_cache_error 0x7f0a0049 -int string em_read_input_stream_error 0x7f0a0047 -int string em_redirection_error 0x7f0a0058 -int string em_request_error 0x7f0a0055 -int string em_response_code_error 0x7f0a0044 -int string em_retry 0x7f0a004f -int string em_retry_times 0x7f0a0050 -int string em_timeout 0x7f0a0043 -int string em_unexpected_response_code 0x7f0a0057 -int string em_unknown_error 0x7f0a0051 -int string em_unknown_host 0x7f0a0056 -int string em_url_error 0x7f0a004e -int string em_url_format_error 0x7f0a004a -int string error 0x7f0a00a4 +int string em_can_not_reach 0x7f0a0056 +int string em_check_login_error 0x7f0a004f +int string em_client_protocol 0x7f0a004b +int string em_host_error 0x7f0a005c +int string em_invalid_request 0x7f0a005d +int string em_login_error 0x7f0a004e +int string em_logout_error 0x7f0a0050 +int string em_network_error 0x7f0a0045 +int string em_no_network 0x7f0a0055 +int string em_no_network_2 0x7f0a0057 +int string em_no_sdcard 0x7f0a005e +int string em_open_input_stream_error 0x7f0a0049 +int string em_parser_error 0x7f0a0048 +int string em_put_cache_error 0x7f0a004c +int string em_read_input_stream_error 0x7f0a004a +int string em_redirection_error 0x7f0a005b +int string em_request_error 0x7f0a0058 +int string em_response_code_error 0x7f0a0047 +int string em_retry 0x7f0a0052 +int string em_retry_times 0x7f0a0053 +int string em_timeout 0x7f0a0046 +int string em_unexpected_response_code 0x7f0a005a +int string em_unknown_error 0x7f0a0054 +int string em_unknown_host 0x7f0a0059 +int string em_url_error 0x7f0a0051 +int string em_url_format_error 0x7f0a004d +int string error 0x7f0a00a7 int string exit_tip 0x7f0a000b -int string favourite 0x7f0a00b2 -int string first_page 0x7f0a003e -int string fit_to_height 0x7f0a00ba -int string fit_to_screen 0x7f0a00bb -int string fit_to_width 0x7f0a00b9 -int string fixed_scale 0x7f0a00bc -int string footer_fail 0x7f0a0090 -int string footer_loaded 0x7f0a008f -int string footer_loading 0x7f0a008e +int string favourite 0x7f0a00b5 +int string first_page 0x7f0a0041 +int string fit_to_height 0x7f0a00bd +int string fit_to_screen 0x7f0a00be +int string fit_to_width 0x7f0a00bc +int string fixed_scale 0x7f0a00bf +int string footer_fail 0x7f0a0093 +int string footer_loaded 0x7f0a0092 +int string footer_loading 0x7f0a0091 int string found_update 0x7f0a002e int string hint_no_keyword 0x7f0a0014 -int string homepage 0x7f0a00b1 -int string input_error 0x7f0a0074 -int string jump 0x7f0a00ae +int string homepage 0x7f0a00b4 +int string input_error 0x7f0a0077 +int string jump 0x7f0a00b1 int string jump_sum 0x7f0a001f int string jump_to 0x7f0a0020 -int string landscape 0x7f0a0061 -int string last_page 0x7f0a009f +int string landscape 0x7f0a0064 +int string last_page 0x7f0a00a2 int string list_title 0x7f0a0029 -int string load_pre 0x7f0a003d -int string login 0x7f0a00a7 -int string logout 0x7f0a00a8 -int string menu 0x7f0a009c -int string new_tag_name 0x7f0a007e -int string next_page 0x7f0a0099 +int string load_pre 0x7f0a0040 +int string login 0x7f0a00aa +int string logout 0x7f0a00ab +int string menu 0x7f0a009f +int string new_tag_name 0x7f0a0081 +int string next_page 0x7f0a009c int string no_found 0x7f0a0028 int string not_login 0x7f0a0011 -int string not_started 0x7f0a0096 -int string password 0x7f0a00ab -int string period 0x7f0a00a2 -int string portrait 0x7f0a0060 -int string pre_page 0x7f0a0098 -int string preference_author 0x7f0a0071 -int string preference_author_summary 0x7f0a0072 -int string preference_auto_page_cache 0x7f0a006a -int string preference_auto_page_cache_summary_off 0x7f0a006c -int string preference_auto_page_cache_summary_on 0x7f0a006b -int string preference_cache 0x7f0a0066 -int string preference_cache_summary 0x7f0a0068 -int string preference_cache_summary_no 0x7f0a0069 -int string preference_category_about 0x7f0a0070 -int string preference_category_cache 0x7f0a0065 -int string preference_category_display 0x7f0a005e -int string preference_clear_cache 0x7f0a0067 -int string preference_download_path 0x7f0a006d -int string preference_media_scan 0x7f0a006e -int string preference_page_scaling 0x7f0a0062 -int string preference_screen_ori 0x7f0a005f -int string preference_settings_title 0x7f0a0064 -int string preference_start_position 0x7f0a0063 -int string preference_update_server 0x7f0a006f -int string pull_load_cancel 0x7f0a008d -int string pull_load_doing 0x7f0a008b -int string pull_load_done 0x7f0a008c -int string pull_load_pull 0x7f0a0089 -int string pull_load_release 0x7f0a008a -int string pull_pre_cancel 0x7f0a0088 -int string pull_pre_doing 0x7f0a0086 -int string pull_pre_done 0x7f0a0087 -int string pull_pre_pull 0x7f0a0084 -int string pull_pre_release 0x7f0a0085 -int string pull_refresh_cancel 0x7f0a0083 -int string pull_refresh_doing 0x7f0a0081 -int string pull_refresh_done 0x7f0a0082 -int string pull_refresh_pull 0x7f0a007f -int string pull_refresh_release 0x7f0a0080 -int string rate 0x7f0a009e -int string read 0x7f0a009d -int string refresh 0x7f0a00a3 -int string register 0x7f0a00a6 -int string remove 0x7f0a00c3 -int string remove_info_data 0x7f0a00c4 -int string retry_max_next 0x7f0a0041 -int string retry_max_pre 0x7f0a0040 -int string sadpanda 0x7f0a00a0 -int string some_page 0x7f0a00af -int string star_2 0x7f0a00b4 -int string star_3 0x7f0a00b5 -int string star_4 0x7f0a00b6 -int string star_5 0x7f0a00b7 -int string start_download_task 0x7f0a0091 -int string start_reloading 0x7f0a003f +int string not_started 0x7f0a0099 +int string password 0x7f0a00ae +int string period 0x7f0a00a5 +int string portrait 0x7f0a0063 +int string pre_page 0x7f0a009b +int string preference_author 0x7f0a0074 +int string preference_author_summary 0x7f0a0075 +int string preference_auto_page_cache 0x7f0a006d +int string preference_auto_page_cache_summary_off 0x7f0a006f +int string preference_auto_page_cache_summary_on 0x7f0a006e +int string preference_cache 0x7f0a0069 +int string preference_cache_summary 0x7f0a006b +int string preference_cache_summary_no 0x7f0a006c +int string preference_category_about 0x7f0a0073 +int string preference_category_cache 0x7f0a0068 +int string preference_category_display 0x7f0a0061 +int string preference_clear_cache 0x7f0a006a +int string preference_download_path 0x7f0a0070 +int string preference_media_scan 0x7f0a0071 +int string preference_page_scaling 0x7f0a0065 +int string preference_screen_ori 0x7f0a0062 +int string preference_settings_title 0x7f0a0067 +int string preference_start_position 0x7f0a0066 +int string preference_update_server 0x7f0a0072 +int string pull_load_cancel 0x7f0a0090 +int string pull_load_doing 0x7f0a008e +int string pull_load_done 0x7f0a008f +int string pull_load_pull 0x7f0a008c +int string pull_load_release 0x7f0a008d +int string pull_pre_cancel 0x7f0a008b +int string pull_pre_doing 0x7f0a0089 +int string pull_pre_done 0x7f0a008a +int string pull_pre_pull 0x7f0a0087 +int string pull_pre_release 0x7f0a0088 +int string pull_refresh_cancel 0x7f0a0086 +int string pull_refresh_doing 0x7f0a0084 +int string pull_refresh_done 0x7f0a0085 +int string pull_refresh_pull 0x7f0a0082 +int string pull_refresh_release 0x7f0a0083 +int string rate 0x7f0a00a1 +int string read 0x7f0a00a0 +int string refresh 0x7f0a00a6 +int string register 0x7f0a00a9 +int string remove 0x7f0a00c6 +int string remove_info_data 0x7f0a00c7 +int string retry_max_next 0x7f0a0044 +int string retry_max_pre 0x7f0a0043 +int string sadpanda 0x7f0a00a3 +int string show_tagged 0x7f0a003f +int string some_page 0x7f0a00b2 +int string star_2 0x7f0a00b7 +int string star_3 0x7f0a00b8 +int string star_4 0x7f0a00b9 +int string star_5 0x7f0a00ba +int string start_download_task 0x7f0a0094 +int string start_reloading 0x7f0a0042 int string start_update 0x7f0a002f -int string tag_change_name 0x7f0a007d -int string tag_name 0x7f0a007a -int string tag_name_empty 0x7f0a007b -int string tag_name_exist 0x7f0a007c +int string tag_change_name 0x7f0a0080 +int string tag_name 0x7f0a007d +int string tag_name_empty 0x7f0a007e +int string tag_name_exist 0x7f0a007f int string tap_update 0x7f0a002b -int string thanks 0x7f0a00c6 +int string thanks 0x7f0a00c9 int string toast_add_download 0x7f0a0027 int string toast_add_favourite 0x7f0a0026 int string toast_invalid_page 0x7f0a0021 @@ -478,44 +488,49 @@ int string toast_login_failed 0x7f0a000e int string toast_login_succeeded 0x7f0a000d int string toast_logout_failed 0x7f0a0013 int string toast_logout_succeeded 0x7f0a0012 -int string top_left 0x7f0a00bd -int string top_right 0x7f0a00be -int string unfinished 0x7f0a00a1 +int string top_left 0x7f0a00c0 +int string top_right 0x7f0a00c1 +int string unfinished 0x7f0a00a4 int string up_to_date 0x7f0a002d -int string update 0x7f0a00c5 +int string update 0x7f0a00c8 int string update_failed 0x7f0a0031 int string update_message 0x7f0a002a -int string update_server_gokuai 0x7f0a0078 -int string update_server_google 0x7f0a0076 -int string update_server_qiniu 0x7f0a0077 -int string username 0x7f0a00aa -int string wait 0x7f0a00a9 -int string waiting 0x7f0a0097 -int string what_to_do 0x7f0a00ad -int string zoom_in 0x7f0a009a -int string zoom_out 0x7f0a009b +int string update_server_gokuai 0x7f0a007b +int string update_server_google 0x7f0a0079 +int string update_server_qiniu 0x7f0a007a +int string username 0x7f0a00ad +int string vote_down 0x7f0a003e +int string vote_up 0x7f0a003d +int string wait 0x7f0a00ac +int string waiting 0x7f0a009a +int string what_to_do 0x7f0a00b0 +int string zoom_in 0x7f0a009d +int string zoom_out 0x7f0a009e int style ActionBar 0x7f0b0000 int style ActionBarTitleFont 0x7f0b0001 -int style AppTheme 0x7f0b0012 -int style AppTheme_ListActivity 0x7f0b0014 -int style AppTheme_NoActionBar 0x7f0b0013 -int style AppTheme_NoActionBar_Transparent 0x7f0b0015 +int style AppTheme 0x7f0b0015 +int style AppTheme_ListActivity 0x7f0b0017 +int style AppTheme_NoActionBar 0x7f0b0016 +int style AppTheme_NoActionBar_Transparent 0x7f0b0018 int style Button 0x7f0b0004 int style Button_Blue 0x7f0b0005 int style Button_Small 0x7f0b0007 int style Button_Small_Blue 0x7f0b0008 +int style Button_Small_Flat 0x7f0b000a +int style Button_Small_Flat_Blue 0x7f0b000b +int style Button_Small_Flat_White 0x7f0b000c int style Button_Small_White 0x7f0b0009 int style Button_White 0x7f0b0006 -int style CardSubtitle 0x7f0b000e -int style CardTitle 0x7f0b000d -int style DetailSubtitle 0x7f0b0010 -int style DetailTitle 0x7f0b000f +int style CardSubtitle 0x7f0b0011 +int style CardTitle 0x7f0b0010 +int style DetailSubtitle 0x7f0b0013 +int style DetailTitle 0x7f0b0012 int style OverFlow 0x7f0b0002 int style PopupMenu 0x7f0b0003 -int style ProgressBar 0x7f0b000a -int style ProgressBar_Large 0x7f0b000c -int style ProgressBar_Small 0x7f0b000b -int style TextTag 0x7f0b0011 +int style ProgressBar 0x7f0b000d +int style ProgressBar_Large 0x7f0b000f +int style ProgressBar_Small 0x7f0b000e +int style TextTag 0x7f0b0014 int[] styleable AutoWrapLayout { 0x7f010019 } int styleable AutoWrapLayout_baseLine 0 int[] styleable CheckImage { 0x7f010018 } diff --git a/bin/classes.dex b/bin/classes.dex index 86a5dc657..7fe40a96a 100644 Binary files a/bin/classes.dex and b/bin/classes.dex differ diff --git a/bin/classes/.gitignore b/bin/classes/.gitignore index addd239bf..0888600c4 100644 --- a/bin/classes/.gitignore +++ b/bin/classes/.gitignore @@ -1,2 +1,3 @@ /com /.gitignore +/ehclient diff --git a/bin/dexedLibs/android-support-v4-1c1a4a4d71c1c723e2137d4d967c3739.jar b/bin/dexedLibs/android-support-v4-1c1a4a4d71c1c723e2137d4d967c3739.jar index 765bee850..564262f0f 100644 Binary files a/bin/dexedLibs/android-support-v4-1c1a4a4d71c1c723e2137d4d967c3739.jar and b/bin/dexedLibs/android-support-v4-1c1a4a4d71c1c723e2137d4d967c3739.jar differ diff --git a/bin/dexedLibs/commons-lang3-3.2.1-8a36c15e1c40f2ad0206e5389bc96b5a.jar b/bin/dexedLibs/commons-lang3-3.2.1-8a36c15e1c40f2ad0206e5389bc96b5a.jar index 23e88a767..fd61141c1 100644 Binary files a/bin/dexedLibs/commons-lang3-3.2.1-8a36c15e1c40f2ad0206e5389bc96b5a.jar and b/bin/dexedLibs/commons-lang3-3.2.1-8a36c15e1c40f2ad0206e5389bc96b5a.jar differ diff --git a/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar b/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar index b5a69b7d0..d16fa72c1 100644 Binary files a/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar and b/bin/dexedLibs/slidingmenu-f48f3a4eceb3b9455e8ae38a55377052.jar differ diff --git a/bin/resources.ap_ b/bin/resources.ap_ index f0acfb141..6832165cb 100644 Binary files a/bin/resources.ap_ and b/bin/resources.ap_ differ diff --git a/res/layout/buttons_dialog.xml b/res/layout/buttons_dialog.xml new file mode 100644 index 000000000..e11f4335e --- /dev/null +++ b/res/layout/buttons_dialog.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/detail.xml b/res/layout/detail.xml index 324161fa4..d283baf6a 100644 --- a/res/layout/detail.xml +++ b/res/layout/detail.xml @@ -66,7 +66,7 @@ + android:text="@string/rate" + android:onClick="ButtonRate" /> - @@ -20,7 +20,7 @@ android:id="@+id/detail_rate" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center" + android:layout_centerVertical="true" android:orientation = "horizontal" /> - + + + + + - - 我知道了 获取预览失败 暂无人投票 + 顶 + 踩 + 相同标签 载入上一页 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 24842222a..aad4907cb 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -15,4 +15,14 @@ 18.0sp 14.0sp + + + 18.0sp + 14.0sp + 12.0dp + 2.0dp + + 8.0dp + 2.0dp + diff --git a/res/values/strings.xml b/res/values/strings.xml index 91b0019b8..001dcd81f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -87,7 +87,9 @@ Yes, I know Get preview error ! Not yet rated - + Vote up + Vote down + Show tagged Load previous page diff --git a/res/values/styles.xml b/res/values/styles.xml index b7d233862..dfd533e76 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -41,7 +41,9 @@ @@ -55,6 +57,24 @@ @android:color/black + + + + + + diff --git a/src/com/hippo/ehviewer/AppContext.java b/src/com/hippo/ehviewer/AppContext.java index 0dd0707c6..d8bf3efed 100644 --- a/src/com/hippo/ehviewer/AppContext.java +++ b/src/com/hippo/ehviewer/AppContext.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.lang.Thread.UncaughtExceptionHandler; import com.hippo.ehviewer.data.Data; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.network.HttpHelper; import com.hippo.ehviewer.util.Cache; import com.hippo.ehviewer.util.Config; diff --git a/src/com/hippo/ehviewer/GalleryDownloader.java b/src/com/hippo/ehviewer/GallerysDownloader.java similarity index 58% rename from src/com/hippo/ehviewer/GalleryDownloader.java rename to src/com/hippo/ehviewer/GallerysDownloader.java index a21660f4e..5cc898ea5 100644 --- a/src/com/hippo/ehviewer/GalleryDownloader.java +++ b/src/com/hippo/ehviewer/GallerysDownloader.java @@ -6,9 +6,10 @@ import java.util.List; import com.hippo.ehviewer.data.Data; import com.hippo.ehviewer.data.DownloadInfo; import com.hippo.ehviewer.data.GalleryInfo; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.network.HttpHelper; -public class GalleryDownloader { +public class GallerysDownloader { private AppContext mAppContext; @@ -16,16 +17,21 @@ public class GalleryDownloader { private List mDownloadList; private String[] mPageTokes; private DownloadInfo curDownloadInfo; + private OnGalleryDownloadListener mListener; private static DownloadInfo emptyDownloadInfo = new DownloadInfo(null); - public GalleryDownloader(AppContext appContext) { + public GallerysDownloader(AppContext appContext) { mAppContext = appContext; mPageTokes = null; mData = mAppContext.getData(); mDownloadList = mData.getAllDownloads(); } + public void setOnGalleryDownloadListener(OnGalleryDownloadListener l) { + mListener = l; + } + public synchronized void add(GalleryInfo galleryInfo) { DownloadInfo downloadInfo = new DownloadInfo(galleryInfo); mData.addDownload(downloadInfo); @@ -62,30 +68,56 @@ public class GalleryDownloader { return null; } + private String getUrlContext(HttpHelper hp, String url) { + int times = 3; + String pageContent; + for (int i = 0; i < times; i++) { + pageContent = hp.get(url); + if (pageContent != null) + return pageContent; + } + return null; + } + private class DownloadGallery implements Runnable { @Override public void run() { if ((curDownloadInfo = getFirstWaiting()) != null) { curDownloadInfo.setDownloadState(DownloadInfo.DOWNLOADING); + if (mListener != null) + mListener.onGalleryDownloadStart(curDownloadInfo); // get GalleryInfo galleryInfo = curDownloadInfo.getGalleryInfo(); - byte[] detail = curDownloadInfo.getDetail(); - if (detail == null) { // First time to start this downloadinfo - HttpHelper hp = new HttpHelper(mAppContext); - //hp.get(urlStr); + + HttpHelper hp = new HttpHelper(mAppContext); + String url = EhClient.getDetailUrl(galleryInfo.gid, galleryInfo.token, + EhClient.getDetailModeForDownloadMode(curDownloadInfo.getMode())); + String pageContent = getUrlContext(hp, url); + if (pageContent == null) { + if (mListener != null) + mListener.onGalleryDownloadFailed(curDownloadInfo, hp.getEMsg()); + // New turn + new Thread(new DownloadGallery()).start(); + } else { + + + + } - - - } } } + interface OnGalleryDownloadListener { + void onGalleryDownloadStart(DownloadInfo downloadInfo); + void onGalleryDownloadStop(DownloadInfo downloadInfo); + void onGalleryDownloadFailed(DownloadInfo downloadInfo, String eMsg); + void onGalleryDownloadCompleted(DownloadInfo downloadInfo); + } + - - } diff --git a/src/com/hippo/ehviewer/ListUrls.java b/src/com/hippo/ehviewer/ListUrls.java index a62eb675a..e6fb6f177 100644 --- a/src/com/hippo/ehviewer/ListUrls.java +++ b/src/com/hippo/ehviewer/ListUrls.java @@ -4,6 +4,8 @@ import java.io.UnsupportedEncodingException; import org.apache.commons.lang3.StringEscapeUtils; +import com.hippo.ehviewer.ehclient.EhClient; + public class ListUrls { // Search type diff --git a/src/com/hippo/ehviewer/UpdateHelper.java b/src/com/hippo/ehviewer/UpdateHelper.java index e34c69fd3..a694df22a 100644 --- a/src/com/hippo/ehviewer/UpdateHelper.java +++ b/src/com/hippo/ehviewer/UpdateHelper.java @@ -101,7 +101,7 @@ public class UpdateHelper { jo.put("detail", detailJO); - return hp.postJson(UPDATE_API, jo.toString()); + return hp.postJson(UPDATE_API, jo); } catch (NameNotFoundException e) { e.printStackTrace(); return "NameNotFound"; diff --git a/src/com/hippo/ehviewer/activity/DownloadActivity.java b/src/com/hippo/ehviewer/activity/DownloadActivity.java index 7096c3e59..52e077ecc 100644 --- a/src/com/hippo/ehviewer/activity/DownloadActivity.java +++ b/src/com/hippo/ehviewer/activity/DownloadActivity.java @@ -7,8 +7,8 @@ import java.util.List; import org.apache.commons.lang3.StringEscapeUtils; import com.hippo.ehviewer.BeautifyScreen; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.service.DownloadService; import com.hippo.ehviewer.service.DownloadServiceConnection; import com.hippo.ehviewer.util.Cache; diff --git a/src/com/hippo/ehviewer/activity/FavouriteActivity.java b/src/com/hippo/ehviewer/activity/FavouriteActivity.java index 209839675..6d0525c72 100644 --- a/src/com/hippo/ehviewer/activity/FavouriteActivity.java +++ b/src/com/hippo/ehviewer/activity/FavouriteActivity.java @@ -24,11 +24,11 @@ import android.widget.Toast; import com.hippo.ehviewer.AppContext; import com.hippo.ehviewer.BeautifyScreen; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.ImageLoadManager; import com.hippo.ehviewer.R; import com.hippo.ehviewer.data.Data; import com.hippo.ehviewer.data.GalleryInfo; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.service.DownloadService; import com.hippo.ehviewer.service.DownloadServiceConnection; import com.hippo.ehviewer.util.Cache; @@ -71,7 +71,7 @@ public class FavouriteActivity extends Activity{ GalleryInfo lmd = mFavouriteLmd.get(longClickItemIndex); Intent it = new Intent(FavouriteActivity.this, DownloadService.class); startService(it); - mServiceConn.getService().add(lmd.gid, lmd.thumb, + mServiceConn.getService().add(String.valueOf(lmd.gid), lmd.thumb, EhClient.detailHeader + lmd.gid + "/" + lmd.token, lmd.title); Toast.makeText(FavouriteActivity.this, getString(R.string.toast_add_download), @@ -119,8 +119,8 @@ public class FavouriteActivity extends Activity{ convertView = mInflater.inflate(R.layout.list_item, null); LoadImageView thumb = (LoadImageView)convertView.findViewById(R.id.cover); - if (!lmd.gid.equals(thumb.getKey())) { - thumb.setLoadInfo(lmd.thumb, lmd.gid); + if (!String.valueOf(lmd.gid).equals(thumb.getKey())) { + thumb.setLoadInfo(lmd.thumb, String.valueOf(lmd.gid)); mImageLoadManager.add(thumb, true); // Set manga name diff --git a/src/com/hippo/ehviewer/activity/MangaActivity.java b/src/com/hippo/ehviewer/activity/MangaActivity.java index ebd762a25..ff3738335 100644 --- a/src/com/hippo/ehviewer/activity/MangaActivity.java +++ b/src/com/hippo/ehviewer/activity/MangaActivity.java @@ -14,11 +14,11 @@ import org.apache.commons.lang3.StringEscapeUtils; import com.hippo.ehviewer.AppContext; import com.hippo.ehviewer.BeautifyScreen; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.R; import com.hippo.ehviewer.R.id; import com.hippo.ehviewer.R.layout; import com.hippo.ehviewer.R.string; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.gallery.GalleryView; import com.hippo.ehviewer.gallery.data.ImageSet; import com.hippo.ehviewer.gallery.ui.GLRootView; diff --git a/src/com/hippo/ehviewer/activity/MangaDetailActivity.java b/src/com/hippo/ehviewer/activity/MangaDetailActivity.java index d1f696df7..fb3a8b91a 100644 --- a/src/com/hippo/ehviewer/activity/MangaDetailActivity.java +++ b/src/com/hippo/ehviewer/activity/MangaDetailActivity.java @@ -4,27 +4,31 @@ import java.util.ArrayList; import com.hippo.ehviewer.AppContext; import com.hippo.ehviewer.BeautifyScreen; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.R; import com.hippo.ehviewer.data.Data; import com.hippo.ehviewer.data.GalleryDetail; import com.hippo.ehviewer.data.GalleryInfo; -import com.hippo.ehviewer.data.PageList; +import com.hippo.ehviewer.data.PreviewList; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.service.DownloadService; import com.hippo.ehviewer.service.DownloadServiceConnection; import com.hippo.ehviewer.util.Cache; import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.Ui; import com.hippo.ehviewer.util.Util; +import com.hippo.ehviewer.view.AlertButton; import com.hippo.ehviewer.view.OlImageView; import com.hippo.ehviewer.widget.AutoWrapLayout; +import com.hippo.ehviewer.widget.ButtonsDialogBuilder; import com.hippo.ehviewer.widget.DialogBuilder; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.content.Intent; +import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; @@ -32,6 +36,7 @@ import android.graphics.drawable.ColorDrawable; import android.os.Build; import android.os.Bundle; import android.util.DisplayMetrics; +import android.util.TypedValue; import com.hippo.ehviewer.util.Log; @@ -44,12 +49,16 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.TranslateAnimation; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; +import android.widget.RatingBar; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; @@ -81,7 +90,7 @@ public class MangaDetailActivity extends Activity { private ViewGroup pageListMain; private AutoWrapLayout pageListLayout; private ProgressBar waitPageList; - private TextView previewNumText; + //private TextView previewNumText; private TextView previewNumText2; private Button previewRefreshButton; private View bottomPanel; @@ -131,7 +140,7 @@ public class MangaDetailActivity extends Activity { waitPageList.setVisibility(View.GONE); previewRefreshButton.setVisibility(View.GONE); - PageList pageList = mangaDetail.previewLists[page]; + PreviewList pageList = mangaDetail.previewLists[page]; if (pageList == null) { Log.d(TAG, "WTF, I may check mangaDetail.pageLists[page] is not null"); Toast.makeText(this, "WTF, I may check mangaDetail.pageLists[page] is not null", Toast.LENGTH_SHORT).show(); @@ -139,8 +148,8 @@ public class MangaDetailActivity extends Activity { } int index = page * mangaDetail.previewPerPage + 1; int rowIndex = 0; - for (PageList.Row row : pageList.rowArray) { - for (PageList.Row.Item item : row.itemArray) { + for (PreviewList.Row row : pageList.rowArray) { + for (PreviewList.Row.Item item : row.itemArray) { TextViewWithUrl tvu = new TextViewWithUrl(MangaDetailActivity.this, item.url); tvu.setGravity(Gravity.CENTER); @@ -189,7 +198,7 @@ public class MangaDetailActivity extends Activity { private void addPageImage(int page, int rowIndex, Bitmap bitmap) { if (page != curPage) return; - PageList pageList = mangaDetail.previewLists[page]; + PreviewList pageList = mangaDetail.previewLists[page]; if (pageList == null) { Log.d(TAG, "WTF, I may check mangaDetail.pageLists[page] is not null"); return; @@ -198,13 +207,13 @@ public class MangaDetailActivity extends Activity { int maxWidth = bitmap.getWidth(); int maxHeight = bitmap.getHeight(); - PageList.Row row = pageList.rowArray.get(rowIndex); - ArrayList items = row.itemArray; + PreviewList.Row row = pageList.rowArray.get(rowIndex); + ArrayList items = row.itemArray; int startIndex = row.startIndex; int endIndex = startIndex + items.size(); for(int i = startIndex ; i < endIndex; i++) { - PageList.Row.Item item = items.get(i - startIndex); + PreviewList.Row.Item item = items.get(i - startIndex); if (item.xOffset + item.width > maxWidth) item.width = maxWidth - item.xOffset; @@ -226,7 +235,7 @@ public class MangaDetailActivity extends Activity { EhClient.OnGetMangaDetailListener { @Override public void onSuccess(GalleryDetail md) { - Cache.mdCache.put(mangaDetail.gid, md); + Cache.mdCache.put(String.valueOf(mangaDetail.gid), md); layout(md); } @@ -334,9 +343,107 @@ public class MangaDetailActivity extends Activity { public void ButtonPreviewRefresh(View v) { refreshPageList(); } - + + public void ButtonRate(View v) { + rate(); + } + // *** Button onclick end ***// + private int getSendableRating(float ratingFloat) { + float dr = ratingFloat*2; + return (int)(dr + 0.5); + } + + public void rate() { + final RatingBar rb = new RatingBar(this); + rb.setMax(10); + rb.setStepSize(0.5f); + LinearLayout ll = new LinearLayout(this); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.CENTER; + lp.setMargins(0, Ui.dp2pix(24), 0, Ui.dp2pix(24)); + ll.addView(rb, lp); + new DialogBuilder(this).setTitle(R.string.rate) + .setView(ll, true) + .setPositiveButton(android.R.string.ok, new OnClickListener() { + @Override + public void onClick(View v) { + int rating = getSendableRating(rb.getRating()); + if (rating <= 0 || rating > 10) + Toast.makeText(MangaDetailActivity.this, "非法评分", Toast.LENGTH_SHORT).show(); // TODO + else { + ((AlertButton)v).dialog.dismiss(); + mEhClient.rate(mangaDetail.gid, mangaDetail.token, + rating, new EhClient.OnRateListener() { + @Override + public void onSuccess(float ratingAvg, + int ratingCnt) { + mangaDetail.rating = ratingAvg; + mangaDetail.people = ratingCnt; + if (!MangaDetailActivity.this.isFinishing()) { + //Reset start + LinearLayout rate = (LinearLayout) findViewById(R.id.detail_rate); + Ui.addStar(rate, mangaDetail.rating); + + // Animation + TextView averagePeople = (TextView)findViewById( + R.id.detail_average_people); + final TextView averagePeopleBak = (TextView)findViewById( + R.id.detail_average_people_bak); + averagePeopleBak.setText(averagePeople.getText()); + averagePeople.setText(String.format("%.2f (%d)", + mangaDetail.rating, mangaDetail.people)); + averagePeopleBak.setVisibility(View.VISIBLE); + + int duration = 1000; + int height = averagePeople.getHeight(); + + TranslateAnimation animation = new TranslateAnimation(0, 0, height, 0); + animation.setDuration(duration); + averagePeople.setAnimation(animation); + + TranslateAnimation animationBak = new TranslateAnimation(0, 0, 0, -height); + animationBak.setDuration(duration); + averagePeopleBak.setAnimation(animationBak); + animationBak.setAnimationListener(new AnimationListener() { + @Override + public void onAnimationStart( + Animation animation) {} + + @Override + public void onAnimationEnd( + Animation animation) { + averagePeopleBak.setVisibility(View.GONE); + } + @Override + public void onAnimationRepeat( + Animation animation) {} + }); + animation.startNow(); + animationBak.startNow(); + } + Toast.makeText(MangaDetailActivity.this, + "评价成功", Toast.LENGTH_SHORT).show(); // TODO + } + @Override + public void onFailure(String eMsg) { + Toast.makeText(MangaDetailActivity.this, + "评价失败\n" + eMsg, Toast.LENGTH_SHORT).show(); // TODO + } + }); + } + } + }).setNegativeButton(android.R.string.cancel, new OnClickListener(){ + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + } + }).create().show(); + } + private AlertDialog createGoToDialog() { return new DialogBuilder(this).setTitle(R.string.jump) .setAdapter(new BaseAdapter() { @@ -388,12 +495,12 @@ public class MangaDetailActivity extends Activity { waitPageList.setVisibility(View.VISIBLE); previewRefreshButton.setVisibility(View.GONE); - previewNumText.setText(String.format("%d / %d", - curPage+1, mangaDetail.previewSum)); + //previewNumText.setText(String.format("%d / %d", + //curPage+1, mangaDetail.previewSum)); previewNumText2.setText(String.format("%d / %d", curPage+1, mangaDetail.previewSum)); - PageList pageList = mangaDetail.previewLists[curPage]; + PreviewList pageList = mangaDetail.previewLists[curPage]; if (pageList == null) { String tempUrl = url; @@ -404,7 +511,7 @@ public class MangaDetailActivity extends Activity { mEhClient.getPageList(tempUrl, curPage, new EhClient.OnGetPageListListener() { @Override - public void onSuccess(Object checkFlag, PageList pageList) { + public void onSuccess(Object checkFlag, PreviewList pageList) { int page = (Integer)checkFlag; mangaDetail.previewLists[page] = pageList; addPageItem(page); @@ -472,7 +579,7 @@ public class MangaDetailActivity extends Activity { GalleryInfo galleryInfo = (GalleryInfo)(intent.getParcelableExtra(KEY_G_INFO)); boolean getFromCache = true; - mangaDetail = Cache.mdCache.get(galleryInfo.gid); + mangaDetail = Cache.mdCache.get(String.valueOf(galleryInfo.gid)); if (mangaDetail == null) { getFromCache = false; mangaDetail = new GalleryDetail(galleryInfo); @@ -491,7 +598,7 @@ public class MangaDetailActivity extends Activity { pageListLayout = (AutoWrapLayout) findViewById(R.id.paper_list_layout); waitPageList = (ProgressBar) findViewById(R.id.paper_list_wait); previewRefreshButton = (Button) findViewById(R.id.preview_button_refresh); - previewNumText = (TextView) findViewById(R.id.preview_num); + //previewNumText = (TextView) findViewById(R.id.preview_num); bottomPanel = (View)findViewById(R.id.bottom_panel); previewNumText2 = (TextView)bottomPanel.findViewById(R.id.preview_num); readButton = (Button)findViewById(R.id.detail_read); @@ -501,11 +608,11 @@ public class MangaDetailActivity extends Activity { BeautifyScreen.ColourfyScreen(this); } - setTitle(mangaDetail.gid); + setTitle(String.valueOf(mangaDetail.gid)); OlImageView coverImage = (OlImageView) findViewById(R.id.detail_cover); coverImage.setUrl(mangaDetail.thumb); - coverImage.setKey(mangaDetail.gid); + coverImage.setKey(String.valueOf(mangaDetail.gid)); coverImage.setCache(Cache.memoryCache, Cache.cpCache); coverImage.loadImage(false); @@ -561,7 +668,7 @@ public class MangaDetailActivity extends Activity { Ui.addStar(rate, mangaDetail.rating); TextView averagePeople = (TextView) findViewById(R.id.detail_average_people); - averagePeople.setText(String.format("%s (%s)", mangaDetail.rating, mangaDetail.people)); + averagePeople.setText(String.format("%.2f (%d)", mangaDetail.rating, mangaDetail.people)); TextView posted = (TextView) findViewById(R.id.detail_posted); posted.setText(mangaDetail.posted); @@ -574,10 +681,8 @@ public class MangaDetailActivity extends Activity { // TODO - if (mangaDetail.tags != null) { - LinearLayout tagsLayout = (LinearLayout) findViewById(R.id.tags_layout); - addTags(tagsLayout, mangaDetail.tags); - } + LinearLayout tagsLayout = (LinearLayout) findViewById(R.id.tags_layout); + addTags(tagsLayout, mangaDetail.tags); mangaDetailNormal.setVisibility(View.VISIBLE); @@ -585,7 +690,7 @@ public class MangaDetailActivity extends Activity { if (mangaDetail.previewSum > 1) goToDialog = createGoToDialog(); else { - previewNumText.setClickable(false); + //previewNumText.setClickable(false); previewNumText2.setClickable(false); } // paper list @@ -594,8 +699,8 @@ public class MangaDetailActivity extends Activity { // preview num bottomPanel.setVisibility(View.VISIBLE); - previewNumText.setText(String.format("%d / %d", - 1, mangaDetail.previewSum)); + //previewNumText.setText(String.format("%d / %d", + //1, mangaDetail.previewSum)); previewNumText2.setText(String.format("%d / %d", 1, mangaDetail.previewSum)); @@ -612,7 +717,12 @@ public class MangaDetailActivity extends Activity { tagsLayout.removeAllViews(); int x = Ui.dp2pix(8); int y = Ui.dp2pix(6); - + Resources resources = getResources(); + // Get tag view resources + int tagTextSize = resources.getDimensionPixelOffset(R.dimen.button_small_size); + ColorStateList tagTextColor = resources.getColorStateList(R.color.blue_bn_text); + int tagPaddingX = resources.getDimensionPixelOffset(R.dimen.button_tag_padding_x); + int tagPaddingY = resources.getDimensionPixelOffset(R.dimen.button_tag_padding_y); for (String[] tagGroup : tagGroups) { LinearLayout tagGroupLayout = new LinearLayout(this); tagGroupLayout.setOrientation(LinearLayout.HORIZONTAL); @@ -625,10 +735,27 @@ public class MangaDetailActivity extends Activity { lp.setMargins(x, y, x, y); tagGroupLayout.addView(groupNameView, lp); } else { - TextView tagView = new TextView(new ContextThemeWrapper(this, R.style.TextTag)); - tagView.setText(tagGroup[i]); - tagView.setTextColor(Color.WHITE); - tagView.setBackgroundColor(Ui.HOLO_BLUE_DARK); + final String tagText = tagGroup[i]; + Button tagView = new Button(this); + tagView.setTextSize(TypedValue.COMPLEX_UNIT_PX, tagTextSize); + tagView.setText(tagText); + tagView.setTextColor(tagTextColor); + tagView.setBackgroundResource(R.drawable.blue_bn_bg); + tagView.setPadding(tagPaddingX, tagPaddingY, tagPaddingX, tagPaddingY); + tagView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + AlertButton voteUp = new AlertButton(MangaDetailActivity.this); + voteUp.setText(getString(R.string.vote_up)); // TODO + AlertButton voteDown = new AlertButton(MangaDetailActivity.this); + voteDown.setText(getString(R.string.vote_down)); // TODO + AlertButton showTagged = new AlertButton(MangaDetailActivity.this); + showTagged.setText(getString(R.string.show_tagged)); // TODO + new ButtonsDialogBuilder(MangaDetailActivity.this).setTitle(tagText) + .addButton(voteUp).addButton(voteDown).addButton(showTagged) + .create().show(); + } + }); AutoWrapLayout.LayoutParams lp = new AutoWrapLayout.LayoutParams(); lp.setMargins(x, y, x, y); tagLayout.addView(tagView, lp); @@ -637,6 +764,20 @@ public class MangaDetailActivity extends Activity { tagGroupLayout.addView(tagLayout); tagsLayout.addView(tagGroupLayout); } + + // Add tag + Button addtagView = new Button(this); + addtagView.setTextSize(TypedValue.COMPLEX_UNIT_PX, tagTextSize); + addtagView.setText("+"); + addtagView.setTextColor(tagTextColor); + addtagView.setBackgroundResource(R.drawable.blue_bn_bg); + addtagView.setPadding(tagPaddingX, tagPaddingY, tagPaddingX, tagPaddingY); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.RIGHT; + lp.setMargins(x, y, x, y); + tagsLayout.addView(addtagView, lp); } @Override @@ -662,13 +803,13 @@ public class MangaDetailActivity extends Activity { Intent it = new Intent(MangaDetailActivity.this, DownloadService.class); startService(it); if (mangaDetail.firstPage == null) - mServiceConn.getService().add(mangaDetail.gid, mangaDetail.thumb, + mServiceConn.getService().add(String.valueOf(mangaDetail.gid), mangaDetail.thumb, EhClient.detailHeader + mangaDetail.gid + "/" + mangaDetail.token, mangaDetail.title); else - mServiceConn.getService().add(mangaDetail.gid, mangaDetail.thumb, + mServiceConn.getService().add(String.valueOf(mangaDetail.gid), mangaDetail.thumb, EhClient.detailHeader + mangaDetail.gid + "/" + mangaDetail.token, - mangaDetail.firstPage, Integer.parseInt(mangaDetail.pages), + mangaDetail.firstPage, mangaDetail.pages, 1, mangaDetail.title); Toast.makeText(MangaDetailActivity.this, getString(R.string.toast_add_download), diff --git a/src/com/hippo/ehviewer/activity/MangaDownloadActivity.java b/src/com/hippo/ehviewer/activity/MangaDownloadActivity.java index c8d0100ca..e3a5c4bde 100644 --- a/src/com/hippo/ehviewer/activity/MangaDownloadActivity.java +++ b/src/com/hippo/ehviewer/activity/MangaDownloadActivity.java @@ -7,8 +7,8 @@ import java.util.Collections; import org.apache.commons.lang3.StringEscapeUtils; import com.hippo.ehviewer.AppContext; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.gallery.GalleryView; import com.hippo.ehviewer.gallery.data.DownloadImageSet; import com.hippo.ehviewer.gallery.data.ImageSet; diff --git a/src/com/hippo/ehviewer/activity/MangaListActivity.java b/src/com/hippo/ehviewer/activity/MangaListActivity.java index 0de034a66..51356c9c7 100644 --- a/src/com/hippo/ehviewer/activity/MangaListActivity.java +++ b/src/com/hippo/ehviewer/activity/MangaListActivity.java @@ -10,7 +10,6 @@ import org.apache.commons.lang3.StringEscapeUtils; import com.hippo.ehviewer.AppContext; import com.hippo.ehviewer.BeautifyScreen; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.ImageLoadManager; import com.hippo.ehviewer.ListUrls; import com.hippo.ehviewer.R; @@ -18,6 +17,7 @@ import com.hippo.ehviewer.UpdateHelper; import com.hippo.ehviewer.data.Data; import com.hippo.ehviewer.data.GalleryInfo; import com.hippo.ehviewer.data.Tag; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.network.Downloader; import com.hippo.ehviewer.service.DownloadService; import com.hippo.ehviewer.service.DownloadServiceConnection; @@ -383,7 +383,7 @@ public class MangaListActivity extends SlidingActivity { lmd = lmdArray.get(longClickItemIndex); Intent it = new Intent(MangaListActivity.this, DownloadService.class); startService(it); - mServiceConn.getService().add(lmd.gid, lmd.thumb, + mServiceConn.getService().add(String.valueOf(lmd.gid), lmd.thumb, EhClient.detailHeader + lmd.gid + "/" + lmd.token, lmd.title); Toast.makeText(MangaListActivity.this, getString(R.string.toast_add_download), @@ -996,7 +996,7 @@ public class MangaListActivity extends SlidingActivity { convertView = mInflater.inflate(R.layout.list_item, null); } LoadImageView thumb = (LoadImageView)convertView.findViewById(R.id.cover); - if (!lmd.gid.equals(thumb.getKey())) { + if (!String.valueOf(lmd.gid).equals(thumb.getKey())) { if (!isNew) { // TODO default index = 0, should get it id ((ViewGroup)convertView).removeView(thumb); @@ -1005,7 +1005,7 @@ public class MangaListActivity extends SlidingActivity { thumb.setId(R.id.cover); ((ViewGroup)convertView).addView(thumb, 0, lp); } - thumb.setLoadInfo(lmd.thumb, lmd.gid); + thumb.setLoadInfo(lmd.thumb, String.valueOf(lmd.gid)); mImageLoadManager.add(thumb, false); // Set manga name diff --git a/src/com/hippo/ehviewer/data/Data.java b/src/com/hippo/ehviewer/data/Data.java index fcaea4e02..7a703c89d 100644 --- a/src/com/hippo/ehviewer/data/Data.java +++ b/src/com/hippo/ehviewer/data/Data.java @@ -11,6 +11,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; +import android.util.SparseArray; /** * @author Hippo @@ -50,7 +51,7 @@ public class Data { private static final String COLUMN_DETAIL = "detail"; private static final String COLUMN_START_PAGE = "start_page"; - private Map mGallerys; + private SparseArray mGallerys; private long mTagRowNum; private List mTags; @@ -69,7 +70,7 @@ public class Data { mDBHelper = new DBHelper(mContext); mDatabase = mDBHelper.getWritableDatabase(); - mGallerys = new HashMap(); + mGallerys = new SparseArray(); getTags(); getReads(); @@ -90,11 +91,11 @@ public class Data { * @param gid * @return */ - public GalleryInfo getGallery(String gid) { + public GalleryInfo getGallery(int gid) { GalleryInfo galleryInfo = mGallerys.get(gid); if (galleryInfo == null) { Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_GALLERY + " where " + COLUMN_GID + "=?", - new String[]{gid}); + new String[]{String.valueOf(gid)}); if (cursor.moveToFirst()) { galleryInfo = new GalleryInfo(); galleryInfo.gid = gid; @@ -104,7 +105,7 @@ public class Data { galleryInfo.category = cursor.getInt(4); galleryInfo.thumb = cursor.getString(5); galleryInfo.uploader = cursor.getString(6); - galleryInfo.rating = cursor.getString(7); + galleryInfo.rating = cursor.getFloat(7); // add to map mGallerys.put(gid, galleryInfo); @@ -115,11 +116,11 @@ public class Data { } @SuppressWarnings("unused") - private synchronized boolean containsGallery(String gid) { + private synchronized boolean containsGallery(int gid) { boolean re = false; Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_GALLERY + " where " + COLUMN_GID + "=?", - new String[]{gid}); + new String[]{String.valueOf(gid)}); if (cursor.moveToFirst()) re = true; cursor.close(); @@ -131,11 +132,11 @@ public class Data { * @param gid * @return */ - private synchronized int getGalleryReference(String gid) { + private synchronized int getGalleryReference(int gid) { int reference = -1; Cursor cursor = mDatabase.rawQuery("select " + COLUMN_REFERENCE + " from " + TABLE_GALLERY + " where " + COLUMN_GID + "=?", - new String[]{gid}); + new String[]{String.valueOf(gid)}); if (cursor.moveToFirst()) { reference = cursor.getInt(0); } @@ -149,11 +150,10 @@ public class Data { * If exits no same gid, add it to table reference is 1 * * @param galleryInfo - * @param isUpdate */ - private void addGallery(GalleryInfo galleryInfo, boolean isUpdate) { + private void addGallery(GalleryInfo galleryInfo) { boolean isInsert; - String gid = galleryInfo.gid; + int gid = galleryInfo.gid; // add to map mGallerys.put(gid, galleryInfo); @@ -161,8 +161,7 @@ public class Data { int reference; if ((reference = getGalleryReference(gid)) != -1) { isInsert = false; - if (!isUpdate) - reference++; + reference++; } else { isInsert = true; @@ -183,31 +182,53 @@ public class Data { if (isInsert) { // Set mDatabase.insert(TABLE_GALLERY, null, values); } else { // Update - mDatabase.update(TABLE_GALLERY, values, COLUMN_GID + "=?", new String[]{gid}); + mDatabase.update(TABLE_GALLERY, values, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); } } + /** + * True if update + * + * @param gid + * @return + */ + private boolean updateGallery(GalleryInfo galleryInfo) { + ContentValues values = new ContentValues(); + values.put(COLUMN_GID, galleryInfo.gid); + values.put(COLUMN_TOKEN, galleryInfo.token); + values.put(COLUMN_TITLE, galleryInfo.title); + values.put(COLUMN_POSTED, galleryInfo.posted); + values.put(COLUMN_CATEGORY, galleryInfo.category); + values.put(COLUMN_THUMB, galleryInfo.thumb); + values.put(COLUMN_UPLOADER, galleryInfo.uploader); + values.put(COLUMN_RATING, galleryInfo.rating); + + return mDatabase.update(TABLE_GALLERY, values, + COLUMN_GID + "=?", new String[]{String.valueOf(galleryInfo.gid)}) != 0; + } + /** * decrease reference by 1, only delete when reference is 0 * @param gid */ - private void deleteGallery(String gid) { + private boolean deleteGallery(int gid) { int reference = getGalleryReference(gid); if (reference == -1) { Log.w(TAG, "Can't get reference when deleteGallery, gid is " + gid); - return; + return false; } reference--; if (reference == 0) { // delete gallery // delete in sql - mDatabase.delete(TABLE_GALLERY, COLUMN_GID + "=?", new String[]{gid}); + mDatabase.delete(TABLE_GALLERY, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); // delete in list mGallerys.remove(gid); } else { // update reference ContentValues values = new ContentValues(); values.put(COLUMN_REFERENCE, reference); - mDatabase.update(TABLE_GALLERY, values, COLUMN_GID + "=?", new String[]{gid}); + mDatabase.update(TABLE_GALLERY, values, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); } + return true; } /****** download ******/ @@ -215,28 +236,20 @@ public class Data { mDownloads = new ArrayList(); mDownloadRowNum = 0; - List invaildGids = new ArrayList(); - Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_DOWNLOAD + " order by " + COLUMN_ID + " asc", null); if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { - - String gid = cursor.getString(1); + int gid = cursor.getInt(1); GalleryInfo galleryInfo = getGallery(gid); - if (galleryInfo == null) { - invaildGids.add(gid); - } else { - int state = cursor.getInt(2); - int pages = cursor.getInt(3); - byte[] detail = cursor.getBlob(4); - int startPage = cursor.getInt(5); - - DownloadInfo downloadInfo = new DownloadInfo( - galleryInfo, state, pages, detail, startPage); - - mDownloads.add(downloadInfo); - } + int state = cursor.getInt(2); + int pages = cursor.getInt(3); + byte[] detail = cursor.getBlob(4); + int startPage = cursor.getInt(5); + DownloadInfo downloadInfo = new DownloadInfo( + galleryInfo, state, pages, detail, startPage); + mDownloads.add(downloadInfo); + cursor.moveToNext(); mDownloadRowNum++; } @@ -244,28 +257,52 @@ public class Data { cursor.close(); } + /** + * True if contain this item + * + * @param gid + * @return + */ + public synchronized boolean containsDownload(int gid) { + boolean re = false; + Cursor cursor = mDatabase.rawQuery("select * from " + + TABLE_DOWNLOAD + " where " + COLUMN_GID + "=?", + new String[]{String.valueOf(gid)}); + if (cursor.moveToFirst()) + re = true; + cursor.close(); + return re; + } + public synchronized boolean addDownload(DownloadInfo downloadInfo) { GalleryInfo galleryInfo = downloadInfo.getGalleryInfo(); - - // add to sql - ContentValues values = new ContentValues(); - values.put(COLUMN_ID, mDownloadRowNum); - values.put(COLUMN_GID, galleryInfo.gid); - values.put(COLUMN_STATE, downloadInfo.getState()); - values.put(COLUMN_DETAIL, downloadInfo.getDetail()); - values.put(COLUMN_START_PAGE, downloadInfo.getStartPage()); - - boolean ok = mDatabase.insert( - TABLE_DOWNLOAD, null, values) != -1; - if (ok) { - // add to list - mDownloadRowNum++; - mDownloads.add(downloadInfo); + int gid = galleryInfo.gid; + // Delete from read + deleteRead(gid); + // Add to download + if (containsDownload(gid)) { + updateGallery(galleryInfo); + return false; + } else { + addGallery(galleryInfo); - // add reference - addGallery(galleryInfo, false); + // add to sql + ContentValues values = new ContentValues(); + values.put(COLUMN_ID, mDownloadRowNum); + values.put(COLUMN_GID, gid); + values.put(COLUMN_STATE, downloadInfo.getState()); + values.put(COLUMN_DETAIL, downloadInfo.getDetail()); + values.put(COLUMN_START_PAGE, downloadInfo.getStartPage()); + if (mDatabase.insert(TABLE_DOWNLOAD, null, + values) != -1) { // If add ok + mDownloadRowNum++; + mDownloads.add(downloadInfo); + return true; + } else { // If add fail + deleteGallery(gid); + return false; + } } - return ok; } public synchronized boolean deleteDownload(int id) { @@ -327,7 +364,7 @@ public class Data { mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(location)}); // Update gallery - addGallery(galleryInfo, true); + updateGallery(galleryInfo); } } @@ -364,57 +401,62 @@ public class Data { Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_READ, null); - List invaildGids = new ArrayList(); - if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { - String gid = cursor.getString(0); + int gid = cursor.getInt(0); GalleryInfo galleryInfo = getGallery(gid); - if (galleryInfo == null) { - invaildGids.add(gid); - } else { - mReads.add(galleryInfo); - } + mReads.add(galleryInfo); cursor.moveToNext(); } } cursor.close(); - - // remove invail gid - for (String invaildGid : invaildGids) { - mDatabase.delete(TABLE_READ, COLUMN_GID + "=?", - new String[]{String.valueOf(invaildGid)}); - } } public synchronized List getAllReads() { return mReads; } - public synchronized void addRead(GalleryInfo galleryInfo) { - // add to sql - ContentValues values = new ContentValues(); - values.put(COLUMN_GID, galleryInfo.gid); - boolean isUpdate = mDatabase.insert( - TABLE_READ, null, values) == -1; - addGallery(galleryInfo, isUpdate); - - // add to list - if (!isUpdate) - mReads.add(galleryInfo); + public synchronized boolean containsRead(int gid) { + boolean re = false; + Cursor cursor = mDatabase.rawQuery("select * from " + + TABLE_READ + " where " + COLUMN_GID + "=?", + new String[]{String.valueOf(gid)}); + if (cursor.moveToFirst()) + re = true; + cursor.close(); + return re; } - public synchronized void deleteRead(String gid) { + public synchronized void addRead(GalleryInfo galleryInfo) { + int gid = galleryInfo.gid; + // Do not add to read if it in download + if (containsDownload(gid)) + return; + + if (containsRead(gid)) { + updateGallery(galleryInfo); + } else { + addGallery(galleryInfo); + // add to sql + ContentValues values = new ContentValues(); + values.put(COLUMN_GID, galleryInfo.gid); + mDatabase.insert(TABLE_READ, null, values); + // add to list + mReads.add(galleryInfo); + } + } + + public synchronized void deleteRead(int gid) { // delete from list for (GalleryInfo galleryInfo : mReads) { - if (galleryInfo.gid.equals(gid)) { + if (galleryInfo.gid == gid) { mReads.remove(galleryInfo); break; } } // delete from sql - mDatabase.delete(TABLE_READ, COLUMN_GID + "=?", new String[]{gid}); + mDatabase.delete(TABLE_READ, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); deleteGallery(gid); } @@ -427,7 +469,7 @@ public class Data { + TABLE_READ, null); if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { - String gid = cursor.getString(0); + int gid = cursor.getInt(0); deleteGallery(gid); cursor.moveToNext(); } @@ -442,34 +484,22 @@ public class Data { Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_LOCAL_FAVOURITE, null); - List invaildGids = new ArrayList(); - if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { - String gid = cursor.getString(0); + int gid = cursor.getInt(0); GalleryInfo galleryInfo = getGallery(gid); - if (galleryInfo == null) { - invaildGids.add(gid); - } else { - mLocalFavourites.add(galleryInfo); - } + mLocalFavourites.add(galleryInfo); cursor.moveToNext(); } } cursor.close(); - - // remove invail gid - for (String invaildGid : invaildGids) { - mDatabase.delete(TABLE_LOCAL_FAVOURITE, COLUMN_GID + "=?", - new String[]{String.valueOf(invaildGid)}); - } } - public synchronized boolean containsLocalFavourite(String gid) { + public synchronized boolean containsLocalFavourite(int gid) { boolean re = false; Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_LOCAL_FAVOURITE + " where " + COLUMN_GID + "=?", - new String[]{gid}); + new String[]{String.valueOf(gid)}); if (cursor.moveToFirst()) re = true; cursor.close(); @@ -481,29 +511,32 @@ public class Data { * @param galleryInfo */ public synchronized void addLocalFavourite(GalleryInfo galleryInfo) { - // add to sql - ContentValues values = new ContentValues(); - values.put(COLUMN_GID, galleryInfo.gid); - boolean isUpdate = mDatabase.insert( - TABLE_LOCAL_FAVOURITE, null, values) == -1; - addGallery(galleryInfo, isUpdate); + int gid = galleryInfo.gid; - // add to list - if (!isUpdate) + if (containsRead(gid)) { + updateGallery(galleryInfo); + } else { + addGallery(galleryInfo); + // add to sql + ContentValues values = new ContentValues(); + values.put(COLUMN_GID, galleryInfo.gid); + mDatabase.insert(TABLE_LOCAL_FAVOURITE, null, values); + // add to list mLocalFavourites.add(galleryInfo); + } } - public synchronized void deleteLocalFavourite(String gid) { + public synchronized void deleteLocalFavourite(int gid) { // delete from list for (GalleryInfo galleryInfo : mLocalFavourites) { - if (galleryInfo.gid.equals(gid)) { + if (galleryInfo.gid == gid) { mLocalFavourites.remove(galleryInfo); break; } } // delete from sql - mDatabase.delete(TABLE_LOCAL_FAVOURITE, COLUMN_GID + "=?", new String[]{gid}); + mDatabase.delete(TABLE_LOCAL_FAVOURITE, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); deleteGallery(gid); } @@ -654,27 +687,29 @@ public class Data { public void onCreate(SQLiteDatabase db) { // gallery String CreateGallery = "create table " + TABLE_GALLERY + "(" - + COLUMN_GID + " text primary key," + + COLUMN_GID + " integer primary key," + COLUMN_TOKEN + " text," + COLUMN_TITLE + " text," + COLUMN_POSTED + " text," + COLUMN_CATEGORY + " integer," + COLUMN_THUMB + " text," + COLUMN_UPLOADER + " text," - + COLUMN_RATING + " text," + + COLUMN_RATING + " float," + COLUMN_REFERENCE + " integer);"; db.execSQL(CreateGallery); // read String CreateRead = "create table " + TABLE_READ + "(" - + COLUMN_GID + " text primary key);"; + + COLUMN_GID + " integer primary key," + + "foreign key(" + COLUMN_GID + ") references " + TABLE_GALLERY + "(" + COLUMN_GID + "));"; db.execSQL(CreateRead); // local favourite String CreateLocalFavourite = "create table " + TABLE_LOCAL_FAVOURITE + "(" - + COLUMN_GID + " text primary key);"; + + COLUMN_GID + " integer primary key," + + "foreign key(" + COLUMN_GID + ") references " + TABLE_GALLERY + "(" + COLUMN_GID + "));"; db.execSQL(CreateLocalFavourite); // tag @@ -692,11 +727,12 @@ public class Data { String CreateDownload = "create table " + TABLE_DOWNLOAD + "(" + COLUMN_ID + " integer primary key," - + COLUMN_GID + " text unique," + + COLUMN_GID + " integer unique," + COLUMN_STATE + " integer," + COLUMN_PAGES + " integer," + COLUMN_DETAIL + " blob," - + COLUMN_START_PAGE + " integer);"; + + COLUMN_START_PAGE + " integer," + + "foreign key(" + COLUMN_GID + ") references " + TABLE_GALLERY + "(" + COLUMN_GID + "));"; db.execSQL(CreateDownload); } diff --git a/src/com/hippo/ehviewer/data/DownloadInfo.java b/src/com/hippo/ehviewer/data/DownloadInfo.java index d3da91bab..1e6083727 100644 --- a/src/com/hippo/ehviewer/data/DownloadInfo.java +++ b/src/com/hippo/ehviewer/data/DownloadInfo.java @@ -1,6 +1,5 @@ package com.hippo.ehviewer.data; - /** * * Use byte[] to store download detail, @@ -84,6 +83,10 @@ public class DownloadInfo { return mGalleryInfo; } + public int getMode() { + return mMode; + } + public int getState() { return mState; } diff --git a/src/com/hippo/ehviewer/data/GalleryDetail.java b/src/com/hippo/ehviewer/data/GalleryDetail.java index 55588f8c1..a2ee6ac2b 100644 --- a/src/com/hippo/ehviewer/data/GalleryDetail.java +++ b/src/com/hippo/ehviewer/data/GalleryDetail.java @@ -5,20 +5,20 @@ import android.os.Parcelable; public class GalleryDetail extends GalleryInfo{ - public String pages; + public int pages; public String size; public String resized; public String parent; public String visible; public String language; - public String people; + public int people; public String firstPage; public String[][] tags; // For Preview public int previewSum; public int previewPerPage; - public PageList[] previewLists; + public PreviewList[] previewLists; /* public static final Parcelable.Creator CREATOR = diff --git a/src/com/hippo/ehviewer/data/GalleryInfo.java b/src/com/hippo/ehviewer/data/GalleryInfo.java index 3515e94a0..e06fcec73 100644 --- a/src/com/hippo/ehviewer/data/GalleryInfo.java +++ b/src/com/hippo/ehviewer/data/GalleryInfo.java @@ -4,28 +4,28 @@ import android.os.Parcel; import android.os.Parcelable; public class GalleryInfo implements Parcelable{ - public String gid; + public int gid; public String token; public String title; public String posted; public int category; public String thumb; public String uploader; - public String rating; + public float rating; public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public GalleryInfo createFromParcel(Parcel source) { GalleryInfo p = new GalleryInfo(); - p.gid = source.readString(); + p.gid = source.readInt(); p.token = source.readString(); p.title = source.readString(); p.posted = source.readString(); p.category = source.readInt(); p.thumb = source.readString(); p.uploader = source.readString(); - p.rating = source.readString(); + p.rating = source.readFloat(); return p; } @@ -42,13 +42,13 @@ public class GalleryInfo implements Parcelable{ @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(gid); + dest.writeInt(gid); dest.writeString(token); dest.writeString(title); dest.writeString(posted); dest.writeInt(category); dest.writeString(thumb); dest.writeString(uploader); - dest.writeString(rating); + dest.writeFloat(rating); } } diff --git a/src/com/hippo/ehviewer/data/PageList.java b/src/com/hippo/ehviewer/data/PreviewList.java similarity index 98% rename from src/com/hippo/ehviewer/data/PageList.java rename to src/com/hippo/ehviewer/data/PreviewList.java index a2bbb2110..4cc297496 100644 --- a/src/com/hippo/ehviewer/data/PageList.java +++ b/src/com/hippo/ehviewer/data/PreviewList.java @@ -2,7 +2,7 @@ package com.hippo.ehviewer.data; import java.util.ArrayList; -public class PageList { +public class PreviewList { public class Row { diff --git a/src/com/hippo/ehviewer/EhClient.java b/src/com/hippo/ehviewer/ehclient/EhClient.java similarity index 92% rename from src/com/hippo/ehviewer/EhClient.java rename to src/com/hippo/ehviewer/ehclient/EhClient.java index 1650ac54c..5759d4636 100644 --- a/src/com/hippo/ehviewer/EhClient.java +++ b/src/com/hippo/ehviewer/ehclient/EhClient.java @@ -1,4 +1,4 @@ -package com.hippo.ehviewer; +package com.hippo.ehviewer.ehclient; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; @@ -20,12 +20,18 @@ import java.util.regex.Pattern; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.http.conn.ConnectTimeoutException; +import org.json.JSONException; +import org.json.JSONObject; +import com.hippo.ehviewer.AppContext; +import com.hippo.ehviewer.DiskCache; +import com.hippo.ehviewer.ListUrls; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.R.string; import com.hippo.ehviewer.activity.DownloadInfo; import com.hippo.ehviewer.data.GalleryDetail; import com.hippo.ehviewer.data.GalleryInfo; -import com.hippo.ehviewer.data.PageList; +import com.hippo.ehviewer.data.PreviewList; import com.hippo.ehviewer.gallery.data.ImageSet; import com.hippo.ehviewer.network.Downloader; import com.hippo.ehviewer.network.HttpHelper; @@ -60,13 +66,17 @@ public class EhClient { private static final int EX = 0x1; private static final int LOFI = 0x2; + public static final String G_API = "http://g.e-hentai.org/api.php"; + public static final String E_API = "http://exhentai.org/api.php"; + public static final long APIUID = 1363542; + public static final String APIKEY = "f4b5407ab1727b9d08d7"; + private static final String loginUrl = "http://forums.e-hentai.org/index.php?act=Login&CODE=01"; private static final String E_HENTAI_LIST_HEADER = "http://g.e-hentai.org/"; private static final String EXHENTAI_LIST_HEADER = "http://exhentai.org/"; public static final String E_HENTAI_DETAIL_HEADER = "http://g.e-hentai.org/g/"; public static final String EXHENTAI_DETAIL_HEADER = "http://exhentai.org/g/"; - public static final String EXHENTAI_PAGE_HEADER = "http://exhentai.org/s/"; @@ -86,7 +96,7 @@ public class EhClient { private AppContext mAppContext; private ThreadPool mThreadPool; - public String getDetailUrl(String gid, String token, int mode) { + public static String getDetailUrl(int gid, String token, int mode) { switch (mode) { case EX: return EH_HEADER + "g/" + gid + "/" + token; @@ -97,7 +107,7 @@ public class EhClient { } } - public String getPageUrl(String gid, String token, int pageNum, int mode) { + public static String getPageUrl(String gid, String token, int pageNum, int mode) { switch (mode) { case EX: return EH_HEADER + "s/" + token + "/" + gid + "-" + pageNum; @@ -108,6 +118,19 @@ public class EhClient { } } + public static int getDetailModeForDownloadMode(int downloadMode) { + switch (downloadMode) { + case com.hippo.ehviewer.data.DownloadInfo.EX: + return EX; + case com.hippo.ehviewer.data.DownloadInfo.LOFI_460x: + case com.hippo.ehviewer.data.DownloadInfo.LOFI_780x: + case com.hippo.ehviewer.data.DownloadInfo.LOFI_980x: + return LOFI; + default: + return G; + } + } + public interface OnLogoutListener { public void onSuccess(); public void onFailure(String eMsg); @@ -135,7 +158,7 @@ public class EhClient { } public interface OnGetPageListListener { - public void onSuccess(Object checkFlag, PageList pageList); + public void onSuccess(Object checkFlag, PreviewList pageList); public void onFailure(Object checkFlag, String eMsg); } @@ -199,6 +222,7 @@ public class EhClient { private static final int GET_MANGA_DETAIL = 0x4; private static final int GET_PAGE_LIST = 0x5; private static final int GET_MANGA_URL = 0x6; + private static final int RATE = 0x7; private static Handler mHandler = new Handler() { @Override @@ -271,6 +295,9 @@ public class EhClient { else listener7.onFailure(getMangaUrlPackage.checkFlag, getMangaUrlPackage.eMsg); break; + + case RATE: + } }; }; @@ -562,7 +589,7 @@ public class EhClient { .compile("/(\\d+)/(\\w+)"); Matcher matcher = pattern.matcher(m.group(7)); if (matcher.find()) { - lmd.gid = matcher.group(1); + lmd.gid = Integer.parseInt(matcher.group(1)); lmd.token = matcher.group(2); } else continue; @@ -576,7 +603,7 @@ public class EhClient { Log.w(TAG, "second is " + temp); lmd.title = temp; } - lmd.rating = getRate(m.group(9)); + lmd.rating = Float.parseFloat(getRate(m.group(9))); lmd.uploader = m.group(10); lmdArray.add(lmd); } @@ -696,53 +723,42 @@ public class EhClient { HttpHelper hp = new HttpHelper(mAppContext); String pageContent = hp.get(url); if (pageContent != null) { - Pattern p = Pattern - .compile("\"]+\">]*alt=\"([\\w|\\-]+)\"[^<>]*/>\"]+\">([^<>]+).+Posted:]*>([\\w|\\-|\\s|:]+)]*>Images:]*>([\\d]+) @ ([\\w|\\.|\\s]+)]*>Resized:]*>([^<>]+)]*>Parent:]*>(?:]*>)?([^<>]+)(?:)?]*>Visible:]*>([^<>]+)]*>Language:]*>([^<>]+)(?:)?]*>(?:)?]*>Rating:]*>]*style=\"([^<>]+)\"[^<>]*>]*>]*>\\(]*>([\\d]+)\\)]*>([^<>]+).+Showing ([\\d|,]+) - ([\\d|,]+) of ([\\d|,]+) images.+]*>(?:]*>)?]*href=\"([^<>\"]+)\"[^<>]*>"); - Matcher m = p.matcher(pageContent); - String offensiveKeystring = "(And if you choose to ignore this warning, you lose all rights to complain about it in the future.)"; - String piningKeyString = "This gallery is pining for the fjords."; - if (m.find()) { - ok = true; - md.category = getType(m.group(1)); - md.uploader = m.group(2); - md.posted = m.group(3); - md.pages = m.group(4); - md.size = m.group(5); - md.resized = m.group(6); - md.parent = m.group(7); - md.visible = m.group(8); - md.language = m.group(9); - md.people = m.group(11); - - Pattern pattern = Pattern.compile("([\\d|\\.]+)"); - Matcher matcher = pattern.matcher(m.group(12)); - if (matcher.find()) - md.rating = matcher.group(1); - else - md.rating = mAppContext.getString(R.string.detail_not_rated); - md.firstPage = m.group(16); - md.previewPerPage = Integer.parseInt(m.group(14).replace(",", - "")) - - Integer.parseInt(m.group(13).replace(",", "")) - + 1; - int total = Integer.parseInt(m.group(15).replace(",", "")); - - md.previewSum = (total + md.previewPerPage - 1) / md.previewPerPage; - - // New pageListArray - md.previewLists = new PageList[md.previewSum]; - // Add page 1 pagelist - PageList pageList = getPageList(pageContent); - md.previewLists[0] = pageList; - md.tags = getTags(pageContent); - } else if (pageContent.contains(offensiveKeystring)) { + + + ParserDetail parser = new ParserDetail(); + int mode = ParserDetail.DETAIL | ParserDetail.TAG + | ParserDetail.PREVIEW_INFO | ParserDetail.PREVIEW; + parser.setMode(mode); + int result = parser.parser(pageContent); + if (result == ParserDetail.OFFENSIVE) { ok = true; md.firstPage = "offensive"; - } else if (pageContent.contains(piningKeyString)) { + } else if (result == ParserDetail.PINING) { ok = true; md.firstPage = "pining"; - } else + } else if ((result & (ParserDetail.DETAIL | ParserDetail.PREVIEW_INFO)) != 0) { + ok = true; + md.category = parser.category; + md.uploader = parser.uploader; + md.posted = parser.posted; + md.pages = parser.pages; + md.size = parser.size; + md.resized = parser.resized; + md.parent = parser.parent; + md.visible = parser.visible; + md.language = parser.language; + md.people = parser.people; + md.rating = parser.rating; + md.firstPage = parser.firstPage; + md.previewPerPage = parser.previewPerPage; + md.previewSum = parser.previewSum; + + md.tags = parser.tags; + md.previewLists = new PreviewList[md.previewSum]; + md.previewLists[0] = parser.previewList; + } else { eMsg = mAppContext.getString(R.string.em_parser_error); + } } else eMsg = hp.getEMsg(); } @@ -783,7 +799,7 @@ public class EhClient { } } if (list.size() == 0) - return null; + return new String[0][0]; String[][] groups = new String[list.size()][]; int i = 0; for (String[] item : list) { @@ -816,11 +832,11 @@ public class EhClient { // Get page list private class GetPageListPackage { public Object checkFlag; - public PageList pageList; + public PreviewList pageList; public OnGetPageListListener listener; public String eMsg; - public GetPageListPackage(Object checkFlag, PageList pageList, OnGetPageListListener listener, + public GetPageListPackage(Object checkFlag, PreviewList pageList, OnGetPageListListener listener, String eMsg) { this.checkFlag = checkFlag; this.pageList = pageList; @@ -832,7 +848,7 @@ public class EhClient { private class GetPageListRunnable implements Runnable { private String url; - public PageList pageList; + public PreviewList pageList; public String eMsg; public GetPageListRunnable(String url) { @@ -876,14 +892,14 @@ public class EhClient { }); } - private PageList getPageList(String pageContent) { - PageList pageList = null; + private PreviewList getPageList(String pageContent) { + PreviewList pageList = null; Pattern p = Pattern .compile("]*class=\"gdtm\"[^<>]*>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*>]*href=\"(.+?)\"[^<>]*>"); Matcher m = p.matcher(pageContent); while (m.find()) { if (pageList == null) - pageList = new PageList(); + pageList = new PreviewList(); pageList.addItem(m.group(3), m.group(4), "0", m.group(1), m.group(2), m.group(5)); } @@ -1466,6 +1482,51 @@ public class EhClient { /********** Use E-hentai API ************/ + public interface OnRateListener { + void onSuccess(float ratingAvg, int ratingCnt); + void onFailure(String eMsg); + } + + public void rate(final int gid, final String token, + final int rating, final OnRateListener listener) { + final JSONObject json = new JSONObject(); + try { + json.put("method", "rategallery"); + json.put("apiuid", APIUID); + json.put("apikey", APIKEY); + json.put("gid", gid); + json.put("token", token); + json.put("rating", rating); + } catch (JSONException e) { + listener.onFailure(e.getMessage()); + return; + } + + new Thread(new Runnable() { + @Override + public void run() { + HttpHelper hp = new HttpHelper(mAppContext); + hp.setOnRespondListener(new HttpHelper.OnRespondListener() { + @Override + public void onSuccess(String pageContext) { + ParserRate parser = new ParserRate(); + if (parser.parser(pageContext)) { + listener.onSuccess(parser.mRatingAvg, parser.mRatingCnt); + } else { + listener.onFailure("parser error"); // TODO + } + } + @Override + public void onFailure(String eMsg) { + listener.onFailure(eMsg); + } + }); + hp.postJson(E_API, json); + } + }).start(); + } + + /* private static class GetGalleryMetadataPackage { public Map lmds; diff --git a/src/com/hippo/ehviewer/ehclient/EhParser.java b/src/com/hippo/ehviewer/ehclient/EhParser.java new file mode 100644 index 000000000..5010569c1 --- /dev/null +++ b/src/com/hippo/ehviewer/ehclient/EhParser.java @@ -0,0 +1,6 @@ +package com.hippo.ehviewer.ehclient; + +public abstract class EhParser { + public Object obj; + abstract boolean parser(String pageContext); +} diff --git a/src/com/hippo/ehviewer/ehclient/ParserDetail.java b/src/com/hippo/ehviewer/ehclient/ParserDetail.java new file mode 100644 index 000000000..921b3968c --- /dev/null +++ b/src/com/hippo/ehviewer/ehclient/ParserDetail.java @@ -0,0 +1,189 @@ +package com.hippo.ehviewer.ehclient; + +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.hippo.ehviewer.ListUrls; +import com.hippo.ehviewer.data.PreviewList; + +public class ParserDetail { + + private static final String OFFENSIVE_STRING = + "(And if you choose to ignore this warning, you lose all rights to complain about it in the future.)"; + private static final String PINING_STRING = + "This gallery is pining for the fjords."; + + public static final int DETAIL = 0x1; + public static final int TAG = 0x2; + public static final int PREVIEW_INFO = 0x4; + public static final int PREVIEW = 0x8; + public static final int OFFENSIVE = 0x10; + public static final int PINING = 0x20; + + private int mMode; + + public int category; + public String uploader; + public String posted; + public int pages; + public String size; + public String resized; + public String parent; + public String visible; + public String language; + public int people; + public float rating; + public String firstPage; + public int previewPerPage; + public int previewSum; + public String[][] tags; + public PreviewList previewList; + + public void setMode(int mode) { + mMode = mode; + } + + public int parser(String pageContent) { + int re = 0; + Pattern p; + Matcher m; + + if (pageContent.contains(OFFENSIVE_STRING)) { + return OFFENSIVE; + } + + if (pageContent.contains(PINING_STRING)) { + return PINING; + } + + // Get detail + if ((mMode & DETAIL) != 0) { + p = Pattern + .compile("\"]+\">]*alt=\"([\\w|\\-]+)\"[^<>]*/>\"]+\">([^<>]+).+Posted:]*>([\\w|\\-|\\s|:]+)]*>Images:]*>([\\d]+) @ ([\\w|\\.|\\s]+)]*>Resized:]*>([^<>]+)]*>Parent:]*>(?:]*>)?([^<>]+)(?:)?]*>Visible:]*>([^<>]+)]*>Language:]*>([^<>]+)(?:)?]*>(?:)?]*>Rating:]*>]*style=\"([^<>]+)\"[^<>]*>]*>]*>\\(]*>([\\d]+)\\)]*>([^<>]+).+Showing ([\\d|,]+) - ([\\d|,]+) of ([\\d|,]+) images.+]*>(?:]*>)?]*href=\"([^<>\"]+)\"[^<>]*>"); + m = p.matcher(pageContent); + if (m.find()) { + re |= DETAIL; + category = getType(m.group(1)); + uploader = m.group(2); + posted = m.group(3); + pages = Integer.parseInt(m.group(4)); + size = m.group(5); + resized = m.group(6); + parent = m.group(7); + visible = m.group(8); + language = m.group(9); + people = Integer.parseInt(m.group(11)); + + Pattern pattern = Pattern.compile("([\\d|\\.]+)"); + Matcher matcher = pattern.matcher(m.group(12)); + if (matcher.find()) + rating = Float.parseFloat(matcher.group(1)); + else + rating = Float.NaN; + + firstPage = m.group(16); + } + } + // Get tag + if ((mMode & TAG) != 0) { + ArrayList list = new ArrayList(); + p = Pattern + .compile("]*>([^<>]+):(?:]*>]*>[^<>]*[^<>]*]*>\\d+[^<>]*)+"); + m = p.matcher(pageContent); + while (m.find()) { + re |= TAG; + String groupName = m.group(1); + String[] group = getTagGroup(m.group(0)); + if (groupName != null && group != null) { + group[0] = groupName; + list.add(group); + } + } + tags = new String[list.size()][]; + int i = 0; + for (String[] item : list) { + tags[i] = item; + i++; + } + } + + // Get preview info + if ((mMode & PREVIEW_INFO) != 0) { + p = Pattern.compile("Showing ([\\d|,]+) - ([\\d|,]+) of ([\\d|,]+) images"); + m = p.matcher(pageContent); + if (m.find()) { + re |= PREVIEW_INFO; + previewPerPage = Integer.parseInt(m.group(2).replace(",", + "")) + - Integer.parseInt(m.group(1).replace(",", "")) + + 1; + int total = Integer.parseInt(m.group(3).replace(",", "")); + previewSum = (total + previewPerPage - 1) / previewPerPage; + } + } + // Get preview + if ((mMode & PREVIEW) != 0) { + p = Pattern + .compile("]*class=\"gdtm\"[^<>]*>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*>]*href=\"(.+?)\"[^<>]*>"); + m = p.matcher(pageContent); + while (m.find()) { + if (previewList == null) { + re |= PREVIEW; + previewList = new PreviewList(); + } + previewList.addItem(m.group(3), m.group(4), "0", m.group(1), + m.group(2), m.group(5)); + } + } + + return re; + } + + private String[] getTagGroup(String pageContent) { + ArrayList list = new ArrayList(); + Pattern p = Pattern.compile("]*>([^<>]+)"); + Matcher m = p.matcher(pageContent); + while (m.find()) { + String str = m.group(1); + if (str != null) + list.add(str); + } + if (list.size() == 0) + return null; + String[] strs = new String[list.size() + 1]; + int i = 1; + for (String str : list) { + strs[i] = str; + i++; + } + return strs; + } + + private int getType(String rawType) { + int type; + if (rawType.equalsIgnoreCase("doujinshi")) + type = ListUrls.DOUJINSHI; + else if (rawType.equalsIgnoreCase("manga")) + type = ListUrls.MANGA; + else if (rawType.equalsIgnoreCase("artistcg")) + type = ListUrls.ARTIST_CG; + else if (rawType.equalsIgnoreCase("gamecg")) + type = ListUrls.GAME_CG; + else if (rawType.equalsIgnoreCase("western")) + type = ListUrls.WESTERN; + else if (rawType.equalsIgnoreCase("non-h")) + type = ListUrls.NON_H; + else if (rawType.equalsIgnoreCase("imageset")) + type = ListUrls.IMAGE_SET; + else if (rawType.equalsIgnoreCase("cosplay")) + type = ListUrls.COSPLAY; + else if (rawType.equalsIgnoreCase("asianporn")) + type = ListUrls.ASIAN_PORN; + else if (rawType.equalsIgnoreCase("misc")) + type = ListUrls.MISC; + else + type = ListUrls.UNKNOWN; + return type; + } +} diff --git a/src/com/hippo/ehviewer/ehclient/ParserRate.java b/src/com/hippo/ehviewer/ehclient/ParserRate.java new file mode 100644 index 000000000..307ab445a --- /dev/null +++ b/src/com/hippo/ehviewer/ehclient/ParserRate.java @@ -0,0 +1,22 @@ +package com.hippo.ehviewer.ehclient; + +import org.json.JSONException; +import org.json.JSONObject; + +public class ParserRate extends EhParser { + + public float mRatingAvg; + public int mRatingCnt; + + @Override + boolean parser(String pageContext) { + try { + JSONObject jsonObject = new JSONObject(pageContext); + mRatingAvg = (float)jsonObject.getDouble("rating_avg"); + mRatingCnt = jsonObject.getInt("rating_cnt"); + return true; + } catch (JSONException e) { + return false; + } + } +} diff --git a/src/com/hippo/ehviewer/network/HttpHelper.java b/src/com/hippo/ehviewer/network/HttpHelper.java index c384a06dc..aafcf796c 100644 --- a/src/com/hippo/ehviewer/network/HttpHelper.java +++ b/src/com/hippo/ehviewer/network/HttpHelper.java @@ -20,17 +20,21 @@ import java.util.Map; import java.util.zip.GZIPInputStream; import org.apache.http.conn.ConnectTimeoutException; +import org.json.JSONObject; import com.hippo.ehviewer.DiskCache; import com.hippo.ehviewer.R; import com.hippo.ehviewer.exception.RedirectionException; import com.hippo.ehviewer.exception.ResponseCodeException; +import com.hippo.ehviewer.util.Constants; import com.hippo.ehviewer.util.Ui; import com.hippo.ehviewer.util.Util; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.os.Handler; +import android.os.Message; import android.support.v4.util.LruCache; import com.hippo.ehviewer.util.Log; @@ -47,8 +51,40 @@ public class HttpHelper { private static String DEFAULT_CHARSET = "utf-8"; private static String CHARSET_KEY = "charset="; + class Package { + OnRespondListener listener; + String str; + } + + private static Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + Package p = (Package)msg.obj; + OnRespondListener listener = p.listener; + String str = p.str; + switch (msg.what) { + case Constants.TRUE: + listener.onSuccess(str); + break; + case Constants.FALSE: + listener.onFailure(str); + break; + } + } + }; + private Context mContext; private Exception mException; + private OnRespondListener mListener; + + public interface OnRespondListener { + void onSuccess(String pageContext); + void onFailure(String eMsg); + } + + public void setOnRespondListener(OnRespondListener l) { + mListener = l; + } public HttpHelper(Context context) { mContext = context; @@ -136,7 +172,9 @@ public class HttpHelper { int redirectionCount = 0; URL url = null; HttpURLConnection conn = null; - + Message msg = null; + if (mListener != null) + msg = new Message(); try { Log.d(TAG, "Http get " + urlStr); @@ -156,7 +194,16 @@ public class HttpHelper { switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: - return getPageContext(conn); + String pageContext = getPageContext(conn); + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = pageContext; + msg.obj = p; + msg.what = Constants.TRUE; + mHandler.sendMessage(msg); + } + return pageContext; case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: @@ -173,6 +220,15 @@ public class HttpHelper { } catch (Exception e) { mException = e; e.printStackTrace(); + + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = getEMsg(); + msg.obj = p; + msg.what = Constants.FALSE; + mHandler.sendMessage(msg); + } return null; } finally { if (conn != null) @@ -190,6 +246,10 @@ public class HttpHelper { URL url = null; HttpURLConnection conn = null; + Message msg = null; + if (mListener != null) + msg = new Message(); + try { Log.d(TAG, "Http post " + urlStr); @@ -231,7 +291,16 @@ public class HttpHelper { switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: - return getPageContext(conn); + String pageContext = getPageContext(conn); + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = pageContext; + msg.obj = p; + msg.what = Constants.TRUE; + mHandler.sendMessage(msg); + } + return pageContext; case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: @@ -248,6 +317,15 @@ public class HttpHelper { } catch (Exception e) { mException = e; e.printStackTrace(); + + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = getEMsg(); + msg.obj = p; + msg.what = Constants.FALSE; + mHandler.sendMessage(msg); + } return null; } finally { if (conn != null) @@ -265,6 +343,10 @@ public class HttpHelper { URL url = null; HttpURLConnection conn = null; + Message msg = null; + if (mListener != null) + msg = new Message(); + try { Log.d(TAG, "Http post " + urlStr); @@ -294,7 +376,16 @@ public class HttpHelper { switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: - return getPageContext(conn); + String pageContext = getPageContext(conn); + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = pageContext; + msg.obj = p; + msg.what = Constants.TRUE; + mHandler.sendMessage(msg); + } + return pageContext; case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: @@ -311,6 +402,15 @@ public class HttpHelper { } catch (Exception e) { mException = e; e.printStackTrace(); + + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = getEMsg(); + msg.obj = p; + msg.what = Constants.FALSE; + mHandler.sendMessage(msg); + } return null; } finally { if (conn != null) @@ -322,13 +422,17 @@ public class HttpHelper { } - public String postJson(String urlStr, String jsonStr) { + public String postJson(String urlStr, JSONObject json) { mException = null; int redirectionCount = 0; URL url = null; HttpURLConnection conn = null; + Message msg = null; + if (mListener != null) + msg = new Message(); + try { Log.d(TAG, "Http post " + urlStr); @@ -350,7 +454,7 @@ public class HttpHelper { conn.setRequestProperty("Connection", "close"); DataOutputStream out = new DataOutputStream(conn.getOutputStream()); - out.writeBytes(jsonStr); + out.writeBytes(json.toString()); out.flush(); out.close(); @@ -360,7 +464,16 @@ public class HttpHelper { switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: - return getPageContext(conn); + String pageContext = getPageContext(conn); + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = pageContext; + msg.obj = p; + msg.what = Constants.TRUE; + mHandler.sendMessage(msg); + } + return pageContext; case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: @@ -377,6 +490,15 @@ public class HttpHelper { } catch (Exception e) { mException = e; e.printStackTrace(); + + if (msg != null) { + Package p = new Package(); + p.listener = mListener; + p.str = getEMsg(); + msg.obj = p; + msg.what = Constants.FALSE; + mHandler.sendMessage(msg); + } return null; } finally { if (conn != null) diff --git a/src/com/hippo/ehviewer/service/DownloadService.java b/src/com/hippo/ehviewer/service/DownloadService.java index 3bc762361..4f9a026f6 100644 --- a/src/com/hippo/ehviewer/service/DownloadService.java +++ b/src/com/hippo/ehviewer/service/DownloadService.java @@ -4,11 +4,11 @@ import java.util.HashMap; import java.util.Map; import com.hippo.ehviewer.AppContext; -import com.hippo.ehviewer.EhClient; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.EhClient.DownloadMangaManager; import com.hippo.ehviewer.activity.DownloadActivity; import com.hippo.ehviewer.activity.DownloadInfo; +import com.hippo.ehviewer.ehclient.EhClient; +import com.hippo.ehviewer.ehclient.EhClient.DownloadMangaManager; import com.hippo.ehviewer.util.Download; import android.app.Notification; diff --git a/src/com/hippo/ehviewer/util/Constants.java b/src/com/hippo/ehviewer/util/Constants.java new file mode 100644 index 000000000..b554e2acd --- /dev/null +++ b/src/com/hippo/ehviewer/util/Constants.java @@ -0,0 +1,6 @@ +package com.hippo.ehviewer.util; + +public class Constants { + public static final int FALSE = 0; + public static final int TRUE = 1; +} diff --git a/src/com/hippo/ehviewer/util/Ui.java b/src/com/hippo/ehviewer/util/Ui.java index aeeca7664..5a48a5bf3 100644 --- a/src/com/hippo/ehviewer/util/Ui.java +++ b/src/com/hippo/ehviewer/util/Ui.java @@ -196,26 +196,15 @@ public class Ui { * @param rawRateString */ public static void addStar(ViewGroup viewGroup, - String rawRateString) { + float rawRate) { if (!mInit) { throw new IllegalStateException("Please init Ui first."); } - if (viewGroup == null || rawRateString == null) + if (viewGroup == null) return; viewGroup.removeAllViews(); - float num = 0; - try{ - num = Float.parseFloat(rawRateString); - } catch (Exception e) { - for (int i = 0; i < 5; i++) { - ImageView IvStarEmpty = new ImageView(mContext); - IvStarEmpty.setImageResource(R.drawable.star_empty); - viewGroup.addView(IvStarEmpty); - } - return; - } - int leve = (int)((num + 0.4999)/0.5); + int leve = (int)((rawRate + 0.4999)/0.5); int starNum = 5; for (int i = 0; i < leve/2; i++) { diff --git a/src/com/hippo/ehviewer/view/OlImageView.java b/src/com/hippo/ehviewer/view/OlImageView.java index a0e1937ba..292b3e0b9 100644 --- a/src/com/hippo/ehviewer/view/OlImageView.java +++ b/src/com/hippo/ehviewer/view/OlImageView.java @@ -1,7 +1,7 @@ package com.hippo.ehviewer.view; import com.hippo.ehviewer.DiskCache; -import com.hippo.ehviewer.EhClient; +import com.hippo.ehviewer.ehclient.EhClient; import com.hippo.ehviewer.util.Util; import android.content.Context; diff --git a/src/com/hippo/ehviewer/widget/ButtonsDialogBuilder.java b/src/com/hippo/ehviewer/widget/ButtonsDialogBuilder.java new file mode 100644 index 000000000..4e8bd7b56 --- /dev/null +++ b/src/com/hippo/ehviewer/widget/ButtonsDialogBuilder.java @@ -0,0 +1,87 @@ +package com.hippo.ehviewer.widget; + +import java.util.LinkedList; +import java.util.List; + +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.view.AlertButton; + +import android.app.AlertDialog; +import android.content.Context; +import android.graphics.Color; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class ButtonsDialogBuilder extends AlertDialog.Builder { + + private static final float WEIGHT = 1.0f; + + private Context mContext; + private View mView; + private LinearLayout mRootView; + private LinearLayout mContainer; + + private List mButtonList; + + public ButtonsDialogBuilder(Context context) { + super(context); + mContext = context; + mButtonList = new LinkedList(); + LayoutInflater inflater = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mView = inflater.inflate(R.layout.buttons_dialog, null); + mRootView = (LinearLayout)mView.findViewById(R.id.button_root); + mContainer = new LinearLayout(mContext); + mContainer.setOrientation(LinearLayout.HORIZONTAL); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); + mRootView.addView(mContainer, lp); + super.setView(mView); + } + + /** + * Set the title using the given resource id. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public ButtonsDialogBuilder setTitle(int titleId) { + setTitle(mContext.getText(titleId)); + return this; + } + + /** + * Set the title displayed in the {@link Dialog}. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public ButtonsDialogBuilder setTitle(CharSequence title) { + TextView titleView = (TextView)mView.findViewById(R.id.title); + titleView.setVisibility(View.VISIBLE); + titleView.setText(title); + return this; + } + + public ButtonsDialogBuilder addButton(AlertButton button) { + // TODO + button.setBackgroundColor(Color.WHITE); + button.setTextColor(Color.BLACK); + mButtonList.add(button); + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + 0, LinearLayout.LayoutParams.MATCH_PARENT); + lp.weight = WEIGHT; + mContainer.addView(button, lp); + return this; + } + + @Override + public AlertDialog create() { + AlertDialog dialog = super.create(); + for (AlertButton ab : mButtonList) + ab.dialog = dialog; + return dialog; + } +} diff --git a/src/com/hippo/ehviewer/widget/DialogBuilder.java b/src/com/hippo/ehviewer/widget/DialogBuilder.java index c15b9409e..3f47a7eed 100644 --- a/src/com/hippo/ehviewer/widget/DialogBuilder.java +++ b/src/com/hippo/ehviewer/widget/DialogBuilder.java @@ -1,266 +1,267 @@ -package com.hippo.ehviewer.widget; - -import com.hippo.ehviewer.R; -import com.hippo.ehviewer.view.AlertButton; - -import android.app.AlertDialog; -import android.content.Context; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.ScrollView; -import android.widget.TextView; - -public class DialogBuilder extends AlertDialog.Builder{ - private View mView; - private Context mContext; - public DialogBuilder(Context context) { - super(context); - mContext = context; - LayoutInflater inflater = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - mView = inflater.inflate(R.layout.dialog, null); - super.setView(mView); - } - - /** - * Set the title using the given resource id. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - @Override - public DialogBuilder setTitle(int titleId) { - setTitle(mContext.getText(titleId)); - return this; - } - - /** - * Set the title displayed in the {@link Dialog}. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - @Override - public DialogBuilder setTitle(CharSequence title) { - TextView titleView = (TextView)mView.findViewById(R.id.title); - titleView.setVisibility(View.VISIBLE); - titleView.setText(title); - return this; - } - - /** - * Set the message to display using the given resource id. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - @Override - public DialogBuilder setMessage(int messageId) { - setMessage(mContext.getText(messageId)); - return this; - } - - /** - * Set the message to display. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - @Override - public DialogBuilder setMessage(CharSequence message) { - ScrollView scrollView = (ScrollView)mView.findViewById(R.id.scroll_view); - scrollView.setVisibility(View.VISIBLE); - TextView messageView = (TextView)mView.findViewById(R.id.message); - messageView.setVisibility(View.VISIBLE); - messageView.setText(message); - return this; - } - - public DialogBuilder setLongMessage(int messageId) { - setLongMessage(mContext.getText(messageId)); - return this; - } - - public DialogBuilder setLongMessage(CharSequence message) { - ScrollView scrollView = (ScrollView)mView.findViewById(R.id.scroll_view); - scrollView.setVisibility(View.VISIBLE); - TextView messageView = (TextView)mView.findViewById(R.id.message); - messageView.setVisibility(View.VISIBLE); - messageView.setText(message); - LinearLayout.LayoutParams lp = - (LinearLayout.LayoutParams)messageView.getLayoutParams(); - lp.setMargins(lp.leftMargin, lp.topMargin/3, - lp.rightMargin, lp.bottomMargin/3); - return this; - } - - /** - * Set the view to display in that dialog. - * @return - */ - public DialogBuilder setView(View view, boolean center) { - ScrollView scrollView = (ScrollView)mView.findViewById(R.id.scroll_view); - scrollView.setVisibility(View.VISIBLE); - LinearLayout customLayout = (LinearLayout)mView.findViewById(R.id.custom); - customLayout.setVisibility(View.VISIBLE); - if (center) { - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( - LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); - lp.gravity = Gravity.CENTER; - customLayout.addView(view, lp); - } else { - LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( - LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); - customLayout.addView(view, lp); - } - return this; - } - - /** - * Set a listener to be invoked when the positive button of the dialog is pressed. - * @param textId The resource id of the text to display in the positive button - * @param listener The View.OnClickListener to use. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setPositiveButton(int textId, final View.OnClickListener listener) { - setPositiveButton(mContext.getText(textId), listener); - return this; - } - - /** - * Set a listener to be invoked when the positive button of the dialog is pressed. - * @param text The text to display in the positive button - * @param listener The View.OnClickListener to use. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setPositiveButton(CharSequence text, final View.OnClickListener listener) { - Button button = (Button)mView.findViewById(R.id.positive_button); - button.setVisibility(View.VISIBLE); - button.setText(text); - button.setOnClickListener(listener); - return this; - } - - /** - * Set a listener to be invoked when the negative button of the dialog is pressed. - * @param textId The resource id of the text to display in the negative button - * @param listener The DialogInterface.OnClickListener to use. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setNegativeButton(int textId, final View.OnClickListener listener) { - setNegativeButton(mContext.getText(textId), listener); - return this; - } - - /** - * Set a listener to be invoked when the negative button of the dialog is pressed. - * @param text The text to display in the negative button - * @param listener The DialogInterface.OnClickListener to use. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setNegativeButton(CharSequence text, final View.OnClickListener listener) { - Button button = (Button)mView.findViewById(R.id.negative_button); - button.setVisibility(View.VISIBLE); - button.setText(text); - button.setOnClickListener(listener); - return this; - } - - /** - * Set a listener to be invoked when the neutral button of the dialog is pressed. - * @param textId The resource id of the text to display in the neutral button - * @param listener The DialogInterface.OnClickListener to use. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setNeutralButton(int textId, final View.OnClickListener listener) { - setNeutralButton(mContext.getText(textId), listener); - return this; - } - - /** - * Set a listener to be invoked when the neutral button of the dialog is pressed. - * @param text The text to display in the neutral button - * @param listener The View.DialogInterface.OnClickListener to use. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setNeutralButton(CharSequence text, final View.OnClickListener listener) { - Button button = (Button)mView.findViewById(R.id.neutral_button); - button.setVisibility(View.VISIBLE); - button.setText(text); - button.setOnClickListener(listener); - return this; - } - - /** - * Sets whether the dialog is cancelable or not. Default is true. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - @Override - public DialogBuilder setCancelable(boolean cancelable) { - super.setCancelable(cancelable); - return this; - } - - /** - * Set a list of items to be displayed in the dialog as the content, you will be notified of the - * selected item via the supplied listener. This should be an array type i.e. R.array.foo - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setItems(int itemsId, AdapterView.OnItemClickListener listener) { - setItems(mContext.getResources().getTextArray(itemsId), listener); - return this; - } - - /** - * Set a list of items to be displayed in the dialog as the content, you will be notified of the - * selected item via the supplied listener. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setItems(CharSequence[] items, AdapterView.OnItemClickListener listener) { - setAdapter(new ArrayAdapter(mContext, - R.layout.list_item_text, items), listener); - return this; - } - - /** - * Set a list of items, which are supplied by the given {@link ListAdapter}, to be - * displayed in the dialog as the content, you will be notified of the - * selected item via the supplied listener. - * - * @param adapter The {@link ListAdapter} to supply the list of items - * @param listener The listener that will be called when an item is clicked. - * - * @return This Builder object to allow for chaining of calls to set methods - */ - public DialogBuilder setAdapter(ListAdapter adapter, AdapterView.OnItemClickListener listener) { - ListView listView = (ListView)mView.findViewById(R.id.list); - listView.setVisibility(View.VISIBLE); - listView.setAdapter(adapter); - listView.setOnItemClickListener(listener); - return this; - } - - public AlertDialog create() { - AlertDialog dialog = super.create(); - AlertButton button = (AlertButton)mView.findViewById(R.id.positive_button); - button.dialog = dialog; - button = (AlertButton)mView.findViewById(R.id.negative_button); - button.dialog = dialog; - button = (AlertButton)mView.findViewById(R.id.neutral_button); - button.dialog = dialog; - return dialog; - } -} +package com.hippo.ehviewer.widget; + +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.view.AlertButton; + +import android.app.AlertDialog; +import android.content.Context; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup.LayoutParams; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.ScrollView; +import android.widget.TextView; + +public class DialogBuilder extends AlertDialog.Builder { + private View mView; + private Context mContext; + public DialogBuilder(Context context) { + super(context); + mContext = context; + LayoutInflater inflater = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mView = inflater.inflate(R.layout.dialog, null); + super.setView(mView); + } + + /** + * Set the title using the given resource id. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public DialogBuilder setTitle(int titleId) { + setTitle(mContext.getText(titleId)); + return this; + } + + /** + * Set the title displayed in the {@link Dialog}. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public DialogBuilder setTitle(CharSequence title) { + TextView titleView = (TextView)mView.findViewById(R.id.title); + titleView.setVisibility(View.VISIBLE); + titleView.setText(title); + return this; + } + + /** + * Set the message to display using the given resource id. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public DialogBuilder setMessage(int messageId) { + setMessage(mContext.getText(messageId)); + return this; + } + + /** + * Set the message to display. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public DialogBuilder setMessage(CharSequence message) { + ScrollView scrollView = (ScrollView)mView.findViewById(R.id.scroll_view); + scrollView.setVisibility(View.VISIBLE); + TextView messageView = (TextView)mView.findViewById(R.id.message); + messageView.setVisibility(View.VISIBLE); + messageView.setText(message); + return this; + } + + public DialogBuilder setLongMessage(int messageId) { + setLongMessage(mContext.getText(messageId)); + return this; + } + + public DialogBuilder setLongMessage(CharSequence message) { + ScrollView scrollView = (ScrollView)mView.findViewById(R.id.scroll_view); + scrollView.setVisibility(View.VISIBLE); + TextView messageView = (TextView)mView.findViewById(R.id.message); + messageView.setVisibility(View.VISIBLE); + messageView.setText(message); + LinearLayout.LayoutParams lp = + (LinearLayout.LayoutParams)messageView.getLayoutParams(); + lp.setMargins(lp.leftMargin, lp.topMargin/3, + lp.rightMargin, lp.bottomMargin/3); + return this; + } + + /** + * Set the view to display in that dialog. + * @return + */ + public DialogBuilder setView(View view, boolean center) { + ScrollView scrollView = (ScrollView)mView.findViewById(R.id.scroll_view); + scrollView.setVisibility(View.VISIBLE); + LinearLayout customLayout = (LinearLayout)mView.findViewById(R.id.custom); + customLayout.setVisibility(View.VISIBLE); + if (center) { + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + lp.gravity = Gravity.CENTER; + customLayout.addView(view, lp); + } else { + LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( + LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); + customLayout.addView(view, lp); + } + return this; + } + + /** + * Set a listener to be invoked when the positive button of the dialog is pressed. + * @param textId The resource id of the text to display in the positive button + * @param listener The View.OnClickListener to use. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setPositiveButton(int textId, final View.OnClickListener listener) { + setPositiveButton(mContext.getText(textId), listener); + return this; + } + + /** + * Set a listener to be invoked when the positive button of the dialog is pressed. + * @param text The text to display in the positive button + * @param listener The View.OnClickListener to use. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setPositiveButton(CharSequence text, final View.OnClickListener listener) { + Button button = (Button)mView.findViewById(R.id.positive_button); + button.setVisibility(View.VISIBLE); + button.setText(text); + button.setOnClickListener(listener); + return this; + } + + /** + * Set a listener to be invoked when the negative button of the dialog is pressed. + * @param textId The resource id of the text to display in the negative button + * @param listener The DialogInterface.OnClickListener to use. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setNegativeButton(int textId, final View.OnClickListener listener) { + setNegativeButton(mContext.getText(textId), listener); + return this; + } + + /** + * Set a listener to be invoked when the negative button of the dialog is pressed. + * @param text The text to display in the negative button + * @param listener The DialogInterface.OnClickListener to use. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setNegativeButton(CharSequence text, final View.OnClickListener listener) { + Button button = (Button)mView.findViewById(R.id.negative_button); + button.setVisibility(View.VISIBLE); + button.setText(text); + button.setOnClickListener(listener); + return this; + } + + /** + * Set a listener to be invoked when the neutral button of the dialog is pressed. + * @param textId The resource id of the text to display in the neutral button + * @param listener The DialogInterface.OnClickListener to use. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setNeutralButton(int textId, final View.OnClickListener listener) { + setNeutralButton(mContext.getText(textId), listener); + return this; + } + + /** + * Set a listener to be invoked when the neutral button of the dialog is pressed. + * @param text The text to display in the neutral button + * @param listener The View.DialogInterface.OnClickListener to use. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setNeutralButton(CharSequence text, final View.OnClickListener listener) { + Button button = (Button)mView.findViewById(R.id.neutral_button); + button.setVisibility(View.VISIBLE); + button.setText(text); + button.setOnClickListener(listener); + return this; + } + + /** + * Sets whether the dialog is cancelable or not. Default is true. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + @Override + public DialogBuilder setCancelable(boolean cancelable) { + super.setCancelable(cancelable); + return this; + } + + /** + * Set a list of items to be displayed in the dialog as the content, you will be notified of the + * selected item via the supplied listener. This should be an array type i.e. R.array.foo + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setItems(int itemsId, AdapterView.OnItemClickListener listener) { + setItems(mContext.getResources().getTextArray(itemsId), listener); + return this; + } + + /** + * Set a list of items to be displayed in the dialog as the content, you will be notified of the + * selected item via the supplied listener. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setItems(CharSequence[] items, AdapterView.OnItemClickListener listener) { + setAdapter(new ArrayAdapter(mContext, + R.layout.list_item_text, items), listener); + return this; + } + + /** + * Set a list of items, which are supplied by the given {@link ListAdapter}, to be + * displayed in the dialog as the content, you will be notified of the + * selected item via the supplied listener. + * + * @param adapter The {@link ListAdapter} to supply the list of items + * @param listener The listener that will be called when an item is clicked. + * + * @return This Builder object to allow for chaining of calls to set methods + */ + public DialogBuilder setAdapter(ListAdapter adapter, AdapterView.OnItemClickListener listener) { + ListView listView = (ListView)mView.findViewById(R.id.list); + listView.setVisibility(View.VISIBLE); + listView.setAdapter(adapter); + listView.setOnItemClickListener(listener); + return this; + } + + @Override + public AlertDialog create() { + AlertDialog dialog = super.create(); + AlertButton button = (AlertButton)mView.findViewById(R.id.positive_button); + button.dialog = dialog; + button = (AlertButton)mView.findViewById(R.id.negative_button); + button.dialog = dialog; + button = (AlertButton)mView.findViewById(R.id.neutral_button); + button.dialog = dialog; + return dialog; + } +}
Showing ([\\d|,]+) - ([\\d|,]+) of ([\\d|,]+) images
(And if you choose to ignore this warning, you lose all rights to complain about it in the future.)
This gallery is pining for the fjords.