~roadmr/ubuntu/precise/checkbox/0.13.1

« back to all changes in this revision

Viewing changes to checkbox_gtk/gtk_interface.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Tardif, Gabor Keleman
  • Date: 2009-08-19 15:36:05 UTC
  • Revision ID: james.westby@ubuntu.com-20090819153605-weo6htup3yi6zn0t
Tags: 0.8~alpha4
* New upstream version:
  * Changed icon.
  * Added timeout property to lock_prompt plugin.
  * Added concept of attachments to tests.
  * Added support for backslahes in templates to wrap lines.
  * Added support blacklisting and whitelisting both tests and suites.
  * Introduced the concept of jobs for suites, tests and attachments.
  * Removed upstart event which is no longer needed.
  * Replaced architecture and category with requires in test definitions.
* Fixed pygst dependency (LP: #334442)
* Fixed configuration file updates during install (LP: #330596)
* Fixed and expanded translations (LP: #347038)
* Fixed ignored system proxy settings (LP: #345548)
* Fixed parsing blank lines in templates (LP: #393907)
* Fixed escaping of lists (LP: #394001)
* Fixed timeout in manual tests (LP: #377986)
* Fixed CLI interface dialog.
* Fixed support for FreeDesktop XDG base directory specification (LP: #363549)
* Added general and package specific apport hooks

[ Gabor Keleman ]
* Fixed untranslated strings in tests (LP: #374666)
* Fixed untranslated last screen (LP: #374646)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
import posixpath
22
22
 
23
23
from gettext import gettext as _
24
 
 
25
 
from checkbox.test import ALL_STATUS, TestResult
26
 
from checkbox.user_interface import UserInterface
 
24
from string import Template
 
25
 
 
26
from checkbox.lib.iterator import NEXT
 
27
 
 
28
from checkbox.job import Job, UNINITIATED
 
29
from checkbox.user_interface import (UserInterface,
 
30
    YES_ANSWER, NO_ANSWER, SKIP_ANSWER,
 
31
    ANSWER_TO_STATUS, STATUS_TO_ANSWER)
27
32
 
28
33
# Import to register HyperTextView type with gtk
29
34
from checkbox_gtk.hyper_text_view import HyperTextView
30
35
 
31
36
 
 
37
ANSWER_TO_BUTTON = {
 
38
    YES_ANSWER: "radio_button_yes",
 
39
    NO_ANSWER: "radio_button_no",
 
40
    SKIP_ANSWER: "radio_button_skip"}
 
41
 
 
42
BUTTON_TO_STATUS = dict((b, ANSWER_TO_STATUS[a])
 
43
    for a, b in ANSWER_TO_BUTTON.items())
 
44
 
 
45
STATUS_TO_BUTTON = dict((s, ANSWER_TO_BUTTON[a])
 
46
    for s, a in STATUS_TO_ANSWER.items())
 
47
 
 
48
 
32
49
# HACK: Setting and unsetting previous and next buttons to workaround
33
50
#       for gnome bug #56070.
34
51
class GTKHack(object):
77
94
        self._notebook = self._get_widget("notebook_main")
78
95
        self._handler_id = None
79
96
 
80
 
    def _get_widget(self, widget):
81
 
        return self.widgets.get_widget(widget)
 
97
    def _get_widget(self, name):
 
98
        return self.widgets.get_widget(name)
82
99
 
83
100
    def _get_radio_button(self, map):
84
101
        for radio_button, value in map.items():
86
103
                return value
87
104
        raise Exception, "Failed to map radio_button."
88
105
 
 
106
    def _get_label(self, name):
 
107
        widget = self._get_widget(name)
 
108
        return widget.get_label()
 
109
 
89
110
    def _get_text(self, name):
90
111
        widget = self._get_widget(name)
91
112
        return widget.get_text()
155
176
        widget = self._get_widget(name)
156
177
        widget.set_sensitive(bool(value))
157
178
 
 
179
    def _set_button(self, name, value=None):
 
180
        if value is None:
 
181
            state = value
 
182
        else:
 
183
            state = self._get_label(name)
 
184
            if value == "":
 
185
                self._set_sensitive(name, False)
 
186
            else:
 
187
                self._set_sensitive(name, True)
 
188
                self._set_label(name, value)
 
189
 
 
190
        return state
 
191
 
158
192
    def _run_dialog(self, dialog=None):
159
193
        def on_dialog_response(dialog, response, self):
160
194
            self.direction = response
194
228
            gtk.main_iteration()
195
229
 
196
230
    @GTKHack
197
 
    def show_intro(self, title, text):
 
231
    def show_text(self, text, previous=None, next=None):
198
232
        # Set buttons
199
 
        self._set_sensitive("button_previous", False)
 
233
        previous_state = self._set_button("button_previous", previous)
 
234
        next_state = self._set_button("button_next", next)
 
235
 
200
236
        self._notebook.set_current_page(0)
201
237
 
202
 
        intro = "\n\n".join([title, text])
203
 
        self._set_hyper_text_view("hyper_text_view_intro_text", intro)
204
 
 
205
 
        self._run_dialog()
206
 
 
207
 
        self._set_sensitive("button_previous", True)
208
 
 
209
 
    @GTKHack
210
 
    def show_category(self, title, text, category=None):
211
 
        # Set buttons
212
 
        self._notebook.set_current_page(1)
213
 
 
214
 
        self._set_hyper_text_view("hyper_text_view_category", text)
215
 
        if category:
216
 
            self._set_active("radio_button_%s" % category)
217
 
 
218
 
        self._run_dialog()
219
 
 
220
 
        return self._get_radio_button({
221
 
            "radio_button_desktop": "desktop",
222
 
            "radio_button_laptop": "laptop",
223
 
            "radio_button_server": "server"})
 
238
        self._set_hyper_text_view("hyper_text_view_text", text)
 
239
 
 
240
        self._run_dialog()
 
241
 
 
242
        # Unset buttons
 
243
        self._set_button("button_previous", previous_state)
 
244
        self._set_button("button_next", next_state)
 
245
 
 
246
    @GTKHack
 
247
    def show_entry(self, text, value, previous=None, next=None):
 
248
        # Set buttons
 
249
        previous_state = self._set_button("button_previous", previous)
 
250
        next_state = self._set_button("button_next", next)
 
251
 
 
252
        self._notebook.set_current_page(3)
 
253
 
 
254
        if value is not None:
 
255
            self._set_text("entry", value)
 
256
 
 
257
        self._set_hyper_text_view("hyper_text_view_entry", text)
 
258
 
 
259
        self._run_dialog()
 
260
 
 
261
        # Unset buttons
 
262
        self._set_button("button_previous", previous_state)
 
263
        self._set_button("button_next", next_state)
 
264
 
 
265
        return self._get_text("entry")
 
266
 
 
267
    @GTKHack
 
268
    def show_check(self, text, options=[], default=[]):
 
269
        # Set buttons
 
270
        self._notebook.set_current_page(1)
 
271
 
 
272
        # Set options
 
273
        option_table = {}
 
274
        vbox = self._get_widget("vbox_options")
 
275
        for option in options:
 
276
            label = "_%s" % option.capitalize()
 
277
            radio_button = gtk.CheckButton(label)
 
278
            radio_button.show()
 
279
            option_table[option] = radio_button
 
280
            vbox.pack_start(radio_button, False, False, 0)
 
281
            if option in default:
 
282
                radio_button.set_active(True)
 
283
 
 
284
        self._set_hyper_text_view("hyper_text_view_options", text)
 
285
 
 
286
        self._run_dialog()
 
287
 
 
288
        # Get options
 
289
        results = []
 
290
        for option, check_button in option_table.items():
 
291
            if check_button.get_active():
 
292
                results.append(option)
 
293
            vbox.remove(check_button)
 
294
 
 
295
        return results
 
296
 
 
297
    @GTKHack
 
298
    def show_radio(self, text, options=[], default=None):
 
299
        # Set buttons
 
300
        self._notebook.set_current_page(1)
 
301
 
 
302
        # Set options
 
303
        option_group = None
 
304
        option_table = {}
 
305
        vbox = self._get_widget("vbox_options")
 
306
        for option in options:
 
307
            label = "_%s" % option.capitalize()
 
308
            radio_button = gtk.RadioButton(option_group, label)
 
309
            radio_button.show()
 
310
            option_table[option] = radio_button
 
311
            vbox.pack_start(radio_button, False, False, 0)
 
312
            if option_group is None:
 
313
                option_group = radio_button
 
314
            if option == default:
 
315
                radio_button.set_active(True)
 
316
 
 
317
        self._set_hyper_text_view("hyper_text_view_options", text)
 
318
 
 
319
        self._run_dialog()
 
320
 
 
321
        # Get option
 
322
        result = None
 
323
        for option, radio_button in option_table.items():
 
324
            if radio_button.get_active():
 
325
                result = option
 
326
            vbox.remove(radio_button)
 
327
 
 
328
        return result
224
329
 
225
330
    def _run_test(self, test):
226
331
        self._set_sensitive("button_test", False)
227
332
 
228
 
        message = _("Running test %s...") % test.name
229
 
        result = self.show_wait(message, test.command)
 
333
        message = _("Running test %s...") % test["name"]
 
334
        job = Job(test["command"], test.get("environ"), test.get("timeout"))
 
335
        self.show_wait(message, job.execute)
230
336
 
231
 
        description = self.do_function(test.description, result)
 
337
        description = Template(test["description"]).substitute({
 
338
            "output": job.data.strip()})
232
339
        self._set_hyper_text_view("hyper_text_view_test", description)
233
340
 
 
341
        self._set_active(STATUS_TO_BUTTON[job.status])
 
342
        self._set_label("button_test", _("_Test Again"))
234
343
        self._set_sensitive("button_test", True)
235
 
        self._set_label("button_test", _("_Test Again"))
236
344
 
237
345
    @GTKHack
238
 
    def show_test(self, test, result=None):
 
346
    def show_test(self, test):
239
347
        self._set_sensitive("button_test", False)
240
348
        self._notebook.set_current_page(2)
241
349
 
242
350
        # Set test description
243
 
        description = self.do_function(test.description, result)
244
 
        self._set_hyper_text_view("hyper_text_view_test", description)
 
351
        if re.search(r"\$output", test["description"]):
 
352
            self._run_test(test)
 
353
        else:
 
354
            self._set_hyper_text_view("hyper_text_view_test",
 
355
                test["description"])
245
356
 
246
357
        # Set buttons
247
 
        if str(test.command):
 
358
        if "command" in test:
248
359
            self._set_sensitive("button_test", True)
249
 
 
250
360
            button_test = self._get_widget("button_test")
251
361
            if self._handler_id:
252
362
                button_test.disconnect(self._handler_id)
253
363
            self._handler_id = button_test.connect("clicked",
254
364
                lambda w, t=test: self._run_test(t))
255
365
 
256
 
        # Default results
257
 
        answers = ["yes", "no", "skip"]
258
 
        if result:
259
 
            self._set_text_view("text_view_comment", result.data)
260
 
            answer = dict(zip(ALL_STATUS, answers))[result.status]
261
 
            self._set_active("radio_button_%s" % answer)
262
 
        else:
263
 
            self._set_text_view("text_view_comment")
264
 
            self._set_active("radio_button_skip")
 
366
        self._set_text_view("text_view_comment", test.get("data", ""))
 
367
        self._set_active(STATUS_TO_BUTTON[test.get("status", UNINITIATED)])
265
368
 
266
369
        self._run_dialog()
267
370
 
269
372
        self._set_hyper_text_view("hyper_text_view_test")
270
373
        self._set_label("button_test", _("_Test"))
271
374
 
272
 
        radio_buttons = ["radio_button_%s" % a for a in answers]
273
 
        status = self._get_radio_button(dict(zip(radio_buttons, ALL_STATUS)))
274
 
        data = self._get_text_view("text_view_comment")
275
 
        return TestResult(test, status, data)
276
 
 
277
 
    @GTKHack
278
 
    def show_exchange(self, authentication, message=None):
279
 
        self._notebook.set_current_page(3)
280
 
 
281
 
        if authentication is not None:
282
 
            self._set_text("entry_authentication", authentication)
283
 
 
284
 
        if message is not None:
285
 
            self._set_hyper_text_view("hyper_text_view_exchange", message)
286
 
 
287
 
        self._run_dialog()
288
 
 
289
 
        authentication = self._get_text("entry_authentication")
290
 
 
291
 
        return authentication
292
 
 
293
 
    @GTKHack
294
 
    def show_final(self, message=None):
295
 
        self._set_label("button_next", _("_Finish"))
296
 
        self._notebook.set_current_page(4)
297
 
 
298
 
        if message is not None:
299
 
            self._set_hyper_text_view("hyper_text_view_final", message)
300
 
 
301
 
        self._run_dialog()
302
 
 
303
 
        self._set_label("button_next", _("Ne_xt"))
304
 
 
305
 
    def show_error(self, title, text):
 
375
        test["data"] = self._get_text_view("text_view_comment")
 
376
        test["status"] = self._get_radio_button(BUTTON_TO_STATUS)
 
377
 
 
378
    def show_error(self, text):
306
379
        message_dialog = gtk.MessageDialog(parent=self._dialog,
307
380
            type=gtk.MESSAGE_ERROR,
308
 
            buttons=gtk.BUTTONS_CLOSE,
 
381
            buttons=gtk.BUTTONS_NONE,
309
382
            message_format=text)
310
383
        message_dialog.set_modal(True)
311
 
        message_dialog.set_title(title)
 
384
        message_dialog.set_title(_("Error"))
 
385
        message_dialog.set_default_response(1)
 
386
        message_dialog.add_buttons(gtk.STOCK_CLOSE, NEXT)
312
387
        self._run_dialog(message_dialog)
313
388
        message_dialog.hide()