watobo 0.9.21 → 0.9.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +46 -1
  3. data/bin/nfq_server.rb +0 -9
  4. data/bin/watobo_gui.rb +3 -13
  5. data/custom-views/prettify-json.rb +9 -18
  6. data/icons/watobo.ico +0 -0
  7. data/icons/watobo.ico.old +0 -0
  8. data/lib/watobo.rb +10 -19
  9. data/lib/watobo/adapters.rb +5 -14
  10. data/lib/watobo/adapters/data_store.rb +50 -59
  11. data/lib/watobo/adapters/file/file_store.rb +287 -296
  12. data/lib/watobo/adapters/file/marshal_store.rb +293 -296
  13. data/lib/watobo/adapters/session_store.rb +5 -14
  14. data/lib/watobo/ca.rb +1 -10
  15. data/lib/watobo/config.rb +197 -206
  16. data/lib/watobo/constants.rb +0 -9
  17. data/lib/watobo/core.rb +3 -12
  18. data/lib/watobo/core/active_check.rb +72 -135
  19. data/lib/watobo/core/active_checks.rb +49 -58
  20. data/lib/watobo/core/ca.rb +369 -389
  21. data/lib/watobo/core/cert_store.rb +34 -43
  22. data/lib/watobo/core/chat.rb +92 -101
  23. data/lib/watobo/core/chats.rb +271 -280
  24. data/lib/watobo/core/client_cert_store.rb +106 -35
  25. data/lib/watobo/core/conversation.rb +48 -57
  26. data/lib/watobo/core/cookie.rb +23 -32
  27. data/lib/watobo/core/egress_handlers.rb +98 -0
  28. data/lib/watobo/core/finding.rb +66 -75
  29. data/lib/watobo/core/findings.rb +107 -114
  30. data/lib/watobo/core/forwarding_proxy.rb +13 -22
  31. data/lib/watobo/core/fuzz_gen.rb +0 -9
  32. data/lib/watobo/core/intercept_carver.rb +166 -177
  33. data/lib/watobo/core/intercept_filter.rb +235 -244
  34. data/lib/watobo/core/interceptor.rb +98 -107
  35. data/lib/watobo/core/min_class.rb +4 -13
  36. data/lib/watobo/core/netfilter_queue.rb +170 -179
  37. data/lib/watobo/core/ott_cache.rb +132 -141
  38. data/lib/watobo/core/parameter.rb +43 -52
  39. data/lib/watobo/core/passive_check.rb +103 -102
  40. data/lib/watobo/core/passive_checks.rb +48 -57
  41. data/lib/watobo/core/passive_scanner.rb +54 -55
  42. data/lib/watobo/core/plugin.rb +11 -20
  43. data/lib/watobo/core/project.rb +3 -9
  44. data/lib/watobo/core/proxy.rb +43 -52
  45. data/lib/watobo/core/request.rb +125 -123
  46. data/lib/watobo/core/response.rb +44 -53
  47. data/lib/watobo/core/scanner.rb +0 -9
  48. data/lib/watobo/core/scanner3.rb +405 -414
  49. data/lib/watobo/core/scope.rb +83 -92
  50. data/lib/watobo/core/session.rb +1043 -1026
  51. data/lib/watobo/core/sid_cache.rb +98 -107
  52. data/lib/watobo/core/subscriber.rb +25 -34
  53. data/lib/watobo/defaults.rb +21 -30
  54. data/lib/watobo/external/diff/lcs.rb +0 -9
  55. data/lib/watobo/external/diff/lcs/array.rb +0 -9
  56. data/lib/watobo/external/diff/lcs/block.rb +0 -9
  57. data/lib/watobo/external/diff/lcs/callbacks.rb +0 -9
  58. data/lib/watobo/external/diff/lcs/change.rb +0 -9
  59. data/lib/watobo/external/diff/lcs/hunk.rb +0 -9
  60. data/lib/watobo/external/diff/lcs/ldiff.rb +0 -9
  61. data/lib/watobo/external/diff/lcs/string.rb +0 -9
  62. data/lib/watobo/externals.rb +6 -15
  63. data/lib/watobo/framework.rb +4 -13
  64. data/lib/watobo/framework/create_project.rb +60 -69
  65. data/lib/watobo/framework/init.rb +0 -9
  66. data/lib/watobo/framework/init_modules.rb +0 -9
  67. data/lib/watobo/framework/license_text.rb +28 -37
  68. data/lib/watobo/framework/load_chat.rb +13 -22
  69. data/lib/watobo/gui.rb +132 -123
  70. data/lib/watobo/gui/about_watobo.rb +0 -9
  71. data/lib/watobo/gui/browser_preview.rb +0 -9
  72. data/lib/watobo/gui/certificate_dialog.rb +0 -9
  73. data/lib/watobo/gui/chat_diff.rb +0 -9
  74. data/lib/watobo/gui/chatviewer_frame.rb +73 -72
  75. data/lib/watobo/gui/checkboxtree.rb +0 -9
  76. data/lib/watobo/gui/checks_policy_frame.rb +0 -9
  77. data/lib/watobo/gui/client_cert_dialog.rb +96 -87
  78. data/lib/watobo/gui/confirm_scan_dialog.rb +0 -9
  79. data/lib/watobo/gui/conversation_table.rb +158 -164
  80. data/lib/watobo/gui/conversation_table_ctrl.rb +207 -216
  81. data/lib/watobo/gui/conversation_table_ctrl2.rb +373 -382
  82. data/lib/watobo/gui/csrf_token_dialog.rb +0 -9
  83. data/lib/watobo/gui/custom_viewer.rb +374 -383
  84. data/lib/watobo/gui/dashboard.rb +296 -303
  85. data/lib/watobo/gui/define_scope_frame.rb +0 -9
  86. data/lib/watobo/gui/differ_frame.rb +215 -224
  87. data/lib/watobo/gui/edit_comment.rb +0 -9
  88. data/lib/watobo/gui/edit_scope_dialog.rb +0 -9
  89. data/lib/watobo/gui/export_dialog.rb +104 -113
  90. data/lib/watobo/gui/finding_info.rb +0 -9
  91. data/lib/watobo/gui/findings_tree.rb +210 -217
  92. data/lib/watobo/gui/full_scan_dialog.rb +0 -9
  93. data/lib/watobo/gui/fuzzer_gui.rb +1295 -1313
  94. data/lib/watobo/gui/fxsave_thread.rb +14 -0
  95. data/lib/watobo/gui/goto_url_dialog.rb +70 -79
  96. data/lib/watobo/gui/hex_viewer.rb +0 -9
  97. data/lib/watobo/gui/html_viewer.rb +287 -296
  98. data/lib/watobo/gui/intercept_filter_dialog.rb +188 -197
  99. data/lib/watobo/gui/interceptor_gui.rb +1041 -1051
  100. data/lib/watobo/gui/interceptor_settings_dialog.rb +0 -9
  101. data/lib/watobo/gui/json_viewer.rb +287 -0
  102. data/lib/watobo/gui/list_box.rb +101 -110
  103. data/lib/watobo/gui/log_file_viewer.rb +32 -41
  104. data/lib/watobo/gui/log_viewer.rb +83 -88
  105. data/lib/watobo/gui/login_wizzard.rb +0 -9
  106. data/lib/watobo/gui/main_window.rb +587 -618
  107. data/lib/watobo/gui/manual_request_editor.rb +620 -565
  108. data/lib/watobo/gui/master_pw_dialog.rb +0 -9
  109. data/lib/watobo/gui/mixins/gui_settings.rb +29 -38
  110. data/lib/watobo/gui/page_tree.rb +217 -226
  111. data/lib/watobo/gui/password_policy_dialog.rb +0 -9
  112. data/lib/watobo/gui/plugin_board.rb +0 -9
  113. data/lib/watobo/gui/preferences_dialog.rb +0 -9
  114. data/lib/watobo/gui/progress_window.rb +17 -27
  115. data/lib/watobo/gui/project_wizzard.rb +0 -9
  116. data/lib/watobo/gui/proxy_dialog.rb +1 -10
  117. data/lib/watobo/gui/quick_scan_dialog.rb +0 -9
  118. data/lib/watobo/gui/request_builder_frame.rb +102 -111
  119. data/lib/watobo/gui/request_editor.rb +181 -137
  120. data/lib/watobo/gui/rewrite_filters_dialog.rb +394 -403
  121. data/lib/watobo/gui/rewrite_rules_dialog.rb +372 -381
  122. data/lib/watobo/gui/save_chat_dialog.rb +140 -149
  123. data/lib/watobo/gui/scanner_settings_dialog.rb +0 -9
  124. data/lib/watobo/gui/select_chat_dialog.rb +0 -9
  125. data/lib/watobo/gui/session_management_dialog.rb +0 -9
  126. data/lib/watobo/gui/sites_tree.rb +0 -9
  127. data/lib/watobo/gui/status_bar.rb +0 -9
  128. data/lib/watobo/gui/table_editor.rb +0 -9
  129. data/lib/watobo/gui/tagless_viewer.rb +0 -9
  130. data/lib/watobo/gui/templates/plugin.rb +0 -9
  131. data/lib/watobo/gui/templates/plugin2.rb +92 -100
  132. data/lib/watobo/gui/templates/plugin_base.rb +144 -153
  133. data/lib/watobo/gui/text_viewer.rb +0 -9
  134. data/lib/watobo/gui/transcoder_window.rb +0 -9
  135. data/lib/watobo/gui/utils/gui_utils.rb +0 -9
  136. data/lib/watobo/gui/utils/init_icons.rb +86 -95
  137. data/lib/watobo/gui/utils/load_icons.rb +33 -42
  138. data/lib/watobo/gui/utils/load_plugins.rb +116 -119
  139. data/lib/watobo/gui/utils/master_password.rb +68 -77
  140. data/lib/watobo/gui/utils/save_default_settings.rb +113 -122
  141. data/lib/watobo/gui/utils/save_project_settings.rb +0 -9
  142. data/lib/watobo/gui/utils/save_proxy_settings.rb +41 -50
  143. data/lib/watobo/gui/utils/save_scanner_settings.rb +18 -27
  144. data/lib/watobo/gui/utils/session_history.rb +112 -121
  145. data/lib/watobo/gui/workspace_dialog.rb +0 -9
  146. data/lib/watobo/gui/www_auth_dialog.rb +0 -9
  147. data/lib/watobo/gui/xml_viewer_frame.rb +0 -9
  148. data/lib/watobo/http.rb +4 -13
  149. data/lib/watobo/http/cookies/cookies.rb +26 -35
  150. data/lib/watobo/http/data/data.rb +45 -54
  151. data/lib/watobo/http/data/json.rb +47 -55
  152. data/lib/watobo/http/url/url.rb +38 -47
  153. data/lib/watobo/http/xml/xml.rb +124 -130
  154. data/lib/watobo/interceptor.rb +3 -12
  155. data/lib/watobo/interceptor/proxy.rb +742 -739
  156. data/lib/watobo/interceptor/transparent.rb +22 -24
  157. data/lib/watobo/mixins.rb +10 -19
  158. data/lib/watobo/mixins/check_info.rb +27 -36
  159. data/lib/watobo/mixins/httpparser.rb +613 -637
  160. data/lib/watobo/mixins/request_parser.rb +88 -97
  161. data/lib/watobo/mixins/shapers.rb +515 -529
  162. data/lib/watobo/mixins/transcoders.rb +3 -11
  163. data/lib/watobo/parser.rb +1 -10
  164. data/lib/watobo/parser/html.rb +83 -92
  165. data/lib/watobo/patch_fxruby_setfocus.rb +26 -0
  166. data/lib/watobo/sockets.rb +3 -12
  167. data/lib/watobo/sockets/agent.rb +828 -837
  168. data/lib/watobo/sockets/client_socket.rb +308 -312
  169. data/lib/watobo/sockets/connection.rb +401 -410
  170. data/lib/watobo/sockets/http_socket.rb +11 -13
  171. data/lib/watobo/sockets/ntlm_auth.rb +129 -138
  172. data/lib/watobo/utils.rb +10 -19
  173. data/lib/watobo/utils/check_regex.rb +0 -9
  174. data/lib/watobo/utils/copy_object.rb +0 -9
  175. data/lib/watobo/utils/crypto.rb +0 -9
  176. data/lib/watobo/utils/expand_range.rb +23 -32
  177. data/lib/watobo/utils/export_xml.rb +97 -106
  178. data/lib/watobo/utils/file_management.rb +9 -11
  179. data/lib/watobo/utils/hexprint.rb +9 -18
  180. data/lib/watobo/utils/load_chat.rb +0 -9
  181. data/lib/watobo/utils/load_icon.rb +0 -9
  182. data/lib/watobo/utils/ntlm.rb +866 -875
  183. data/lib/watobo/utils/print_debug.rb +12 -21
  184. data/lib/watobo/utils/response_builder.rb +90 -99
  185. data/lib/watobo/utils/response_hash.rb +0 -9
  186. data/lib/watobo/utils/secure_eval.rb +0 -9
  187. data/lib/watobo/utils/strings.rb +10 -19
  188. data/lib/watobo/utils/text2request.rb +0 -9
  189. data/lib/watobo/utils/url.rb +23 -32
  190. data/lib/watobo/utils/utf16.rb +11 -20
  191. data/modules/active/Apache/mod_status.rb +0 -9
  192. data/modules/active/Apache/multiview.rb +151 -160
  193. data/modules/active/Flash/crossdomain.rb +0 -9
  194. data/modules/active/JWT/jwt_oauth2_none.rb +111 -0
  195. data/modules/active/cq5/cq5_default_selectors.rb +106 -115
  196. data/modules/active/cq5/cqp_user_enumeration.rb +125 -134
  197. data/modules/active/directories/dirwalker.rb +0 -9
  198. data/modules/active/discovery/fileextensions.rb +0 -9
  199. data/modules/active/discovery/http_methods.rb +0 -9
  200. data/modules/active/discovery/jsmapfiles.rb +79 -0
  201. data/modules/active/domino/domino_db.rb +68 -76
  202. data/modules/active/dotNET/custom_errors.rb +102 -111
  203. data/modules/active/dotNET/dotnet_files.rb +90 -99
  204. data/modules/active/fileinclusion/lfi_simple.rb +0 -9
  205. data/modules/active/jboss/jboss_basic.rb +0 -9
  206. data/modules/active/sap/business_objects.rb +51 -60
  207. data/modules/active/sap/its_commands.rb +0 -9
  208. data/modules/active/sap/its_service_parameter.rb +0 -9
  209. data/modules/active/sap/its_services.rb +0 -9
  210. data/modules/active/sap/its_xss.rb +0 -9
  211. data/modules/active/shell_shock/shell_shock.rb +139 -148
  212. data/modules/active/siebel/siebel_apps.rb +160 -169
  213. data/modules/active/sqlinjection/sql_boolean.rb +0 -9
  214. data/modules/active/sqlinjection/sql_numerical.rb +198 -0
  215. data/modules/active/sqlinjection/sqli_error.rb +0 -9
  216. data/modules/active/sqlinjection/sqli_timing.rb +220 -229
  217. data/modules/active/struts2/default_handler_ognl.rb +106 -115
  218. data/modules/active/struts2/include_params_ognl.rb +105 -114
  219. data/modules/active/xml/xml_xxe.rb +112 -123
  220. data/modules/active/xss/xss_ng.rb +214 -223
  221. data/modules/active/xss/xss_simple.rb +0 -9
  222. data/modules/passive/ajax.rb +68 -77
  223. data/modules/passive/autocomplete.rb +56 -65
  224. data/modules/passive/cookie_options.rb +0 -9
  225. data/modules/passive/cookie_xss.rb +0 -9
  226. data/modules/passive/detect_code.rb +0 -9
  227. data/modules/passive/detect_fileupload.rb +0 -9
  228. data/modules/passive/detect_infrastructure.rb +0 -9
  229. data/modules/passive/detect_one_time_tokens.rb +0 -9
  230. data/modules/passive/dirindexing.rb +0 -9
  231. data/modules/passive/disclosure_domino.rb +55 -64
  232. data/modules/passive/disclosure_emails.rb +0 -9
  233. data/modules/passive/disclosure_ipaddr.rb +55 -53
  234. data/modules/passive/filename_as_parameter.rb +0 -9
  235. data/modules/passive/form_spotter.rb +0 -9
  236. data/modules/passive/hidden_fields.rb +50 -59
  237. data/modules/passive/hotspots.rb +0 -9
  238. data/modules/passive/in_script_parameter.rb +0 -9
  239. data/modules/passive/json_web_token.rb +93 -0
  240. data/modules/passive/multiple_server_headers.rb +0 -9
  241. data/modules/passive/possible_login.rb +0 -9
  242. data/modules/passive/redirect_url.rb +0 -9
  243. data/modules/passive/redirectionz.rb +0 -9
  244. data/modules/passive/sap-headers.rb +56 -65
  245. data/modules/passive/xss_dom.rb +0 -9
  246. data/plugins/aem/aem.rb +11 -20
  247. data/plugins/aem/gui/main.rb +118 -127
  248. data/plugins/aem/gui/tree_view.rb +171 -180
  249. data/plugins/aem/lib/agent.rb +130 -138
  250. data/plugins/aem/lib/dispatcher.rb +45 -51
  251. data/plugins/aem/lib/engine.rb +177 -186
  252. data/plugins/catalog/catalog.rb +345 -355
  253. data/plugins/crawler/crawler.rb +4 -13
  254. data/plugins/crawler/gui.rb +5 -14
  255. data/plugins/crawler/gui/auth_frame.rb +270 -279
  256. data/plugins/crawler/gui/crawler_gui.rb +271 -276
  257. data/plugins/crawler/gui/general_settings_frame.rb +96 -105
  258. data/plugins/crawler/gui/hooks_frame.rb +80 -89
  259. data/plugins/crawler/gui/scope_frame.rb +50 -59
  260. data/plugins/crawler/gui/settings_tabbook.rb +38 -47
  261. data/plugins/crawler/gui/status_frame.rb +59 -68
  262. data/plugins/crawler/lib/bags.rb +18 -27
  263. data/plugins/crawler/lib/constants.rb +11 -20
  264. data/plugins/crawler/lib/engine.rb +488 -497
  265. data/plugins/crawler/lib/grabber.rb +68 -77
  266. data/plugins/crawler/lib/status.rb +71 -80
  267. data/plugins/crawler/lib/uri_mp.rb +12 -21
  268. data/plugins/filefinder/filefinder.rb +326 -333
  269. data/plugins/sqlmap/bin/test.rb +78 -87
  270. data/plugins/sqlmap/gui.rb +4 -13
  271. data/plugins/sqlmap/gui/main.rb +218 -227
  272. data/plugins/sqlmap/gui/options_frame.rb +97 -106
  273. data/plugins/sqlmap/lib/sqlmap_ctrl.rb +90 -100
  274. data/plugins/sqlmap/sqlmap.rb +2 -11
  275. data/plugins/sslchecker/cli/sslchecker_cli.rb +0 -9
  276. data/plugins/sslchecker/gui/cipher_table.rb +246 -254
  277. data/plugins/sslchecker/gui/gui.rb +258 -264
  278. data/plugins/sslchecker/gui/sslchecker.rb +4 -13
  279. data/plugins/sslchecker/lib/check.rb +127 -133
  280. data/plugins/wshell/gui/main.rb +119 -117
  281. data/plugins/wshell/lib/core.rb +38 -88
  282. data/plugins/wshell/wshell.rb +11 -20
  283. metadata +170 -164
@@ -0,0 +1,14 @@
1
+ module Watobo
2
+ def self.save_thread(ms=250, &block)
3
+ FXApp.instance.addTimeout(ms, :repeat => true, &block)
4
+ end
5
+
6
+ def self.save_thread_UNUSED(ms=250, &block)
7
+ Thread.new {
8
+ loop do
9
+ sleep 0.5
10
+ Watobo::Gui.application.runOnUiThread(&block)
11
+ end
12
+ }
13
+ end
14
+ end
@@ -1,80 +1,71 @@
1
- #.
2
- # goto_url_dialog.rb
3
- #.
4
- # Copyright 2014 by siberas, http://www.siberas.de
5
- # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
- # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
7
- # WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
- # You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9
-
10
1
  # @private
11
- module Watobo#:nodoc: all
12
- module Gui
13
- class GotoUrlDialog < FXDialogBox
14
-
15
- include Responder
16
-
17
- attr :url_pattern
18
- def initialize(owner, pattern=nil )
19
- #super(owner, "Edit Target Scope", DECOR_TITLE|DECOR_BORDER, :width => 300, :height => 425)
20
- super(owner, "Enter URL filter (regex):", DECOR_ALL, :width => 300, :height => 150)
21
-
22
- FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
23
-
24
- base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
25
- @url_pattern = ""
26
-
27
-
28
- @pattern_field = FXTextField.new(base_frame, 40, :target => @pattern, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT)
29
- @pattern_field.setText(pattern) unless pattern.nil?
30
- @pattern_field.setFocus()
31
- @pattern_field.setDefault()
32
-
33
- @pattern_field.connect(SEL_KEYPRESS) { |sender, sel, event|
34
- if event.code == KEY_Tab
35
- @finishButton.setFocus()
36
- @finishButton.setDefault()
37
- true
38
- else
39
- false
40
- end
41
-
42
- }
43
- buttons_frame = FXHorizontalFrame.new(base_frame,
44
- :opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP)
45
-
46
- @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
47
- @finishButton.enable
48
-
49
-
50
- @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
51
- #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
52
- self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
53
- true
54
- end
55
-
56
- @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
57
- :target => self, :selector => FXDialogBox::ID_CANCEL,
58
- :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
59
-
60
- end
61
-
62
- private
63
-
64
- def onAccept(sender, sel, event)
65
- begin
66
- @url_pattern = @pattern_field.text
67
- "regex_test".match(/#{@url_pattern}/)
68
- rescue
69
- @url_pattern = Regexp.quote @pattern_field.text
70
- end
71
-
72
- # Watobo::Scope.set @defineScopeFrame.getScope()
73
-
74
- getApp().stopModal(self, 1)
75
- self.hide()
76
- return 0
77
- end
78
- end
79
- end
80
- end
2
+ module Watobo#:nodoc: all
3
+ module Gui
4
+ class GotoUrlDialog < FXDialogBox
5
+
6
+ include Responder
7
+
8
+ attr :url_pattern
9
+ def initialize(owner, pattern=nil )
10
+ #super(owner, "Edit Target Scope", DECOR_TITLE|DECOR_BORDER, :width => 300, :height => 425)
11
+ super(owner, "Enter URL filter (regex):", DECOR_ALL, :width => 300, :height => 150)
12
+
13
+ FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
14
+
15
+ base_frame = FXVerticalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
16
+ @url_pattern = ""
17
+
18
+
19
+ @pattern_field = FXTextField.new(base_frame, 40, :target => @pattern, :selector => FXDataTarget::ID_VALUE, :opts => TEXTFIELD_NORMAL|LAYOUT_SIDE_LEFT)
20
+ @pattern_field.setText(pattern) unless pattern.nil?
21
+ @pattern_field.setFocus()
22
+ @pattern_field.setDefault()
23
+
24
+ @pattern_field.connect(SEL_KEYPRESS) { |sender, sel, event|
25
+ if event.code == KEY_Tab
26
+ @finishButton.setFocus()
27
+ @finishButton.setDefault()
28
+ true
29
+ else
30
+ false
31
+ end
32
+
33
+ }
34
+ buttons_frame = FXHorizontalFrame.new(base_frame,
35
+ :opts => LAYOUT_FILL_X|LAYOUT_SIDE_TOP)
36
+
37
+ @finishButton = FXButton.new(buttons_frame, "Accept" , nil, nil, :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
38
+ @finishButton.enable
39
+
40
+
41
+ @finishButton.connect(SEL_COMMAND) do |sender, sel, item|
42
+ #self.handle(self, FXSEL(SEL_COMMAND, ID_CANCEL), nil)
43
+ self.handle(self, FXSEL(SEL_COMMAND, ID_ACCEPT), nil)
44
+ true
45
+ end
46
+
47
+ @cancelButton = FXButton.new(buttons_frame, "Cancel" ,
48
+ :target => self, :selector => FXDialogBox::ID_CANCEL,
49
+ :opts => BUTTON_NORMAL|LAYOUT_RIGHT)
50
+
51
+ end
52
+
53
+ private
54
+
55
+ def onAccept(sender, sel, event)
56
+ begin
57
+ @url_pattern = @pattern_field.text
58
+ "regex_test".match(/#{@url_pattern}/)
59
+ rescue
60
+ @url_pattern = Regexp.quote @pattern_field.text
61
+ end
62
+
63
+ # Watobo::Scope.set @defineScopeFrame.getScope()
64
+
65
+ getApp().stopModal(self, 1)
66
+ self.hide()
67
+ return 0
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,12 +1,3 @@
1
- #.
2
- # hex_viewer.rb
3
- #.
4
- # Copyright 2014 by siberas, http://www.siberas.de
5
- # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
- # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
7
- # WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
- # You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9
-
10
1
  # @private
11
2
  module Watobo#:nodoc: all
12
3
  module Gui
@@ -1,297 +1,288 @@
1
- #.
2
- # html_viewer.rb
3
- #.
4
- # Copyright 2014 by siberas, http://www.siberas.de
5
- # This file is part of WATOBO (Web Application Tool Box) http://watobo.sourceforge.com
6
- # WATOBO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation version 2 of the License.
7
- # WATOBO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
- # You should have received a copy of the GNU General Public License along with WATOBO; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9
-
10
- require 'fox16/scintilla'
11
-
1
+ require 'fox16/scintilla'
2
+
12
3
  # @private
13
- module Watobo#:nodoc: all
14
- module Gui
15
- class HTMLViewer < FXScintilla
16
- attr_accessor :max_len
17
-
18
- def search_text(text, &block)
19
- matches = []
20
- setTargetStart 0
21
- setTargetEnd getLength
22
- while searchInTarget(text.length, text) >= 0
23
- pos = getTargetStart
24
- setTargetStart pos+1
25
- setTargetEnd getLength
26
- yield pos if block_given?
27
- matches << pos
28
- end
29
-
30
- matches
31
- end
32
-
33
-
34
- def initialize(owner, opts)
35
- super(owner, nil, 0, opts)
36
- self.setLexer FXScintilla::SCLEX_HTML
37
- self.setCodePage(FXScintilla::SC_CP_UTF8)
38
- self.styleSetFont(FXScintilla::STYLE_DEFAULT, "fixed")
39
- self.styleSetSize(FXScintilla::STYLE_DEFAULT, 9)
40
- self.styleClearAll
41
- self.styleSetFore(FXScintilla::SCE_P_DEFAULT, FXRGB(0x80, 0x80, 0x80) & 0xffffff)
42
- self.styleSetFore(FXScintilla::SCE_P_COMMENTLINE, FXRGB(0x00, 0x7f, 0x00) & 0xffffff)
43
- self.styleSetFore(FXScintilla::SCE_P_NUMBER, FXRGB(0x00, 0x7f, 0x7f) & 0xffffff)
44
- self.styleSetFore(FXScintilla::SCE_P_STRING, FXRGB(0x7f, 0x00, 0x7f) & 0xffffff)
45
- self.styleSetFore(FXScintilla::SCE_P_CHARACTER, FXRGB(0x7f, 0x00, 0x7f) & 0xffffff)
46
- self.styleSetFore(FXScintilla::SCE_P_WORD, FXRGB(0x00, 0x00, 0x7f) & 0xffffff)
47
- self.styleSetBold(FXScintilla::SCE_P_WORD, true)
48
- self.styleSetFore(FXScintilla::SCE_P_TRIPLE, FXRGB(0x7f, 0x00, 0x00) & 0xffffff)
49
- self.styleSetFore(FXScintilla::SCE_P_TRIPLEDOUBLE, FXRGB(0x7f, 0x00, 0x00) & 0xffffff)
50
- self.styleSetFore(FXScintilla::SCE_P_CLASSNAME, FXRGB(0x00, 0x00, 0xff) & 0xffffff)
51
- self.styleSetBold(FXScintilla::SCE_P_CLASSNAME, true)
52
- self.styleSetFore(FXScintilla::SCE_P_DEFNAME, FXRGB(0x00, 0x7f, 0x7f) & 0xffffff)
53
- self.styleSetBold(FXScintilla::SCE_P_DEFNAME, true)
54
- self.styleSetBold(FXScintilla::SCE_P_OPERATOR, true)
55
- self.styleSetFore(FXScintilla::SCE_P_IDENTIFIER, FXRGB(0x7f, 0x7f, 0x7f) & 0xffffff)
56
- self.styleSetFore(FXScintilla::SCE_P_COMMENTBLOCK, FXRGB(0x7f, 0x7f, 0x7f) & 0xffffff)
57
- self.styleSetFore(FXScintilla::SCE_P_STRINGEOL, FXRGB(0x00, 0x00, 0x00) & 0xffffff)
58
- self.styleSetBack(FXScintilla::SCE_P_STRINGEOL, FXRGB(0xe0, 0xc0, 0xe0) & 0xffffff)
59
- self.styleSetEOLFilled(FXScintilla::SCE_P_STRINGEOL, true)
60
- self.styleSetFore(34, FXRGB(0x00, 0x00, 0xff) & 0xffffff)
61
- self.styleSetBold(34, true)
62
- self.styleSetFore(35, FXRGB(0xff, 0x00, 0x00) & 0xffffff)
63
- self.styleSetBold(35, true)
64
- @max_len = 0
65
- end
66
- end
67
-
68
- class HTMLViewerFrame < FXVerticalFrame
69
-
70
- attr_accessor :max_len
71
-
72
- def setText(text, prefs={})
73
-
74
- normalized_text = "- empty -"
75
- if text.is_a? String
76
- normalized_text = text.gsub(/[^[:print:]]/,".")
77
- elsif text.respond_to? :has_body?
78
- unless text.body.nil? or text.body.empty?
79
- body = text.body.strip
80
- if text.content_type =~ /(html|xml)/
81
- doc = Nokogiri::XML(body, &:noblanks)
82
- fbody = doc.to_xhtml( indent:3, indent_text:" ")
83
- normalized_text = fbody.to_s
84
- else
85
- normalized_text = body
86
- end
87
- end
88
- elsif text.is_a? Array
89
- normalized_text = text.join
90
- end
91
-
92
- @text = normalized_text
93
-
94
- # puts normalized_text
95
- @html_viewer.setText(@text)
96
- #@html_viewer.encodedFromUTF8(normalized_text)
97
-
98
- @match_pos_label.text = "0/0"
99
- @match_pos_label.textColor = 'grey'
100
-
101
- @html_viewer.setTargetStart 0
102
- @html_viewer.setTargetEnd @html_viewer.getLength
103
-
104
- applyFilter() if @auto_apply_cbtn.checked?
105
- end
106
-
107
- def highlight(pattern)
108
- highlightPattern(pattern)
109
- end
110
-
111
- def getText
112
- @html_viewer.to_s
113
- end
114
-
115
- def initialize(owner, opts)
116
- super(owner, opts)
117
-
118
- @text_matches = []
119
-
120
- @style = 2 # default style
121
- @text = ''
122
- @max_len = 5000
123
- @filter_mode = SEL_TYPE_HIGHLIGHT
124
- @match_pos = 0
125
-
126
- text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT,:height => 24, :padding => 0)
127
-
128
- #@auto_apply_cbtn.connect(SEL_COMMAND, method(:onInterceptChanged))
129
-
130
- pmatch_btn = FXButton.new(text_view_header, "<", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
131
- @match_pos_label = FXLabel.new(text_view_header, "0/0", :opts => LAYOUT_FILL_Y)
132
- @match_pos_label.textColor = 'grey'
133
- pmatch_btn.connect(SEL_COMMAND) { gotoPrevMatch() }
134
- nmatch_btn = FXButton.new(text_view_header, ">", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
135
- nmatch_btn.connect(SEL_COMMAND) { gotoNextMatch() }
136
-
137
- # @filter_text = FXTextField.new(text_view_header, 10,
138
- # :target => @filter_dt, :selector => FXDataTarget::ID_VALUE,
139
- # :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
140
-
141
- @filter_text = FXComboBox.new(text_view_header, 20, nil, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
142
- @filter_text.connect(SEL_COMMAND){
143
- applyFilter()
144
- addFilterHistory()
145
- }
146
-
147
- @filter_text.connect(SEL_CHANGED) {
148
- applyFilter()
149
- }
150
-
151
- @auto_apply_cbtn = FXCheckButton.new(text_view_header, "auto-apply", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_RIGHT|LAYOUT_FILL_Y)
152
-
153
-
154
- text_box_frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
155
-
156
- @html_viewer = HTMLViewer.new(text_box_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
157
- #searchflags = FXScintilla::SCFIND_WHOLEWORD|FXScintilla::SCFIND_MATCHCASE|FXScintilla::SCFIND_REGEXP|FXScintilla::SCFIND_WORDSTART
158
- @searchflags = FXScintilla::SCFIND_REGEXP
159
- @html_viewer.setSearchFlags @searchflags
160
-
161
- addHotkeyHandler(@html_viewer)
162
- addHotkeyHandler(@filter_text)
163
-
164
- # @filter_dt.connect(SEL_COMMAND) { applyFilter() }
165
-
166
- end
167
-
168
- def applyFilter
169
- pattern = @filter_text.text
170
- return if pattern.empty?
171
-
172
- @match_pos_label.text = "0/0"
173
- @match_pos_label.textColor = 'grey'
174
-
175
- @text_matches = @html_viewer.search_text(pattern)
176
-
177
-
178
- if @text_matches.length > 0
179
- @match_pos_label.textColor = 'black'
180
- @match_pos_label.text = "1/#{@text_matches.length}"
181
-
182
- show_match_pos(0)
183
- end
184
-
185
- end
186
-
187
- private
188
-
189
- def show_match_pos(match_pos=nil)
190
-
191
- pos = match_pos.nil? ? 0 : match_pos
192
- return false if @text_matches.empty?
193
- return false if pos > @text_matches.length-1
194
- @match_pos = pos
195
- pattern = @filter_text.text
196
- text_pos = @text_matches[pos]
197
- @html_viewer.gotoPos text_pos
198
- @html_viewer.setSel text_pos, text_pos+pattern.length
199
- end
200
-
201
- def show_next
202
- if @match_pos < @text_matches.length-1
203
- @match_pos += 1
204
- show_match_pos @match_pos
205
- return true
206
- end
207
- return false
208
- end
209
-
210
- def show_prev
211
- if @match_pos > 0
212
- @match_pos -= 1
213
- show_match_pos @match_pos
214
- return true
215
- end
216
- return false
217
- end
218
-
219
-
220
- def addFilterHistory()
221
- text = @filter_text.text
222
- return true if text == ''
223
- has_item = false
224
- @filter_text.each do |item, data|
225
- has_item = true if data == text
226
- end
227
- @filter_text.appendItem(text, text) unless has_item == true
228
- @filter_text.numVisible = @filter_text.numItems
229
- end
230
-
231
- def resetFilter
232
- @match_pos_label.text = "0/0"
233
- @match_pos_label.textColor = 'grey'
234
- @filter_text.text = ''
235
- end
236
-
237
- def addHotkeyHandler(widget)
238
- @ctrl_pressed = false
239
-
240
- widget.connect(SEL_KEYPRESS) { |sender, sel, event|
241
- state = false
242
- @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
243
- # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
244
- if event.code == KEY_Return
245
- highlight(@filter_text.text)
246
- state = true # special handling of KEY_Return, because we don't want a linebreak in textbox.
247
- end
248
-
249
- if event.code == KEY_F1
250
-
251
- unless event.moved?
252
- FXMenuPane.new(self) do |menu_pane|
253
- FXMenuCaption.new(menu_pane, "Hotkeys:")
254
- FXMenuSeparator.new(menu_pane)
255
- [ "<ctrl-r> - Reset Filter",
256
- "<ctrl-n> - Goto Next",
257
- "<ctrl-shift-n> - Goto Prev"
258
- ].each do |hk|
259
- FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
260
- end
261
-
262
- menu_pane.create
263
- menu_pane.popup(nil, event.root_x, event.root_y)
264
- app.runModalWhileShown(menu_pane)
265
- end
266
-
267
- end
268
- end
269
-
270
- if @ctrl_pressed
271
- case event.code
272
- when KEY_n
273
- if show_next
274
- @match_pos_label.text = "#{@match_pos+1}/#{@text_matches.length}"
275
- end
276
- when KEY_N
277
- if show_prev
278
- @match_pos_label.text = "#{@match_pos+1}/#{@text_matches.length}"
279
- end
280
- when KEY_r
281
- resetFilter()
282
-
283
- end
284
- end
285
- state
286
- }
287
-
288
- widget.connect(SEL_KEYRELEASE) { |sender, sel, event|
289
- @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
290
- false
291
- }
292
- end
293
-
294
- end
295
- end
296
- end
297
-
4
+ module Watobo#:nodoc: all
5
+ module Gui
6
+ class HTMLViewer < FXScintilla
7
+ attr_accessor :max_len
8
+
9
+ def search_text(text, &block)
10
+ matches = []
11
+ setTargetStart 0
12
+ setTargetEnd getLength
13
+ while searchInTarget(text.length, text) >= 0
14
+ pos = getTargetStart
15
+ setTargetStart pos+1
16
+ setTargetEnd getLength
17
+ yield pos if block_given?
18
+ matches << pos
19
+ end
20
+
21
+ matches
22
+ end
23
+
24
+
25
+ def initialize(owner, opts)
26
+ super(owner, nil, 0, opts)
27
+ self.setLexer FXScintilla::SCLEX_HTML
28
+ self.setCodePage(FXScintilla::SC_CP_UTF8)
29
+ self.styleSetFont(FXScintilla::STYLE_DEFAULT, "fixed")
30
+ self.styleSetSize(FXScintilla::STYLE_DEFAULT, 9)
31
+ self.styleClearAll
32
+ self.styleSetFore(FXScintilla::SCE_P_DEFAULT, FXRGB(0x80, 0x80, 0x80) & 0xffffff)
33
+ self.styleSetFore(FXScintilla::SCE_P_COMMENTLINE, FXRGB(0x00, 0x7f, 0x00) & 0xffffff)
34
+ self.styleSetFore(FXScintilla::SCE_P_NUMBER, FXRGB(0x00, 0x7f, 0x7f) & 0xffffff)
35
+ self.styleSetFore(FXScintilla::SCE_P_STRING, FXRGB(0x7f, 0x00, 0x7f) & 0xffffff)
36
+ self.styleSetFore(FXScintilla::SCE_P_CHARACTER, FXRGB(0x7f, 0x00, 0x7f) & 0xffffff)
37
+ self.styleSetFore(FXScintilla::SCE_P_WORD, FXRGB(0x00, 0x00, 0x7f) & 0xffffff)
38
+ self.styleSetBold(FXScintilla::SCE_P_WORD, true)
39
+ self.styleSetFore(FXScintilla::SCE_P_TRIPLE, FXRGB(0x7f, 0x00, 0x00) & 0xffffff)
40
+ self.styleSetFore(FXScintilla::SCE_P_TRIPLEDOUBLE, FXRGB(0x7f, 0x00, 0x00) & 0xffffff)
41
+ self.styleSetFore(FXScintilla::SCE_P_CLASSNAME, FXRGB(0x00, 0x00, 0xff) & 0xffffff)
42
+ self.styleSetBold(FXScintilla::SCE_P_CLASSNAME, true)
43
+ self.styleSetFore(FXScintilla::SCE_P_DEFNAME, FXRGB(0x00, 0x7f, 0x7f) & 0xffffff)
44
+ self.styleSetBold(FXScintilla::SCE_P_DEFNAME, true)
45
+ self.styleSetBold(FXScintilla::SCE_P_OPERATOR, true)
46
+ self.styleSetFore(FXScintilla::SCE_P_IDENTIFIER, FXRGB(0x7f, 0x7f, 0x7f) & 0xffffff)
47
+ self.styleSetFore(FXScintilla::SCE_P_COMMENTBLOCK, FXRGB(0x7f, 0x7f, 0x7f) & 0xffffff)
48
+ self.styleSetFore(FXScintilla::SCE_P_STRINGEOL, FXRGB(0x00, 0x00, 0x00) & 0xffffff)
49
+ self.styleSetBack(FXScintilla::SCE_P_STRINGEOL, FXRGB(0xe0, 0xc0, 0xe0) & 0xffffff)
50
+ self.styleSetEOLFilled(FXScintilla::SCE_P_STRINGEOL, true)
51
+ self.styleSetFore(34, FXRGB(0x00, 0x00, 0xff) & 0xffffff)
52
+ self.styleSetBold(34, true)
53
+ self.styleSetFore(35, FXRGB(0xff, 0x00, 0x00) & 0xffffff)
54
+ self.styleSetBold(35, true)
55
+ @max_len = 0
56
+ end
57
+ end
58
+
59
+ class HTMLViewerFrame < FXVerticalFrame
60
+
61
+ attr_accessor :max_len
62
+
63
+ def setText(text, prefs={})
64
+
65
+ normalized_text = "- empty -"
66
+ if text.is_a? String
67
+ normalized_text = text.gsub(/[^[:print:]]/,".")
68
+ elsif text.respond_to? :has_body?
69
+ unless text.body.nil? or text.body.empty?
70
+ body = text.body.strip
71
+ if text.content_type =~ /(html|xml)/
72
+ doc = Nokogiri::XML(body, &:noblanks)
73
+ fbody = doc.to_xhtml( indent:3, indent_text:" ")
74
+ normalized_text = fbody.to_s
75
+ else
76
+ normalized_text = body
77
+ end
78
+ end
79
+ elsif text.is_a? Array
80
+ normalized_text = text.join
81
+ end
82
+
83
+ @text = normalized_text
84
+
85
+ # puts normalized_text
86
+ @html_viewer.setText(@text)
87
+ #@html_viewer.encodedFromUTF8(normalized_text)
88
+
89
+ @match_pos_label.text = "0/0"
90
+ @match_pos_label.textColor = 'grey'
91
+
92
+ @html_viewer.setTargetStart 0
93
+ @html_viewer.setTargetEnd @html_viewer.getLength
94
+
95
+ applyFilter() if @auto_apply_cbtn.checked?
96
+ end
97
+
98
+ def highlight(pattern)
99
+ highlightPattern(pattern)
100
+ end
101
+
102
+ def getText
103
+ @html_viewer.to_s
104
+ end
105
+
106
+ def initialize(owner, opts)
107
+ super(owner, opts)
108
+
109
+ @text_matches = []
110
+
111
+ @style = 2 # default style
112
+ @text = ''
113
+ @max_len = 5000
114
+ @filter_mode = SEL_TYPE_HIGHLIGHT
115
+ @match_pos = 0
116
+
117
+ text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT,:height => 24, :padding => 0)
118
+
119
+ #@auto_apply_cbtn.connect(SEL_COMMAND, method(:onInterceptChanged))
120
+
121
+ pmatch_btn = FXButton.new(text_view_header, "<", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
122
+ @match_pos_label = FXLabel.new(text_view_header, "0/0", :opts => LAYOUT_FILL_Y)
123
+ @match_pos_label.textColor = 'grey'
124
+ pmatch_btn.connect(SEL_COMMAND) { gotoPrevMatch() }
125
+ nmatch_btn = FXButton.new(text_view_header, ">", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
126
+ nmatch_btn.connect(SEL_COMMAND) { gotoNextMatch() }
127
+
128
+ # @filter_text = FXTextField.new(text_view_header, 10,
129
+ # :target => @filter_dt, :selector => FXDataTarget::ID_VALUE,
130
+ # :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
131
+
132
+ @filter_text = FXComboBox.new(text_view_header, 20, nil, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
133
+ @filter_text.connect(SEL_COMMAND){
134
+ applyFilter()
135
+ addFilterHistory()
136
+ }
137
+
138
+ @filter_text.connect(SEL_CHANGED) {
139
+ applyFilter()
140
+ }
141
+
142
+ @auto_apply_cbtn = FXCheckButton.new(text_view_header, "auto-apply", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_RIGHT|LAYOUT_FILL_Y)
143
+
144
+
145
+ text_box_frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
146
+
147
+ @html_viewer = HTMLViewer.new(text_box_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y)
148
+ #searchflags = FXScintilla::SCFIND_WHOLEWORD|FXScintilla::SCFIND_MATCHCASE|FXScintilla::SCFIND_REGEXP|FXScintilla::SCFIND_WORDSTART
149
+ @searchflags = FXScintilla::SCFIND_REGEXP
150
+ @html_viewer.setSearchFlags @searchflags
151
+
152
+ addHotkeyHandler(@html_viewer)
153
+ addHotkeyHandler(@filter_text)
154
+
155
+ # @filter_dt.connect(SEL_COMMAND) { applyFilter() }
156
+
157
+ end
158
+
159
+ def applyFilter
160
+ pattern = @filter_text.text
161
+ return if pattern.empty?
162
+
163
+ @match_pos_label.text = "0/0"
164
+ @match_pos_label.textColor = 'grey'
165
+
166
+ @text_matches = @html_viewer.search_text(pattern)
167
+
168
+
169
+ if @text_matches.length > 0
170
+ @match_pos_label.textColor = 'black'
171
+ @match_pos_label.text = "1/#{@text_matches.length}"
172
+
173
+ show_match_pos(0)
174
+ end
175
+
176
+ end
177
+
178
+ private
179
+
180
+ def show_match_pos(match_pos=nil)
181
+
182
+ pos = match_pos.nil? ? 0 : match_pos
183
+ return false if @text_matches.empty?
184
+ return false if pos > @text_matches.length-1
185
+ @match_pos = pos
186
+ pattern = @filter_text.text
187
+ text_pos = @text_matches[pos]
188
+ @html_viewer.gotoPos text_pos
189
+ @html_viewer.setSel text_pos, text_pos+pattern.length
190
+ end
191
+
192
+ def show_next
193
+ if @match_pos < @text_matches.length-1
194
+ @match_pos += 1
195
+ show_match_pos @match_pos
196
+ return true
197
+ end
198
+ return false
199
+ end
200
+
201
+ def show_prev
202
+ if @match_pos > 0
203
+ @match_pos -= 1
204
+ show_match_pos @match_pos
205
+ return true
206
+ end
207
+ return false
208
+ end
209
+
210
+
211
+ def addFilterHistory()
212
+ text = @filter_text.text
213
+ return true if text == ''
214
+ has_item = false
215
+ @filter_text.each do |item, data|
216
+ has_item = true if data == text
217
+ end
218
+ @filter_text.appendItem(text, text) unless has_item == true
219
+ @filter_text.numVisible = @filter_text.numItems
220
+ end
221
+
222
+ def resetFilter
223
+ @match_pos_label.text = "0/0"
224
+ @match_pos_label.textColor = 'grey'
225
+ @filter_text.text = ''
226
+ end
227
+
228
+ def addHotkeyHandler(widget)
229
+ @ctrl_pressed = false
230
+
231
+ widget.connect(SEL_KEYPRESS) { |sender, sel, event|
232
+ state = false
233
+ @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
234
+ # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
235
+ if event.code == KEY_Return
236
+ highlight(@filter_text.text)
237
+ state = true # special handling of KEY_Return, because we don't want a linebreak in textbox.
238
+ end
239
+
240
+ if event.code == KEY_F1
241
+
242
+ unless event.moved?
243
+ FXMenuPane.new(self) do |menu_pane|
244
+ FXMenuCaption.new(menu_pane, "Hotkeys:")
245
+ FXMenuSeparator.new(menu_pane)
246
+ [ "<ctrl-r> - Reset Filter",
247
+ "<ctrl-n> - Goto Next",
248
+ "<ctrl-shift-n> - Goto Prev"
249
+ ].each do |hk|
250
+ FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
251
+ end
252
+
253
+ menu_pane.create
254
+ menu_pane.popup(nil, event.root_x, event.root_y)
255
+ app.runModalWhileShown(menu_pane)
256
+ end
257
+
258
+ end
259
+ end
260
+
261
+ if @ctrl_pressed
262
+ case event.code
263
+ when KEY_n
264
+ if show_next
265
+ @match_pos_label.text = "#{@match_pos+1}/#{@text_matches.length}"
266
+ end
267
+ when KEY_N
268
+ if show_prev
269
+ @match_pos_label.text = "#{@match_pos+1}/#{@text_matches.length}"
270
+ end
271
+ when KEY_r
272
+ resetFilter()
273
+
274
+ end
275
+ end
276
+ state
277
+ }
278
+
279
+ widget.connect(SEL_KEYRELEASE) { |sender, sel, event|
280
+ @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
281
+ false
282
+ }
283
+ end
284
+
285
+ end
286
+ end
287
+ end
288
+