C0 code coverage information
Generated on Tue Oct 16 11:40:51 -0400 2007 with rcov 0.8.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Copyright (C) 2004-2006 Laurent Sansonetti
2 #
3 # Alexandria is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License as
5 # published by the Free Software Foundation; either version 2 of the
6 # License, or (at your option) any later version.
7 #
8 # Alexandria is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public
14 # License along with Alexandria; see the file COPYING. If not,
15 # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 # Boston, MA 02111-1307, USA.
17
18 module Alexandria
19 module UI
20 class SmartLibraryPropertiesDialogBase < Gtk::Dialog
21 include GetText
22 GetText.bindtextdomain(Alexandria::TEXTDOMAIN, nil, nil, "UTF-8")
23
24 attr_reader :predicate_operator_rule
25
26 def initialize(parent)
27 super("", parent, Gtk::Dialog::MODAL,
28 [Gtk::Stock::HELP, Gtk::Dialog::RESPONSE_HELP])
29
30 self.window_position = Gtk::Window::POS_CENTER
31 self.has_separator = false
32 self.resizable = true
33 self.border_width = 4
34 self.vbox.border_width = 12
35
36 main_box = Gtk::VBox.new
37 main_box.border_width = 4
38 main_box.spacing = 8
39
40 self.vbox << main_box
41
42 @smart_library_rules = []
43
44 @rules_header_box = Gtk::HBox.new
45 @rules_header_box.spacing = 2
46
47 @rules_box = Gtk::VBox.new
48 @rules_box.spacing = 8
49 @rules_box.border_width = 8
50
51 scrollview = Gtk::ScrolledWindow.new
52 scrollview.hscrollbar_policy = Gtk::POLICY_NEVER
53 scrollview.vscrollbar_policy = Gtk::POLICY_AUTOMATIC
54 scrollview.set_size_request(-1, 125)
55 scrollview.add_with_viewport(@rules_box)
56
57 main_box.pack_start(@rules_header_box, false, false, 0)
58 main_box << scrollview
59 end
60
61 #########
62 protected
63 #########
64
65 def smart_library_rules
66 fill_smart_library_rules_values
67 return @smart_library_rules
68 end
69
70 def has_weirdnesses?
71 fill_smart_library_rules_values
72 smart_library_rules.each do |rule|
73 return true if rule.value == ""
74 end
75 return false
76 end
77
78 def user_confirms_possible_weirdnesses_before_saving?
79 return true unless has_weirdnesses?
80 dialog = AlertDialog.new(
81 self,
82 _("Empty or conflictive condition"),
83 Gtk::Stock::DIALOG_QUESTION,
84 [[Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL],
85 [_("_Save However"), Gtk::Dialog::RESPONSE_YES]],
86 _("This smart library contains one or more conditions " +
87 "which are empty or conflict with each other. This is " +
88 "likely to result in never matching a book. Are you " +
89 "sure you want to save this library?"))
90 dialog.default_response = Gtk::Dialog::RESPONSE_CANCEL
91 dialog.show_all
92 confirmed = dialog.run == Gtk::Dialog::RESPONSE_YES
93 dialog.destroy
94 return confirmed
95 end
96
97 def update_rules_header_box(predicate_operator_rule=
98 SmartLibrary::ALL_RULES)
99
100 @rules_header_box.children.each { |x| @rules_header_box.remove(x) }
101
102 if @rules_box.children.length > 1
103 label1 = Gtk::Label.new
104 label1.set_alignment(0.0, 0.5)
105 label1.text = _("Match")
106
107 cb = Gtk::ComboBox.new
108 [_("all"), _("any")].each { |x| cb.append_text(x) }
109 cb.signal_connect('changed') do
110 @predicate_operator_rule = cb.active == 0 \
111 ? SmartLibrary::ALL_RULES : SmartLibrary::ANY_RULE
112 end
113 cb.active =
114 predicate_operator_rule == SmartLibrary::ALL_RULES ? 0 : 1
115
116 label2 = Gtk::Label.new
117 label2.set_alignment(0.0, 0.5)
118 label2.text = _("of the following rules:")
119
120 @rules_header_box.pack_start(label1, false, false, 0)
121 @rules_header_box.pack_start(cb, false, false, 0)
122 @rules_header_box.pack_start(label2, false, false, 0)
123 else
124 label = Gtk::Label.new
125 label.set_alignment(0.0, 0.5)
126 label.text = _("Match the following rule:")
127 @rules_header_box << label
128 @predicate_operator_rule = SmartLibrary::ALL_RULES
129 end
130
131 @rules_header_box.show_all
132 end
133
134 def insert_new_rule(rule=nil)
135 rule_box = Gtk::HBox.new
136 rule_box.spacing = 8
137
138 left_operand_combo = Gtk::ComboBox.new
139 operator_combo = Gtk::ComboBox.new
140 value_entry = Gtk::Entry.new
141 date_entry = Gnome::DateEdit.new(0, false, false)
142 # Really hide the time part of the date entry, as the constructor
143 # does not seem to do it...
144 date_entry.children[2..3].each { |x| date_entry.remove(x) }
145 date_entry.spacing = 8
146 entry_label = Gtk::Label.new("")
147
148 add_button = Gtk::Button.new("")
149 add_button.remove(add_button.children.first)
150 add_button << Gtk::Image.new(Gtk::Stock::ADD,
151 Gtk::IconSize::BUTTON)
152
153 add_button.signal_connect('clicked') { insert_new_rule }
154
155 remove_button = Gtk::Button.new("")
156 remove_button.remove(remove_button.children.first)
157 remove_button << Gtk::Image.new(Gtk::Stock::REMOVE,
158 Gtk::IconSize::BUTTON)
159
160 remove_button.signal_connect('clicked') do |button|
161 idx = @rules_box.children.index(rule_box)
162 raise if idx.nil?
163 @smart_library_rules.delete_at(idx)
164 @rules_box.remove(rule_box)
165 sensitize_remove_rule_buttons
166 update_rules_header_box
167 end
168
169 operands = SmartLibrary::Rule::Operands::LEFT
170 operands.each do |operand|
171 left_operand_combo.append_text(operand.name)
172 end
173 operator_combo.signal_connect('changed') do
174 operand = operands[left_operand_combo.active]
175 operations = SmartLibrary::Rule.operations_for_operand(operand)
176 operation = operations[operator_combo.active]
177
178 value_entry.visible = date_entry.visible =
179 entry_label.visible = false
180 right_operand = operation.last
181 unless right_operand.nil?
182 entry = case right_operand.klass.name
183 when 'Time'
184 date_entry
185 else
186 value_entry
187 end
188 entry.visible = true
189 unless right_operand.name.nil?
190 entry_label.text = right_operand.name
191 entry_label.visible = true
192 end
193 end
194
195 idx = @rules_box.children.index(rule_box)
196 new_rule = @smart_library_rules[idx]
197 if new_rule.nil?
198 new_rule = SmartLibrary::Rule.new(operand,
199 operation.first,
200 nil)
201 @smart_library_rules << new_rule
202 end
203 new_rule.operand = operand
204 new_rule.operation = operation.first
205 new_rule.value = nil
206 end
207 left_operand_combo.signal_connect('changed') do
208 operand = operands[left_operand_combo.active]
209 operator_combo.freeze_notify do
210 operator_combo.model.clear
211 operations = SmartLibrary::Rule.operations_for_operand(operand)
212 operations.each do |operation|
213 operator = operation.first
214 operator_combo.append_text(operator.name)
215 end
216 operator_combo.active = 0
217 end
218 end
219
220 rule_box.pack_start(left_operand_combo, false, false, 0)
221 rule_box.pack_start(operator_combo, false, false, 0)
222 rule_box.pack_start(value_entry)
223 rule_box.pack_start(date_entry)
224 rule_box.pack_start(entry_label, false, false, 0)
225 rule_box.pack_end(remove_button, false, false, 0)
226 rule_box.pack_end(add_button, false, false, 0)
227
228 rule_box.show_all
229 value_entry.visible = date_entry.visible = entry_label.visible =
230 false
231
232 @rules_box.pack_start(rule_box, false, true, 0)
233
234 if rule
235 operand_idx = operands.index(rule.operand)
236 operations =
237 SmartLibrary::Rule.operations_for_operand(rule.operand)
238 operation_idx = operations.map \
239 { |x| x.first }.index(rule.operation)
240
241 if operand_idx != nil and operation_idx != nil
242 left_operand_combo.active = operand_idx
243 operator_combo.active = operation_idx
244 if rule.value != nil
245 case rule.value
246 when String
247 value_entry.text = rule.value
248 when Time
249 date_entry.time = rule.value.tv_sec
250 end
251 end
252 end
253 else
254 left_operand_combo.active = 0
255 end
256
257 @rules_box.check_resize # force a layout
258 update_rules_header_box
259 sensitize_remove_rule_buttons
260 end
261
262 def sensitize_remove_rule_buttons
263 boxes = @rules_box.children
264 state = boxes.length > 1
265 boxes.each do |box|
266 button = box.children[-1]
267 if button.is_a?(Gtk::Button)
268 button.sensitive = state
269 end
270 end
271 end
272
273 def fill_smart_library_rules_values
274 @rules_box.children.each_with_index do |box, i|
275 entry, date = box.children[2..3]
276 @smart_library_rules[i].value = if entry.visible?
277 entry.text.strip
278 elsif date.visible?
279 Time.at(date.time)
280 end
281 end
282 end
283 end
284 end
285 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.