watobo 0.9.11 → 0.9.12

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 (40) hide show
  1. data/CHANGELOG +12 -0
  2. data/bin/watobo +9 -1
  3. data/lib/watobo/adapters/data_store.rb +14 -1
  4. data/lib/watobo/adapters/file/file_store.rb +33 -0
  5. data/lib/watobo/core/active_check.rb +3 -2
  6. data/lib/watobo/core/project.rb +6 -2
  7. data/lib/watobo/core/scanner.rb +7 -1
  8. data/lib/watobo/core/session.rb +3 -1
  9. data/lib/watobo/gui/checkboxtree.rb +243 -101
  10. data/lib/watobo/gui/checks_policy_frame.rb +60 -22
  11. data/lib/watobo/gui/dashboard.rb +25 -4
  12. data/lib/watobo/gui/findings_tree.rb +35 -46
  13. data/lib/watobo/gui/full_scan_dialog.rb +2 -1
  14. data/lib/watobo/gui/fuzzer_gui.rb +1 -1
  15. data/lib/watobo/gui/interceptor_settings_dialog.rb +1 -1
  16. data/lib/watobo/gui/log_viewer.rb +3 -1
  17. data/lib/watobo/gui/main_window.rb +9 -9
  18. data/lib/watobo/gui/manual_request_editor.rb +11 -1
  19. data/lib/watobo/gui/progress_window.rb +16 -6
  20. data/lib/watobo/gui/quick_scan_dialog.rb +5 -5
  21. data/lib/watobo/gui/templates/plugin2.rb +13 -26
  22. data/lib/watobo/mixins/shapers.rb +4 -2
  23. data/lib/watobo.rb +1 -1
  24. data/modules/active/Apache/mod_status.rb +4 -3
  25. data/modules/active/sap/its_commands.rb +1 -1
  26. data/modules/active/sap/its_service_parameter.rb +1 -1
  27. data/modules/active/siebel/siebel_apps.rb +184 -0
  28. data/modules/passive/disclosure_domino.rb +82 -0
  29. data/modules/passive/form_spotter.rb +2 -1
  30. data/plugins/catalog/catalog.rb +63 -25
  31. data/plugins/crawler/gui/crawler_gui.rb +8 -6
  32. data/plugins/crawler/gui/general_settings_frame.rb +4 -4
  33. data/plugins/crawler/lib/grabber.rb +2 -2
  34. data/plugins/filefinder/dbs/hbci.db +1 -0
  35. data/plugins/filefinder/dbs/well_known.db +4 -0
  36. data/plugins/filefinder/filefinder.rb +11 -8
  37. data/plugins/sqlmap/gui/main.rb +17 -5
  38. data/plugins/sslchecker/gui/cipher_table.rb +1 -1
  39. data/plugins/sslchecker/gui/gui.rb +33 -14
  40. metadata +5 -2
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ = Version 0.9.12
2
+ == NEW
3
+ * [Module] Siebel Checks: Enumeration of default apps and files, e.g. base.txt
4
+ * [Module] PassiveCheck filtering Domino DB names
5
+ * [GUI] added De-Select-All buttons to scan policy
6
+ * [GUI] finding details menu available at finding-class level
7
+
8
+ == Fixes
9
+ * crash when pasting data (Linux)
10
+ * crash on starting full scan dialog
11
+ * minor issue when adding a new db-path to catalog scanner plugin
12
+
1
13
  = Version 0.9.11
2
14
  == NEW
3
15
  * [FileFinder] pimped the interface, added save-settings
data/bin/watobo CHANGED
@@ -1,2 +1,10 @@
1
1
  #!/bin/ruby
2
- puts "Please use the command watobo_gui.rb to start watobo."
2
+ # this is just a little wrapper to start watobo with another command than watobo_gui.rb
3
+ if $0 == __FILE__
4
+ inc_path = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")) # this is the same as rubygems would do
5
+ $: << inc_path
6
+ end
7
+
8
+ path = File.dirname(File.expand_path(__FILE__))
9
+ require File.join(path, "watobo_gui")
10
+
@@ -20,7 +20,13 @@
20
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  # .
22
22
  module Watobo
23
- class DataStore
23
+ class DataStore
24
+
25
+ @engine = nil
26
+
27
+ def self.engine
28
+ @engine
29
+ end
24
30
 
25
31
  def self.acquire(project_name, session_name)
26
32
  a = Watobo::Conf::Datastore.adapter
@@ -30,9 +36,16 @@ module Watobo
30
36
  else
31
37
  nil
32
38
  end
39
+ @engine = store
33
40
  store
34
41
  end
35
42
 
36
43
 
37
44
  end
45
+
46
+ def self.log(message, prefs={})
47
+ if DataStore.engine.respond_to? :logger
48
+ DataStore.engine.logger message, prefs
49
+ end
50
+ end
38
51
  end
@@ -149,6 +149,10 @@ module Watobo
149
149
  wsp = Watobo.workspace_path
150
150
  return false unless File.exist? wsp
151
151
  puts "* using workspace path: #{wsp}" if $DEBUG
152
+
153
+ @log_file = nil
154
+ @log_lock = Mutex.new
155
+
152
156
  @project_path = File.join(wsp, project_name)
153
157
  unless File.exist? @project_path
154
158
  puts "* create project path: #{@project_path}" if $DEBUG
@@ -193,6 +197,8 @@ module Watobo
193
197
  end
194
198
  end
195
199
  end
200
+
201
+ @log_file = File.join(@log_path, session_name + ".log")
196
202
 
197
203
  # @chat_files = get_file_list(@conversation_path, "*-chat")
198
204
  # @finding_files = get_file_list(@findings_path, "*-finding")
@@ -248,6 +254,33 @@ module Watobo
248
254
  s = Watobo::Utils.load_settings(project_file)
249
255
  s
250
256
 
257
+ end
258
+
259
+ def logger( message, prefs = {} )
260
+ opts = { :sender => "unknown", :level => Watobo::Constants::LOG_INFO }
261
+ opts.update prefs
262
+ return false if @log_file.nil?
263
+ begin
264
+ t = Time.now
265
+ now = t.strftime("%m/%d/%Y @ %H:%M:%S")
266
+ log_message = [ now ]
267
+ log_message << "#{opts[:sender]}"
268
+ if message.is_a? Array
269
+ log_message << message.join("\n| ")
270
+ log_message << "\n-"
271
+ else
272
+ log_message << message
273
+ end
274
+ @log_lock.synchronize do
275
+ File.open(@log_file,"a") do |lfh|
276
+ lfh.puts log_message.join("|")
277
+ end
278
+ end
279
+ rescue => bang
280
+ puts bang
281
+ end
282
+
283
+
251
284
  end
252
285
 
253
286
  private
@@ -55,10 +55,11 @@ module Watobo
55
55
  id_string << new_details[:title] if new_details[:title]
56
56
 
57
57
  if id_string == '' then
58
- id_string = rand(10000)
58
+ id_string = (Time.now.to_i + rand(10000)).to_s
59
59
  end
60
60
  #
61
61
  new_details[:fid] = Digest::MD5.hexdigest(id_string)
62
+ puts new_details[:fid] if $DEBUG
62
63
 
63
64
  new_details[:module] = self.class.to_s
64
65
  # new_details[:module] = Module.nesting[]
@@ -67,7 +68,7 @@ module Watobo
67
68
  new_details.delete(:chat)
68
69
 
69
70
  new_finding = Watobo::Finding.new(request, response, new_details)
70
- # puts new_finding
71
+ # puts new_finding
71
72
  notify(:new_finding, new_finding)
72
73
  }
73
74
  end
@@ -640,7 +640,7 @@ module Watobo
640
640
  :save_finding => true
641
641
  }
642
642
  options.update opts
643
- # puts "* add finding #{finding.details[:fid]}" if $DEBUG
643
+ puts "[Project] add finding #{finding.details[:fid]}" if $DEBUG
644
644
 
645
645
  @findings_count ||= Hash.new
646
646
  @findings_count[finding.details[:class]] = 0 unless @findings_count.has_key? finding.details[:class]
@@ -814,7 +814,11 @@ module Watobo
814
814
  # @active_checks = @settings[:active_checks]
815
815
  @settings[:active_checks].each do |am|
816
816
  ac = am.new(self)
817
- ac.subscribe(:new_finding){ |nf| addFinding(nf) }
817
+ # puts "subscribe to #{ac.class}"
818
+ ac.subscribe(:new_finding){ |nf|
819
+ # puts "[subscribe] new_finding"
820
+ addFinding(nf)
821
+ }
818
822
  @active_checks << ac
819
823
  end
820
824
 
@@ -27,6 +27,7 @@ module Watobo
27
27
  attr :progress
28
28
 
29
29
  include Watobo::Constants
30
+
30
31
  def subscribe(event, &callback)
31
32
  (@event_dispatcher_listeners[event] ||= []) << callback
32
33
  end
@@ -264,11 +265,16 @@ module Watobo
264
265
  check.reset()
265
266
  if @prefs[:online_check] == false or siteAlive?(chat) then
266
267
  @check_list << Thread.new(check, chat, check_prefs){|m, c, p|
268
+ begin
267
269
  m_name = m.class.to_s.gsub(/.*::/,'')
268
270
  notify(:module_started, m_name)
269
271
  m.run_checks(c,p)
272
+ rescue => bang
273
+ puts bang
274
+ puts bang.backtrace
275
+ end
270
276
  notify(:logger, LOG_INFO, "finished checks: #{m.class} on chat #{c.id}")
271
- notify(:module_finished, m_name)
277
+ notify(:module_finished, m)
272
278
  }
273
279
  end
274
280
  end
@@ -37,6 +37,8 @@ include Watobo::Constants
37
37
  @@login_in_progress = false
38
38
  def subscribe(event, &callback)
39
39
  (@event_dispatcher_listeners[event] ||= []) << callback
40
+ puts "#{self} : #subscriptions -> #{event} :" + @event_dispatcher_listeners[event].length.to_s
41
+ puts @event_dispatcher_listeners[event].first
40
42
  end
41
43
 
42
44
  def clearEvents(event)
@@ -46,7 +48,7 @@ include Watobo::Constants
46
48
 
47
49
  def notify(event, *args)
48
50
  if @event_dispatcher_listeners[event]
49
- puts "NOTIFY: #{self}(:#{event}) [#{@event_dispatcher_listeners[event].length}]" if $DEBUG
51
+ # puts "NOTIFY: #{self}(:#{event}) [#{@event_dispatcher_listeners[event].length}]" if $DEBUG
50
52
  @event_dispatcher_listeners[event].each do |m|
51
53
  m.call(*args) if m.respond_to? :call
52
54
  end
@@ -19,20 +19,71 @@
19
19
  # along with WATOBO; if not, write to the Free Software
20
20
  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
21
  # .
22
+ if $0 == __FILE__
23
+ inc_path = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
24
+ $: << inc_path
25
+
26
+ require 'watobo'
27
+ require 'watobo/gui'
28
+
29
+ require 'fox16'
30
+
31
+ include Fox
32
+ include Watobo::Constants
33
+
34
+ end
35
+
22
36
  module Watobo
23
37
  module Gui
24
38
  class CheckBoxTreeItem < FXTreeItem
25
39
  attr_accessor :checked
26
-
40
+
27
41
  include Watobo::Gui::Icons
28
- def initialize(text, checked, data)
29
- @checked = checked
30
- icon = ICON_CB_CHECKED
31
- icon = ICON_CB_UNCHECKED if not checked
32
- super(text, icon, icon, data)
42
+ def check
43
+ begin
44
+ @checked = true
45
+ self.setOpenIcon(ICON_CB_CHECKED)
46
+ self.setClosedIcon(ICON_CB_CHECKED)
47
+ # opened = true
48
+ rescue => bang
49
+ puts "!!!ERROR: could not uncheck item"
50
+ end
51
+ end
52
+
53
+ def uncheck
54
+ begin
55
+ @checked = false
56
+ self.setOpenIcon(ICON_CB_UNCHECKED)
57
+ self.setClosedIcon(ICON_CB_UNCHECKED)
58
+ #opened = false
59
+ rescue => bang
60
+ puts "!!!ERROR: could not uncheck item"
61
+ end
62
+ end
63
+
64
+ def toggle
65
+ if @checked
66
+ uncheck
67
+ else
68
+ check
69
+ end
70
+ end
71
+
72
+ def initialize(item_text, item_status, item_data)
73
+ super item_text
74
+ @checked = item_status
75
+ #icon = ICON_CB_CHECKED
76
+ #icon = ICON_CB_UNCHECKED if not status
77
+ #super(text, icon, icon, data)
78
+ # data = item_data
79
+ if @checked
80
+ check
81
+ else
82
+ uncheck
83
+ end
33
84
  end
34
85
  end
35
-
86
+
36
87
  class CheckBoxTreeList < FXTreeList
37
88
  include Watobo::Gui::Icons
38
89
  #------------------------------
@@ -42,51 +93,52 @@ module Watobo
42
93
  # :name => element_name, number of subtrees controlled via pipe-char, e.g. <level1>|<level2>|item
43
94
  # :enabled => true|false,
44
95
  # :data => object|string|...
45
- # }, {..} ]
46
- def createTree(elements)
96
+ # }, {..} ]
97
+ def elements=(elements)
47
98
  self.clearItems()
48
99
  elements.each do |e|
49
-
50
- # puts icon.class.to_s
100
+
101
+ # puts icon.class.to_s
51
102
  node = nil
52
103
  levels = e[:name].split('|')
53
- puts "Processing: #{e[:name]} > #{e[:data].class}" if $DEBUG
54
- levels.each do |l|
55
-
104
+ # puts "Processing: #{e[:name]} > #{e[:data].class}" if $DEBUG
105
+ levels.each_with_index do |l,i|
106
+ #puts "#{l} - #{l.class}"
56
107
  item = self.findItem(l, node, SEARCH_FORWARD|SEARCH_IGNORECASE)
57
-
108
+
58
109
  if item.nil? then
59
- new_item = CheckBoxTreeItem.new(l, e[:enabled], nil)
60
- # item = self.appendItem(node, l, ICON_CB_CHECKED, ICON_CB_CHECKED)
61
- item = self.appendItem(node, new_item)
62
- if e[:enabled] then
63
- self.openItem(item, false)
64
- else
65
- self.closeItem(item, false)
66
- end
110
+ # new_item = CheckBoxTreeItem.new(l, e[:enabled], nil)
111
+ new_item = CheckBoxTreeItem.new(l, e[:enabled], :none)
112
+ # item = self.appendItem(node, l, ICON_CB_CHECKED, ICON_CB_CHECKED)
113
+ item = self.appendItem(node, new_item)
114
+ # if e[:enabled] then
115
+ # self.openItem(item, false)
116
+ # else
117
+ # self.closeItem(item, false)
118
+ # end
67
119
  end
68
120
  node = item
69
- if l == levels.last then
121
+ if i == levels.length-1 then
70
122
  self.setItemData(item, e[:data])
71
123
  updateParent(item)
72
124
  end
73
-
125
+
74
126
  end
75
127
  end
76
128
  end
77
-
129
+
78
130
  def updateParent(child)
79
131
  parent = child.parent
80
132
  # count enabled childs
81
133
  return false if parent.nil?
82
134
  ec = 0
83
135
  parent.each do |item|
84
- #data = self.getItemData(item)
85
- #ec += 1 if data[:enabled]
136
+ #data = self.getItemData(item)
137
+ #ec += 1 if data[:enabled]
86
138
  ec += 1 if item.checked
87
139
  end
88
140
  if ec == 0 then
89
-
141
+
90
142
  # puts "no childs selected"
91
143
  icon = ICON_CB_UNCHECKED
92
144
  self.setItemData(parent, :none)
@@ -95,130 +147,220 @@ module Watobo
95
147
  icon = ICON_CB_CHECKED_ORANGE
96
148
  self.setItemData(parent, :partly)
97
149
  else
98
-
99
- # puts "all childs have been selected"
150
+
151
+ # puts "all childs have been selected"
100
152
  icon = ICON_CB_CHECKED
101
153
  self.setItemData(parent, :all)
102
154
  end
103
155
  self.setItemOpenIcon(parent, icon)
104
156
  self.setItemClosedIcon(parent, icon)
105
157
  end
106
-
107
- def toggleState(item)
108
- # data = self.getItemData(item)
109
- # if data[:enabled] then
110
- if item.checked then
111
- uncheckItem(item)
112
- else
113
- checkItem(item)
114
- end
115
- end
116
-
117
- def uncheckItem(item)
118
- begin
119
- #data = self.getItemData(item)
120
- #data[:enabled]= false
121
- item.checked = false
122
- self.setItemOpenIcon(item, ICON_CB_UNCHECKED)
123
- self.setItemClosedIcon(item, ICON_CB_UNCHECKED)
124
- #puts item.data.class
125
- rescue => bang
126
- puts "!!!ERROR: could not uncheck item"
127
- end
128
-
129
- end
130
-
131
-
132
- def getCheckedData(item = nil, data = nil)
158
+
159
+ def getCheckedData(item = nil, data = nil)
133
160
  data = [] if !data
134
161
  item = self if !item
135
162
  item.each do |c|
136
- getCheckedData(c, data) if c.numChildren > 0
137
- data.push c.data if self.itemLeaf?(c) and c.checked
138
- end
139
- data
163
+ getCheckedData(c, data) if c.numChildren > 0
164
+ data.push c.data if self.itemLeaf?(c) and c.checked
165
+ end
166
+ data
140
167
  end
141
-
142
- def checkItem(item)
143
- begin
144
- #data = self.getItemData(item)
145
- #data[:enabled] = true
146
- item.checked = true
147
- self.setItemClosedIcon(item, ICON_CB_CHECKED)
148
- self.setItemOpenIcon(item, ICON_CB_CHECKED)
149
- # puts item.data.class
150
- rescue => bang
151
- puts "!!!ERROR: could not uncheck item"
168
+
169
+ def checkAll
170
+ self.each do |r|
171
+ r.check
172
+ setItemData(r,:all)
173
+ r.each do |c|
174
+ c.check
175
+ end
176
+ self.update
177
+ # checkAllChildren(r)
178
+ # openItem(child, true)
152
179
  end
153
180
  end
154
-
181
+
182
+ def uncheckAll
183
+ self.each do |r|
184
+ # uncheckItem(r)
185
+ r.uncheck
186
+ setItemData(r,:none)
187
+ r.each do |c|
188
+ c.uncheck
189
+ end
190
+ #uncheckAllChildren(r)
191
+ self.update
192
+ end
193
+ end
194
+
195
+
155
196
  def uncheckAllChildren(parent)
156
197
  parent.each do |child|
157
- uncheckItem(child)
198
+ #uncheckItem(child)
199
+ child.uncheck
158
200
  end
159
201
  end
160
-
202
+
161
203
  def checkAllChildren(parent)
162
204
  parent.each do |child|
163
- checkItem(child)
205
+ #checkItem(child)
206
+ child.check
207
+
164
208
  end
165
209
  end
166
-
210
+
167
211
  def initialize(parent)
168
-
212
+
169
213
  @parent = parent
170
214
  super(parent, :opts => LAYOUT_FILL_X|LAYOUT_FILL_Y|
171
- TREELIST_SHOWS_LINES|
172
- TREELIST_SHOWS_BOXES|
173
- TREELIST_ROOT_BOXES|
174
- #TREELIST_EXTENDEDSELECT|
175
- TREELIST_MULTIPLESELECT
215
+ TREELIST_SHOWS_LINES|
216
+ TREELIST_SHOWS_BOXES|
217
+ TREELIST_ROOT_BOXES|
218
+ #TREELIST_EXTENDEDSELECT|
219
+ TREELIST_MULTIPLESELECT
176
220
  )
177
221
  #LAYOUT_TOP|LAYOUT_RIGHT|TREELIST_SHOWS_LINES|TREELIST_SHOWS_BOXES|TREELIST_ROOT_BOXES|TREELIST_EXTENDEDSELECT
178
-
222
+
179
223
  self.connect(SEL_COMMAND) do |sender, sel, item|
180
224
  if $DEBUG
181
- puts "Selected Item: #{item}"
225
+ puts "Selected Item: #{item}"
182
226
  if item.parent
183
227
  puts "Member Of: #{item.parent}"
184
- puts "Has Brothers: #{item.parent.numChildren}"
228
+ puts "Has Brothers: #{item.parent.numChildren}"
185
229
  end
186
230
  end
231
+
187
232
  if self.itemLeaf?(item) then
188
- toggleState(item)
233
+ #toggleState(item)
234
+ item.toggle
189
235
  updateParent(item)
190
236
  else
191
237
  data = self.getItemData(item)
238
+
192
239
  new_state = case data
193
- when :partly
240
+ when :partly
194
241
  # puts data
195
242
  icon = ICON_CB_UNCHECKED
196
243
  uncheckAllChildren(item)
197
244
  :none
198
- when :none
245
+ when :none
199
246
  # puts data
200
247
  icon = ICON_CB_CHECKED
201
248
  checkAllChildren(item)
202
249
  :all
203
- when :all
250
+ when :all
204
251
  # puts data
205
252
  icon = ICON_CB_UNCHECKED
206
253
  uncheckAllChildren(item)
207
254
  :none
208
255
  end
209
-
210
- self.setItemData(item, new_state)
211
- self.setItemClosedIcon(item, icon)
212
- self.setItemOpenIcon(item, icon)
256
+
257
+ self.setItemData(item, new_state)
258
+ self.setItemClosedIcon(item, icon)
259
+ self.setItemOpenIcon(item, icon)
213
260
  end
214
-
261
+
215
262
  self.killSelection()
216
- end
217
-
218
-
219
-
263
+ end
264
+
220
265
  end
221
266
  end
222
- #--
267
+ #--
223
268
  end
224
269
  end
270
+
271
+ ##########################
272
+
273
+ if $0 == __FILE__
274
+ module Watobo
275
+ module Gui
276
+
277
+ @application ||= FXApp.new('LayoutTester', 'FoxTest')
278
+ class TestGui < FXMainWindow
279
+ class TreeDlg < FXDialogBox
280
+
281
+ include Responder
282
+ def initialize(parent, project=nil, prefs={} )
283
+ super(parent, "CheckBox Dialog", DECOR_ALL, :width => 300, :height => 400)
284
+ FXMAPFUNC(SEL_COMMAND, ID_ACCEPT, :onAccept)
285
+ frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE)
286
+ elements = []
287
+ num_root_nodes = 4
288
+ max_child_nodes = 4
289
+ num_root_nodes.times do |ri|
290
+ max_child_nodes.times do |si|
291
+ name = "root#{ri}|sub#{si}"
292
+ data = name + "-data"
293
+ e = { :name => name, :enabled => false, :data => data }
294
+ elements << e
295
+ end
296
+ end
297
+ @cbtree = CheckBoxTreeList.new(frame)
298
+ @cbtree.elements = elements
299
+
300
+ end
301
+ private
302
+
303
+ def onAccept(sender, sel, event)
304
+ puts "#{self} closed"
305
+
306
+ getApp().stopModal(self, 1)
307
+ self.hide()
308
+ return 1
309
+ end
310
+ end
311
+
312
+ def leave
313
+ d = @cbtree.getCheckedData
314
+ puts d.class
315
+ puts d
316
+ exit
317
+ end
318
+
319
+ def initialize(app)
320
+ # Call base class initializer first
321
+ super(app, "Test Application", :width => 800, :height => 600)
322
+ frame = FXVerticalFrame.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y|FRAME_GROOVE)
323
+
324
+ elements = []
325
+ num_root_nodes = 4
326
+ max_child_nodes = 4
327
+ num_root_nodes.times do |ri|
328
+ max_child_nodes.times do |si|
329
+ name = "root#{ri}|sub#{si}"
330
+ data = name + "-data"
331
+ e = { :name => name, :enabled => false, :data => data }
332
+ elements << e
333
+ end
334
+ end
335
+
336
+ @cbtree = CheckBoxTreeList.new(frame)
337
+ @cbtree.elements = elements
338
+
339
+ FXButton.new(frame, "Select All",:opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT).connect(SEL_COMMAND){ @cbtree.checkAll }
340
+ FXButton.new(frame, "Deselect All",:opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT).connect(SEL_COMMAND){ @cbtree.uncheckAll }
341
+
342
+ FXButton.new(frame, "Open TreeDialog",:opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT).connect(SEL_COMMAND){
343
+ dlg = TreeDlg.new(self)
344
+ if dlg.execute != 0 then
345
+ puts "* Dialog Finished"
346
+ else
347
+ puts "Dialog Canceled"
348
+ end
349
+ }
350
+
351
+ FXButton.new(frame, "Exit",:opts => FRAME_THICK|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_TOP|LAYOUT_LEFT).connect(SEL_COMMAND){ leave }
352
+ end
353
+
354
+ def create
355
+ super # Create the windows
356
+ show(PLACEMENT_SCREEN) # Make the main window appear
357
+ end
358
+ end
359
+ # application = FXApp.new('LayoutTester', 'FoxTest')
360
+ TestGui.new(@application)
361
+ @application.create
362
+ @application.run
363
+
364
+ end
365
+ end
366
+ end