~sylvain-pineau/checkbox/show_reports

« back to all changes in this revision

Viewing changes to checkbox_gtk/gtk_interface.py

  • Committer: Sylvain Pineau
  • Date: 2012-02-20 14:39:24 UTC
  • Revision ID: sylvain.pineau@canonical.com-20120220143924-ceg7lrnyzzco2dxu
Provide a test report screen for cli/urwid/gtk ui and a bug report for the gtk ui (to be used in conjunction with checkbox-oem).

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
from gettext import gettext as _
23
23
from string import Template
 
24
from operator import itemgetter
 
25
from contextlib import contextmanager
24
26
 
25
27
from gi.repository import Gtk, Gdk, Pango, PangoCairo
26
28
import cairo
109
111
        self._notebook = self._get_widget("notebook_main")
110
112
        self._handlers = {}
111
113
 
 
114
        # Set recorded bugs container
 
115
        self.bugs = dict()
 
116
 
112
117
    def _get_widget(self, name):
113
118
        return self.widgets.get_object(name)
114
119
 
116
121
        for radio_button, value in map.items():
117
122
            if self._get_widget(radio_button).get_active():
118
123
                return value
119
 
        raise Exception, "Failed to map radio_button."
 
124
        raise Exception("Failed to map radio_button.")
120
125
 
121
126
    def _get_label(self, name):
122
127
        widget = self._get_widget(name)
211
216
            title += " - %s" % test_name
212
217
        self._get_widget("dialog_main").set_title(title)
213
218
 
 
219
    @contextmanager
 
220
    def _add_temporary_buttons(self, buttons):
 
221
        """
 
222
        Add buttons to dialog
 
223
        and remove them after action is executed
 
224
        """
 
225
        action_area = self._dialog.get_action_area()
 
226
        for position, button in enumerate(buttons):
 
227
            action_area.pack_start(button, False, False, 0)
 
228
            action_area.reorder_child(button, position)
 
229
            button.show()
 
230
        yield
 
231
 
 
232
        for button in buttons:
 
233
            action_area.remove(button)
 
234
 
214
235
    def _run_dialog(self, dialog=None):
215
236
        def on_dialog_response(dialog, response, self):
216
237
            # Keep dialog alive when the button that has been clicked
557
578
            options.remove(default)
558
579
            options.append(default)
559
580
        for index, option in enumerate(options):
560
 
            message_dialog.add_button(option, index)
 
581
            button = getattr(Gtk, "STOCK_%s" % option.upper())
 
582
            message_dialog.add_buttons(button, index)
561
583
 
562
584
        self._run_dialog(message_dialog)
563
585
        message_dialog.hide()
602
624
        #Position to render text
603
625
        cairo_drawing_context.move_to(75,45)
604
626
        PangoCairo.show_layout(cairo_drawing_context,pango_text_layout)
 
627
 
 
628
    @GTKHack
 
629
    def show_report(self, text, results):
 
630
        """
 
631
        Display results report
 
632
        """
 
633
        # Set options page
 
634
        self._notebook.set_current_page(1)
 
635
 
 
636
        # Create treeview to display test cases results
 
637
        # in a tree hierarchy
 
638
        COLUMN_NAME, COLUMN_RESULT, RESULT_COLOR = range(3)
 
639
        treestore = Gtk.TreeStore(str, str, str)
 
640
        treeview = Gtk.TreeView()
 
641
        treeview.set_model(treestore)
 
642
        treeview.set_headers_visible(False)
 
643
        treeview.show()
 
644
 
 
645
        cell = Gtk.CellRendererText()
 
646
        col = Gtk.TreeViewColumn(None, cell, text=COLUMN_NAME)
 
647
        treeview.append_column(col)
 
648
 
 
649
        col = Gtk.TreeViewColumn(None, cell,
 
650
                                 text=COLUMN_RESULT,
 
651
                                 foreground=RESULT_COLOR)
 
652
        treeview.append_column(col)
 
653
 
 
654
        status_color_table = {'pass': 'green',
 
655
                              'fail': 'red',
 
656
                              }
 
657
 
 
658
        def set_results(results, parent=None):
 
659
            for name, data in sorted(results.iteritems(),
 
660
                                     key=itemgetter(0)):
 
661
                is_suite = all(issubclass(type(value), dict)
 
662
                               for value in data.itervalues())
 
663
 
 
664
                if is_suite:
 
665
                    iterator = treestore.append(parent, [name, '', None])
 
666
                    set_results(data, iterator)
 
667
                else:
 
668
                    status = data['status']
 
669
                    status_color = status_color_table.get(status)
 
670
                    treestore.append(parent, [name, status, status_color])
 
671
 
 
672
        set_results(results)
 
673
 
 
674
        vbox = self._get_widget("vbox_options_list")
 
675
        vbox.pack_start(treeview, False, False, 0)
 
676
 
 
677
        self._set_hyper_text_view("hyper_text_view_options", text)
 
678
 
 
679
        # Set extra buttons
 
680
        def create_button(label, callback):
 
681
            button = Gtk.Button(label)
 
682
            button.connect("clicked", callback)
 
683
            return button
 
684
 
 
685
        button_data = ((_("Expand All"),
 
686
                        lambda button: treeview.expand_all()),
 
687
                       (_("Collapse All"),
 
688
                        lambda button: treeview.collapse_all()),
 
689
                       )
 
690
        buttons = [create_button(label, callback)
 
691
                   for label, callback in button_data]
 
692
 
 
693
        with self._add_temporary_buttons(buttons):
 
694
            self._run_dialog()
 
695
 
 
696
        vbox.remove(treeview)
 
697
 
 
698
    @GTKHack
 
699
    def show_bugs(self, reactor, interface):
 
700
        """
 
701
        Display bug report
 
702
        """
 
703
        # Create a new page to handle the bug report
 
704
        vbox_additional_bugs = Gtk.VBox()
 
705
 
 
706
        frame1 = Gtk.Frame(label=None)
 
707
        frame1.set_shadow_type(Gtk.ShadowType.NONE)
 
708
        label1 = Gtk.Label("The following bugs have been recorded:")
 
709
        label1.set_alignment(0, 0)
 
710
        frame1.add(label1)
 
711
        vbox_additional_bugs.pack_start(frame1, False, False, 0)
 
712
        frame1.show()
 
713
        label1.show()
 
714
 
 
715
        sc1 = Gtk.ScrolledWindow()
 
716
        sc1.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS)
 
717
        sc1.show()
 
718
        vbox_additional_bugs.pack_start(sc1, True, True, 0)
 
719
 
 
720
        frame2 = Gtk.Frame(label=None)
 
721
        frame2.set_shadow_type(Gtk.ShadowType.NONE)
 
722
        label2 = Gtk.Label("Enter below additional bugs id you want"
 
723
                           " to link to this report then Refresh")
 
724
        label2.set_alignment(0, 0)
 
725
        frame2.add(label2)
 
726
        vbox_additional_bugs.pack_start(frame2, False, False, 0)
 
727
        frame2.show()
 
728
        label2.show()
 
729
 
 
730
        textview = Gtk.TextView()
 
731
        textview.show()
 
732
 
 
733
        sc2 = Gtk.ScrolledWindow()
 
734
        sc2.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS)
 
735
        sc2.show()
 
736
        sc2.add_with_viewport(textview)
 
737
        vbox_additional_bugs.pack_end(sc2, False, False, 0)
 
738
 
 
739
        vbox_additional_bugs.show()
 
740
 
 
741
        # Create a liststore with string columns
 
742
        liststore = Gtk.ListStore(str, str, str)
 
743
 
 
744
        # Create a view for the liststore
 
745
        listview = Gtk.TreeView()
 
746
        listview.set_model(liststore)
 
747
        listview.show()
 
748
 
 
749
        # Create CellRenderers to render Text cells
 
750
        cell1 = Gtk.CellRendererText()
 
751
        cell2 = Gtk.CellRendererText()
 
752
        cell3 = Gtk.CellRendererText()
 
753
 
 
754
        # Create columns
 
755
        tvcolumn1 = Gtk.TreeViewColumn('Id')
 
756
        tvcolumn2 = Gtk.TreeViewColumn('Headline')
 
757
        tvcolumn3 = Gtk.TreeViewColumn('Test')
 
758
 
 
759
        # Liststore update
 
760
        def liststore_update():
 
761
            liststore.clear()
 
762
            for id, data in self.bugs.iteritems():
 
763
                test_name_pattern = re.compile(
 
764
                    r'CheckboxTest:\s+(?P<test_name>.*?)\n')
 
765
                match = test_name_pattern.search(data['messages'])
 
766
                impacted_test = match.group('test_name') if match else ''
 
767
                liststore.append([id, data['title'], impacted_test])
 
768
 
 
769
        # Fill the liststore with recorded bugs
 
770
        liststore_update()
 
771
 
 
772
        # Add columns to the Treeview
 
773
        listview.append_column(tvcolumn1)
 
774
        listview.append_column(tvcolumn2)
 
775
        listview.append_column(tvcolumn3)
 
776
 
 
777
        tvcolumn1.pack_start(cell1, False)
 
778
        tvcolumn2.pack_start(cell2, False)
 
779
        tvcolumn3.pack_start(cell3, False)
 
780
        tvcolumn1.add_attribute(cell1, "text", 0)
 
781
        tvcolumn2.add_attribute(cell2, "text", 1)
 
782
        tvcolumn3.add_attribute(cell3, "text", 2)
 
783
 
 
784
        # Allow sorting for each column
 
785
        tvcolumn1.set_sort_column_id(0)
 
786
        tvcolumn2.set_sort_column_id(1)
 
787
        tvcolumn3.set_sort_column_id(2)
 
788
 
 
789
        sc1.add_with_viewport(listview)
 
790
        self._notebook.append_page(vbox_additional_bugs, None)
 
791
        self._notebook.set_current_page(4)
 
792
 
 
793
        # Set extra buttons
 
794
        def create_button(label, callback):
 
795
            button = Gtk.Button(label)
 
796
            button.connect("clicked", callback)
 
797
            return button
 
798
 
 
799
        # Callback to enter a new bug
 
800
        def new_bug():
 
801
            from checkbox_oem import bug
 
802
            factory = bug.GTKBugReportingAssistant
 
803
            assistant = factory()
 
804
            assistant.run()
 
805
            if hasattr(assistant, 'bug'):
 
806
                bug = assistant.bug
 
807
                reactor.fire("query-bugs", interface, [bug.id])
 
808
                liststore_update()
 
809
 
 
810
        # Callback to refresh the bug list
 
811
        def refresh_bug_list():
 
812
            textbuffer = textview.get_buffer()
 
813
            (start, end) = textbuffer.get_bounds()
 
814
            text = textbuffer.get_text(start, end, False)
 
815
            bug_pattern = re.compile(r'\b\d+\b')
 
816
            bugs_id = bug_pattern.findall(text)
 
817
            if bugs_id:
 
818
                reactor.fire("query-bugs", interface, bugs_id)
 
819
                liststore_update()
 
820
 
 
821
        button_data = ((_("New Bug"),
 
822
                        lambda button: new_bug()),
 
823
                       (_("Refresh"),
 
824
                        lambda button: refresh_bug_list()),
 
825
                       )
 
826
 
 
827
        buttons = [create_button(label, callback)
 
828
                   for label, callback in button_data]
 
829
 
 
830
        with self._add_temporary_buttons(buttons):
 
831
            self._run_dialog()