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.
- data/CHANGELOG +12 -0
- data/bin/watobo +9 -1
- data/lib/watobo/adapters/data_store.rb +14 -1
- data/lib/watobo/adapters/file/file_store.rb +33 -0
- data/lib/watobo/core/active_check.rb +3 -2
- data/lib/watobo/core/project.rb +6 -2
- data/lib/watobo/core/scanner.rb +7 -1
- data/lib/watobo/core/session.rb +3 -1
- data/lib/watobo/gui/checkboxtree.rb +243 -101
- data/lib/watobo/gui/checks_policy_frame.rb +60 -22
- data/lib/watobo/gui/dashboard.rb +25 -4
- data/lib/watobo/gui/findings_tree.rb +35 -46
- data/lib/watobo/gui/full_scan_dialog.rb +2 -1
- data/lib/watobo/gui/fuzzer_gui.rb +1 -1
- data/lib/watobo/gui/interceptor_settings_dialog.rb +1 -1
- data/lib/watobo/gui/log_viewer.rb +3 -1
- data/lib/watobo/gui/main_window.rb +9 -9
- data/lib/watobo/gui/manual_request_editor.rb +11 -1
- data/lib/watobo/gui/progress_window.rb +16 -6
- data/lib/watobo/gui/quick_scan_dialog.rb +5 -5
- data/lib/watobo/gui/templates/plugin2.rb +13 -26
- data/lib/watobo/mixins/shapers.rb +4 -2
- data/lib/watobo.rb +1 -1
- data/modules/active/Apache/mod_status.rb +4 -3
- data/modules/active/sap/its_commands.rb +1 -1
- data/modules/active/sap/its_service_parameter.rb +1 -1
- data/modules/active/siebel/siebel_apps.rb +184 -0
- data/modules/passive/disclosure_domino.rb +82 -0
- data/modules/passive/form_spotter.rb +2 -1
- data/plugins/catalog/catalog.rb +63 -25
- data/plugins/crawler/gui/crawler_gui.rb +8 -6
- data/plugins/crawler/gui/general_settings_frame.rb +4 -4
- data/plugins/crawler/lib/grabber.rb +2 -2
- data/plugins/filefinder/dbs/hbci.db +1 -0
- data/plugins/filefinder/dbs/well_known.db +4 -0
- data/plugins/filefinder/filefinder.rb +11 -8
- data/plugins/sqlmap/gui/main.rb +17 -5
- data/plugins/sslchecker/gui/cipher_table.rb +1 -1
- data/plugins/sslchecker/gui/gui.rb +33 -14
- 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
|
-
|
|
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
|
-
|
|
71
|
+
# puts new_finding
|
|
71
72
|
notify(:new_finding, new_finding)
|
|
72
73
|
}
|
|
73
74
|
end
|
data/lib/watobo/core/project.rb
CHANGED
|
@@ -640,7 +640,7 @@ module Watobo
|
|
|
640
640
|
:save_finding => true
|
|
641
641
|
}
|
|
642
642
|
options.update opts
|
|
643
|
-
|
|
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
|
-
|
|
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
|
|
data/lib/watobo/core/scanner.rb
CHANGED
|
@@ -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,
|
|
277
|
+
notify(:module_finished, m)
|
|
272
278
|
}
|
|
273
279
|
end
|
|
274
280
|
end
|
data/lib/watobo/core/session.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
|
96
|
+
# }, {..} ]
|
|
97
|
+
def elements=(elements)
|
|
47
98
|
self.clearItems()
|
|
48
99
|
elements.each do |e|
|
|
49
|
-
|
|
50
|
-
|
|
100
|
+
|
|
101
|
+
# puts icon.class.to_s
|
|
51
102
|
node = nil
|
|
52
103
|
levels = e[:name].split('|')
|
|
53
|
-
|
|
54
|
-
levels.
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
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
|
-
|
|
85
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
225
|
+
puts "Selected Item: #{item}"
|
|
182
226
|
if item.parent
|
|
183
227
|
puts "Member Of: #{item.parent}"
|
|
184
|
-
|
|
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
|
-
|
|
240
|
+
when :partly
|
|
194
241
|
# puts data
|
|
195
242
|
icon = ICON_CB_UNCHECKED
|
|
196
243
|
uncheckAllChildren(item)
|
|
197
244
|
:none
|
|
198
|
-
|
|
245
|
+
when :none
|
|
199
246
|
# puts data
|
|
200
247
|
icon = ICON_CB_CHECKED
|
|
201
248
|
checkAllChildren(item)
|
|
202
249
|
:all
|
|
203
|
-
|
|
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
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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
|