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
@@ -1,12 +1,3 @@
1
- #.
2
- # csrf_token_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
2
  module Watobo#:nodoc: all
12
3
  module Gui
@@ -1,384 +1,375 @@
1
- #.
2
- # custom_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
- # @private
11
- module Watobo#:nodoc: all
12
- module Gui
13
-
14
- class ViewerHandlerCtrl < FXHorizontalFrame
15
- attr :handler
16
-
17
- def has_handler?
18
- !@handler.nil?
19
- end
20
-
21
- def initialize(parent, opts = { :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM, :padding => 0 })
22
- super parent, opts
23
- @parent = parent
24
- #handler_ctrl_frame = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X, :padding => 0)
25
- FXLabel.new(self, "View Handler:")
26
- @handler_status_lbl = FXLabel.new(self, "None")
27
- @handler_status_lbl.backColor = "red"
28
- add_handler_btn = FXButton.new(self, "add", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
29
- add_handler_btn.connect(SEL_COMMAND){ add_handler }
30
- reload_handler_btn = FXButton.new(self, "reload", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
31
- reload_handler_btn.connect(SEL_COMMAND){ load_handler(@handler_file) }
32
- reset_handler_btn = FXButton.new(self, "reset", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
33
-
34
- reset_handler_btn.connect(SEL_COMMAND){
35
- @handler = nil
36
- @handler_file = nil
37
- @handler_status_lbl.text = "None"
38
- @handler_status_lbl.backColor = "red"
39
- }
40
- end
41
-
42
-
43
- def add_handler
44
- handler_filename = FXFileDialog.getOpenFilename(self, "Select handler file", @handler_path, "*.rb\n*")
45
- if handler_filename != "" then
46
- if File.exists?(handler_filename) then
47
- @handler_file = handler_filename
48
- @handler_path = File.dirname(handler_filename) + "/"
49
- load_handler(handler_filename)
50
- end
51
- end
52
-
53
- end
54
-
55
- def load_handler(file)
56
- @handler = nil
57
- @handler_status_lbl.text = "None"
58
- @handler_status_lbl.backColor = "red"
59
-
60
- return false if file.nil?
61
- return false unless File.exist? file
62
- begin
63
- source = File.read(file)
64
- #puts source
65
- result = eval(source)
66
- if result.respond_to? :call
67
- @handler = result
68
- @handler_status_lbl.text = "#{File.basename(file).gsub(/\.rb$/,'')}"
69
- @handler_status_lbl.textColor = 'black'
70
- @handler_status_lbl.backColor = 'green'
71
- @parent.setText
72
- end
73
- return true
74
-
75
- rescue SyntaxError, LocalJumpError, NameError => e
76
- out = e.to_s
77
- out << e.backtrace.join("\n")
78
- rescue => bang
79
- out = bang
80
- out << bang.backtrace.join("\n")
81
- end
82
- puts out
83
- return false
84
- end
85
-
86
- def call_handler(object)
87
- return object if @handler.nil?
88
- begin
89
- result = @handler.call(object)
90
- return result
91
- rescue => bang
92
- result = bang.to_s
93
- result << bang.backtrace.join("\n")
94
- return result
95
- end
96
-
97
- end
98
- end
99
-
100
-
101
- class CustomViewer < FXVerticalFrame
102
- SEL_TYPE_GREP = 0
103
- SEL_TYPE_HIGHLIGHT = 1
104
- attr_accessor :max_len
105
-
106
- def style=(new_style)
107
- @simple_text_view.style = new_style
108
- end
109
-
110
- def editable=(value)
111
- @simple_text_view.editable = value
112
- end
113
-
114
- def setText(object=nil, prefs={})
115
-
116
- o = object.nil? ? @object : object
117
- return false if o.nil?
118
- @object = o
119
- normalized_text = o.to_s
120
- if o.is_a? Watobo::Request or o.is_a? Watobo::Response
121
- if @handler_ctrl.has_handler?
122
- result = @handler_ctrl.call_handler(o)
123
- normalized_text = result
124
- end
125
- else
126
- return false
127
- end
128
-
129
- @text = normalized_text
130
- #@text = text
131
- @simple_text_view.max_len = -1
132
- @simple_text_view.setText(normalized_text, prefs)
133
- @match_pos_label.text = "0/0"
134
- @match_pos_label.textColor = 'grey'
135
-
136
- applyFilter() if @auto_apply_cbtn.checked?
137
- end
138
-
139
- def highlight(pattern)
140
- highlightPattern(pattern)
141
- end
142
-
143
- def setFont(font_type=nil, size=nil)
144
- @simple_text_view.setFont(font_type, size)
145
- end
146
-
147
- def getText
148
- @simple_text_view.textbox.to_s
149
- end
150
-
151
- def initialize(owner, opts)
152
- super(owner, opts)
153
-
154
- @text_matches = []
155
-
156
- @style = 2 # default style
157
- @text = ''
158
- @object = nil
159
- @max_len = 5000
160
- @filter_mode = SEL_TYPE_HIGHLIGHT
161
- @cur_match_pos = 0
162
- @text_dt = FXDataTarget.new('')
163
- @filter_dt = FXDataTarget.new('')
164
-
165
- @handler = nil
166
- @handler_file = nil
167
- @handler_path = nil
168
-
169
- @handler_ctrl = ViewerHandlerCtrl.new(self)
170
-
171
- text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT,:height => 24, :padding => 0)
172
-
173
- #@auto_apply_cbtn.connect(SEL_COMMAND, method(:onInterceptChanged))
174
-
175
- pmatch_btn = FXButton.new(text_view_header, "<", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
176
- @match_pos_label = FXLabel.new(text_view_header, "0/0", :opts => LAYOUT_FILL_Y)
177
- @match_pos_label.textColor = 'grey'
178
- pmatch_btn.connect(SEL_COMMAND) { gotoPrevMatch() }
179
- nmatch_btn = FXButton.new(text_view_header, ">", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
180
- nmatch_btn.connect(SEL_COMMAND) { gotoNextMatch() }
181
-
182
- # @filter_text = FXTextField.new(text_view_header, 10,
183
- # :target => @filter_dt, :selector => FXDataTarget::ID_VALUE,
184
- # :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
185
-
186
- @filter_text = FXComboBox.new(text_view_header, 20, @filter_dt, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
187
- @filter_text.connect(SEL_COMMAND){
188
- applyFilter()
189
- addFilterHistory()
190
- }
191
-
192
- @filter_text.connect(SEL_CHANGED) {
193
- applyFilter()
194
- }
195
-
196
- menu = FXMenuPane.new(self)
197
- FXMenuCommand.new(menu, "&Highlight").connect(SEL_COMMAND){
198
- @filter_mode = SEL_TYPE_HIGHLIGHT
199
- applyFilter()
200
- @mode_btn.text = "Highlight"
201
- }#, method(:switchMethod))
202
- FXMenuCommand.new(menu, "&Grep").connect(SEL_COMMAND){
203
- @filter_mode = SEL_TYPE_GREP
204
- applyFilter()
205
- @mode_btn.text = "Grep"
206
- }#, method(:switchMethod))
207
-
208
- @auto_apply_cbtn = FXCheckButton.new(text_view_header, "auto-apply", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_RIGHT|LAYOUT_FILL_Y)
209
- @mode_btn = FXMenuButton.new(text_view_header, "Highlight", nil, menu,
210
- :opts=> MENUBUTTON_DOWN|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_RIGHT|LAYOUT_FILL_Y)
211
-
212
- reset_button = FXButton.new(text_view_header, "&Reset", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y)
213
- reset_button.connect(SEL_COMMAND){ resetFilter() }
214
-
215
- text_box_frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
216
-
217
- @simple_text_view = SimpleTextView.new(text_box_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y,:padding => 0)
218
- @simple_text_view.style = 1
219
- @simple_text_view.editable = false
220
- @simple_text_view.textStyle -= TEXT_WORDWRAP
221
-
222
- addHotkeyHandler(@simple_text_view.textbox)
223
- addHotkeyHandler(@filter_text)
224
-
225
- @filter_dt.connect(SEL_COMMAND) { applyFilter() }
226
-
227
- end
228
-
229
- def applyFilter
230
- pattern = @filter_text.text
231
- @match_pos_label.text = "0/0"
232
- @simple_text_view.resetMatches()
233
- @simple_text_view.setText(@text)
234
- @match_pos_label.textColor = 'grey'
235
- return true if pattern == ''
236
- case @filter_mode
237
- when SEL_TYPE_GREP
238
- grepPattern(pattern)
239
- when SEL_TYPE_HIGHLIGHT
240
- highlightPattern(pattern)
241
- end
242
- end
243
-
244
- private
245
-
246
- def gotoNextMatch()
247
- @cur_match_pos += 1 if @cur_match_pos < @simple_text_view.numMatches-1
248
- @simple_text_view.makeMatchVisible(@cur_match_pos)
249
- @match_pos_label.text = "#{@cur_match_pos+1}/#{@simple_text_view.numMatches}" if @simple_text_view.numMatches > 0
250
- end
251
-
252
- def gotoPrevMatch()
253
- @cur_match_pos -= 1 if @cur_match_pos > 0
254
- @simple_text_view.makeMatchVisible(@cur_match_pos)
255
- @match_pos_label.text = "#{@cur_match_pos+1}/#{@simple_text_view.numMatches}" if @simple_text_view.numMatches > 0
256
- end
257
-
258
- def addFilterHistory()
259
- text = @filter_text.text
260
- return true if text == ''
261
- has_item = false
262
- @filter_text.each do |item, data|
263
- has_item = true if data == text
264
- end
265
- @filter_text.appendItem(text, text) unless has_item == true
266
- @filter_text.numVisible = @filter_text.numItems
267
- end
268
-
269
- def resetFilter
270
- @simple_text_view.max_len = 0
271
- @simple_text_view.setText(@text)
272
- @match_pos_label.text = "0/0"
273
- @match_pos_label.textColor = 'grey'
274
- @filter_text.text = ''
275
- end
276
-
277
- def highlightPattern(pattern)
278
- @cur_match_pos = 0
279
- @simple_text_view.max_len = 0
280
-
281
- @match_pos_label.textColor = 'black'
282
-
283
- @simple_text_view.setText(@text)
284
- @simple_text_view.highlight(pattern)
285
- @match_pos_label.text = "0/#{@simple_text_view.numMatches()}"
286
-
287
- @simple_text_view.makeMatchVisible(0)
288
-
289
- @match_pos_label.text = "1/#{@simple_text_view.numMatches()}" if @simple_text_view.numMatches() > 0
290
-
291
- end
292
-
293
- def grepPattern(pattern)
294
- @cur_match_pos = 0
295
- @simple_text_view.max_len = 0
296
-
297
- @match_pos_label.textColor = 'black'
298
-
299
- @simple_text_view.setText(@text)
300
-
301
- @simple_text_view.filter(pattern)
302
- @match_pos_label.text = "0/#{@simple_text_view.numMatches()}"
303
- @simple_text_view.highlight(pattern)
304
- @simple_text_view.makeMatchVisible(0)
305
-
306
- @filter_mode = SEL_TYPE_GREP
307
-
308
- @match_pos_label.text = "1/#{@simple_text_view.numMatches()}" if @simple_text_view.numMatches() > 0
309
-
310
- end
311
-
312
- def addHotkeyHandler(widget)
313
- @ctrl_pressed = false
314
-
315
- widget.connect(SEL_KEYPRESS) { |sender, sel, event|
316
- # puts event.code
317
- @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
318
- # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
319
- if event.code == KEY_Return
320
- highlight(@filter_text.text)
321
- true # special handling of KEY_Return, because we don't want a linebreak in textbox.
322
- end
323
-
324
- if event.code == KEY_F1
325
-
326
- unless event.moved?
327
- FXMenuPane.new(self) do |menu_pane|
328
- FXMenuCaption.new(menu_pane, "Hotkeys:")
329
- FXMenuSeparator.new(menu_pane)
330
- [ "<ctrl-r> - Reset Filter",
331
- "<ctrl-g> - Grep",
332
- "<ctrl-h> - Highlight",
333
- "<ctrl-n> - Goto Next",
334
- "<ctrl-shift-n> - Goto Prev",
335
- "<ctrl-w> - Switch Wordwrap"
336
- ].each do |hk|
337
- FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
338
- end
339
-
340
- menu_pane.create
341
- menu_pane.popup(nil, event.root_x, event.root_y)
342
- app.runModalWhileShown(menu_pane)
343
- end
344
-
345
- end
346
- end
347
-
348
- if @ctrl_pressed
349
- case event.code
350
- when KEY_n
351
- gotoNextMatch()
352
- addFilterHistory()
353
- when KEY_N
354
- gotoPrevMatch()
355
- addFilterHistory()
356
- when KEY_w
357
- @simple_text_view.textbox.textStyle ^= TEXT_WORDWRAP
358
- when KEY_h
359
- @mode_btn.text = "Highlight"
360
- @filter_mode = SEL_TYPE_HIGHLIGHT
361
- addFilterHistory()
362
- applyFilter()
363
- when KEY_g
364
- @mode_btn.text = "Grep"
365
- @filter_mode = SEL_TYPE_GREP
366
- addFilterHistory()
367
- applyFilter()
368
- when KEY_r
369
- resetFilter()
370
-
371
- end
372
- end
373
- false
374
- }
375
-
376
- widget.connect(SEL_KEYRELEASE) { |sender, sel, event|
377
- @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
378
- false
379
- }
380
- end
381
-
382
- end
383
- end
1
+ # @private
2
+ module Watobo#:nodoc: all
3
+ module Gui
4
+
5
+ class ViewerHandlerCtrl < FXHorizontalFrame
6
+ attr :handler
7
+
8
+ def has_handler?
9
+ !@handler.nil?
10
+ end
11
+
12
+ def initialize(parent, opts = { :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM, :padding => 0 })
13
+ super parent, opts
14
+ @parent = parent
15
+ #handler_ctrl_frame = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X, :padding => 0)
16
+ FXLabel.new(self, "View Handler:")
17
+ @handler_status_lbl = FXLabel.new(self, "None")
18
+ @handler_status_lbl.backColor = "red"
19
+ add_handler_btn = FXButton.new(self, "add", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
20
+ add_handler_btn.connect(SEL_COMMAND){ add_handler }
21
+ reload_handler_btn = FXButton.new(self, "reload", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
22
+ reload_handler_btn.connect(SEL_COMMAND){ load_handler(@handler_file) }
23
+ reset_handler_btn = FXButton.new(self, "reset", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y|LAYOUT_RIGHT)
24
+
25
+ reset_handler_btn.connect(SEL_COMMAND){
26
+ @handler = nil
27
+ @handler_file = nil
28
+ @handler_status_lbl.text = "None"
29
+ @handler_status_lbl.backColor = "red"
30
+ }
31
+ end
32
+
33
+
34
+ def add_handler
35
+ handler_filename = FXFileDialog.getOpenFilename(self, "Select handler file", @handler_path, "*.rb\n*")
36
+ if handler_filename != "" then
37
+ if File.exists?(handler_filename) then
38
+ @handler_file = handler_filename
39
+ @handler_path = File.dirname(handler_filename) + "/"
40
+ load_handler(handler_filename)
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ def load_handler(file)
47
+ @handler = nil
48
+ @handler_status_lbl.text = "None"
49
+ @handler_status_lbl.backColor = "red"
50
+
51
+ return false if file.nil?
52
+ return false unless File.exist? file
53
+ begin
54
+ source = File.read(file)
55
+ #puts source
56
+ result = eval(source)
57
+ if result.respond_to? :call
58
+ @handler = result
59
+ @handler_status_lbl.text = "#{File.basename(file).gsub(/\.rb$/,'')}"
60
+ @handler_status_lbl.textColor = 'black'
61
+ @handler_status_lbl.backColor = 'green'
62
+ @parent.setText
63
+ end
64
+ return true
65
+
66
+ rescue SyntaxError, LocalJumpError, NameError => e
67
+ out = e.to_s
68
+ out << e.backtrace.join("\n")
69
+ rescue => bang
70
+ out = bang
71
+ out << bang.backtrace.join("\n")
72
+ end
73
+ puts out
74
+ return false
75
+ end
76
+
77
+ def call_handler(object)
78
+ return object if @handler.nil?
79
+ begin
80
+ result = @handler.call(object)
81
+ return result
82
+ rescue => bang
83
+ result = bang.to_s
84
+ result << bang.backtrace.join("\n")
85
+ return result
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+
92
+ class CustomViewer < FXVerticalFrame
93
+ SEL_TYPE_GREP = 0
94
+ SEL_TYPE_HIGHLIGHT = 1
95
+ attr_accessor :max_len
96
+
97
+ def style=(new_style)
98
+ @simple_text_view.style = new_style
99
+ end
100
+
101
+ def editable=(value)
102
+ @simple_text_view.editable = value
103
+ end
104
+
105
+ def setText(object=nil, prefs={})
106
+
107
+ o = object.nil? ? @object : object
108
+ return false if o.nil?
109
+ @object = o
110
+ normalized_text = o.to_s
111
+ if o.is_a? Watobo::Request or o.is_a? Watobo::Response
112
+ if @handler_ctrl.has_handler?
113
+ result = @handler_ctrl.call_handler(o)
114
+ normalized_text = result
115
+ end
116
+ else
117
+ return false
118
+ end
119
+
120
+ @text = normalized_text
121
+ #@text = text
122
+ @simple_text_view.max_len = -1
123
+ @simple_text_view.setText(normalized_text, prefs)
124
+ @match_pos_label.text = "0/0"
125
+ @match_pos_label.textColor = 'grey'
126
+
127
+ applyFilter() if @auto_apply_cbtn.checked?
128
+ end
129
+
130
+ def highlight(pattern)
131
+ highlightPattern(pattern)
132
+ end
133
+
134
+ def setFont(font_type=nil, size=nil)
135
+ @simple_text_view.setFont(font_type, size)
136
+ end
137
+
138
+ def getText
139
+ @simple_text_view.textbox.to_s
140
+ end
141
+
142
+ def initialize(owner, opts)
143
+ super(owner, opts)
144
+
145
+ @text_matches = []
146
+
147
+ @style = 2 # default style
148
+ @text = ''
149
+ @object = nil
150
+ @max_len = 5000
151
+ @filter_mode = SEL_TYPE_HIGHLIGHT
152
+ @cur_match_pos = 0
153
+ @text_dt = FXDataTarget.new('')
154
+ @filter_dt = FXDataTarget.new('')
155
+
156
+ @handler = nil
157
+ @handler_file = nil
158
+ @handler_path = nil
159
+
160
+ @handler_ctrl = ViewerHandlerCtrl.new(self)
161
+
162
+ text_view_header = FXHorizontalFrame.new(self, :opts => LAYOUT_FILL_X|LAYOUT_SIDE_BOTTOM|LAYOUT_FIX_HEIGHT,:height => 24, :padding => 0)
163
+
164
+ #@auto_apply_cbtn.connect(SEL_COMMAND, method(:onInterceptChanged))
165
+
166
+ pmatch_btn = FXButton.new(text_view_header, "<", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
167
+ @match_pos_label = FXLabel.new(text_view_header, "0/0", :opts => LAYOUT_FILL_Y)
168
+ @match_pos_label.textColor = 'grey'
169
+ pmatch_btn.connect(SEL_COMMAND) { gotoPrevMatch() }
170
+ nmatch_btn = FXButton.new(text_view_header, ">", nil, nil, 0, FRAME_RAISED|LAYOUT_FILL_Y)
171
+ nmatch_btn.connect(SEL_COMMAND) { gotoNextMatch() }
172
+
173
+ # @filter_text = FXTextField.new(text_view_header, 10,
174
+ # :target => @filter_dt, :selector => FXDataTarget::ID_VALUE,
175
+ # :opts => FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
176
+
177
+ @filter_text = FXComboBox.new(text_view_header, 20, @filter_dt, 0, FRAME_SUNKEN|FRAME_THICK|LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
178
+ @filter_text.connect(SEL_COMMAND){
179
+ applyFilter()
180
+ addFilterHistory()
181
+ }
182
+
183
+ @filter_text.connect(SEL_CHANGED) {
184
+ applyFilter()
185
+ }
186
+
187
+ menu = FXMenuPane.new(self)
188
+ FXMenuCommand.new(menu, "&Highlight").connect(SEL_COMMAND){
189
+ @filter_mode = SEL_TYPE_HIGHLIGHT
190
+ applyFilter()
191
+ @mode_btn.text = "Highlight"
192
+ }#, method(:switchMethod))
193
+ FXMenuCommand.new(menu, "&Grep").connect(SEL_COMMAND){
194
+ @filter_mode = SEL_TYPE_GREP
195
+ applyFilter()
196
+ @mode_btn.text = "Grep"
197
+ }#, method(:switchMethod))
198
+
199
+ @auto_apply_cbtn = FXCheckButton.new(text_view_header, "auto-apply", nil, 0, ICON_BEFORE_TEXT|LAYOUT_SIDE_TOP|LAYOUT_RIGHT|LAYOUT_FILL_Y)
200
+ @mode_btn = FXMenuButton.new(text_view_header, "Highlight", nil, menu,
201
+ :opts=> MENUBUTTON_DOWN|FRAME_RAISED|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_RIGHT|LAYOUT_FILL_Y)
202
+
203
+ reset_button = FXButton.new(text_view_header, "&Reset", nil, nil, 0, FRAME_RAISED|FRAME_THICK|LAYOUT_FILL_Y)
204
+ reset_button.connect(SEL_COMMAND){ resetFilter() }
205
+
206
+ text_box_frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_SUNKEN|FRAME_THICK, :padding => 0)
207
+
208
+ @simple_text_view = SimpleTextView.new(text_box_frame, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y,:padding => 0)
209
+ @simple_text_view.style = 1
210
+ @simple_text_view.editable = false
211
+ @simple_text_view.textStyle -= TEXT_WORDWRAP
212
+
213
+ addHotkeyHandler(@simple_text_view.textbox)
214
+ addHotkeyHandler(@filter_text)
215
+
216
+ @filter_dt.connect(SEL_COMMAND) { applyFilter() }
217
+
218
+ end
219
+
220
+ def applyFilter
221
+ pattern = @filter_text.text
222
+ @match_pos_label.text = "0/0"
223
+ @simple_text_view.resetMatches()
224
+ @simple_text_view.setText(@text)
225
+ @match_pos_label.textColor = 'grey'
226
+ return true if pattern == ''
227
+ case @filter_mode
228
+ when SEL_TYPE_GREP
229
+ grepPattern(pattern)
230
+ when SEL_TYPE_HIGHLIGHT
231
+ highlightPattern(pattern)
232
+ end
233
+ end
234
+
235
+ private
236
+
237
+ def gotoNextMatch()
238
+ @cur_match_pos += 1 if @cur_match_pos < @simple_text_view.numMatches-1
239
+ @simple_text_view.makeMatchVisible(@cur_match_pos)
240
+ @match_pos_label.text = "#{@cur_match_pos+1}/#{@simple_text_view.numMatches}" if @simple_text_view.numMatches > 0
241
+ end
242
+
243
+ def gotoPrevMatch()
244
+ @cur_match_pos -= 1 if @cur_match_pos > 0
245
+ @simple_text_view.makeMatchVisible(@cur_match_pos)
246
+ @match_pos_label.text = "#{@cur_match_pos+1}/#{@simple_text_view.numMatches}" if @simple_text_view.numMatches > 0
247
+ end
248
+
249
+ def addFilterHistory()
250
+ text = @filter_text.text
251
+ return true if text == ''
252
+ has_item = false
253
+ @filter_text.each do |item, data|
254
+ has_item = true if data == text
255
+ end
256
+ @filter_text.appendItem(text, text) unless has_item == true
257
+ @filter_text.numVisible = @filter_text.numItems
258
+ end
259
+
260
+ def resetFilter
261
+ @simple_text_view.max_len = 0
262
+ @simple_text_view.setText(@text)
263
+ @match_pos_label.text = "0/0"
264
+ @match_pos_label.textColor = 'grey'
265
+ @filter_text.text = ''
266
+ end
267
+
268
+ def highlightPattern(pattern)
269
+ @cur_match_pos = 0
270
+ @simple_text_view.max_len = 0
271
+
272
+ @match_pos_label.textColor = 'black'
273
+
274
+ @simple_text_view.setText(@text)
275
+ @simple_text_view.highlight(pattern)
276
+ @match_pos_label.text = "0/#{@simple_text_view.numMatches()}"
277
+
278
+ @simple_text_view.makeMatchVisible(0)
279
+
280
+ @match_pos_label.text = "1/#{@simple_text_view.numMatches()}" if @simple_text_view.numMatches() > 0
281
+
282
+ end
283
+
284
+ def grepPattern(pattern)
285
+ @cur_match_pos = 0
286
+ @simple_text_view.max_len = 0
287
+
288
+ @match_pos_label.textColor = 'black'
289
+
290
+ @simple_text_view.setText(@text)
291
+
292
+ @simple_text_view.filter(pattern)
293
+ @match_pos_label.text = "0/#{@simple_text_view.numMatches()}"
294
+ @simple_text_view.highlight(pattern)
295
+ @simple_text_view.makeMatchVisible(0)
296
+
297
+ @filter_mode = SEL_TYPE_GREP
298
+
299
+ @match_pos_label.text = "1/#{@simple_text_view.numMatches()}" if @simple_text_view.numMatches() > 0
300
+
301
+ end
302
+
303
+ def addHotkeyHandler(widget)
304
+ @ctrl_pressed = false
305
+
306
+ widget.connect(SEL_KEYPRESS) { |sender, sel, event|
307
+ # puts event.code
308
+ @ctrl_pressed = true if event.code == KEY_Control_L or event.code == KEY_Control_R
309
+ # @shift_pressed = true if @ctrl_pressed and ( event.code == KEY_Shift_L or event.code == KEY_Shift_R )
310
+ if event.code == KEY_Return
311
+ highlight(@filter_text.text)
312
+ true # special handling of KEY_Return, because we don't want a linebreak in textbox.
313
+ end
314
+
315
+ if event.code == KEY_F1
316
+
317
+ unless event.moved?
318
+ FXMenuPane.new(self) do |menu_pane|
319
+ FXMenuCaption.new(menu_pane, "Hotkeys:")
320
+ FXMenuSeparator.new(menu_pane)
321
+ [ "<ctrl-r> - Reset Filter",
322
+ "<ctrl-g> - Grep",
323
+ "<ctrl-h> - Highlight",
324
+ "<ctrl-n> - Goto Next",
325
+ "<ctrl-shift-n> - Goto Prev",
326
+ "<ctrl-w> - Switch Wordwrap"
327
+ ].each do |hk|
328
+ FXMenuCaption.new(menu_pane, hk).backColor = 'yellow'
329
+ end
330
+
331
+ menu_pane.create
332
+ menu_pane.popup(nil, event.root_x, event.root_y)
333
+ app.runModalWhileShown(menu_pane)
334
+ end
335
+
336
+ end
337
+ end
338
+
339
+ if @ctrl_pressed
340
+ case event.code
341
+ when KEY_n
342
+ gotoNextMatch()
343
+ addFilterHistory()
344
+ when KEY_N
345
+ gotoPrevMatch()
346
+ addFilterHistory()
347
+ when KEY_w
348
+ @simple_text_view.textbox.textStyle ^= TEXT_WORDWRAP
349
+ when KEY_h
350
+ @mode_btn.text = "Highlight"
351
+ @filter_mode = SEL_TYPE_HIGHLIGHT
352
+ addFilterHistory()
353
+ applyFilter()
354
+ when KEY_g
355
+ @mode_btn.text = "Grep"
356
+ @filter_mode = SEL_TYPE_GREP
357
+ addFilterHistory()
358
+ applyFilter()
359
+ when KEY_r
360
+ resetFilter()
361
+
362
+ end
363
+ end
364
+ false
365
+ }
366
+
367
+ widget.connect(SEL_KEYRELEASE) { |sender, sel, event|
368
+ @ctrl_pressed = false if event.code == KEY_Control_L or event.code == KEY_Control_R
369
+ false
370
+ }
371
+ end
372
+
373
+ end
374
+ end
384
375
  end