From 4383eaf83bba4fd021471dcfd751b7f98990854a Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Tue, 19 Jan 2010 14:37:49 +0100 Subject: GUI: redesign of reporter dialog --- src/Gui/CCReporterDialog.py | 226 ++++++++------- src/Gui/report.glade | 648 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 612 insertions(+), 262 deletions(-) (limited to 'src') diff --git a/src/Gui/CCReporterDialog.py b/src/Gui/CCReporterDialog.py index ab6ad0f..47cf908 100644 --- a/src/Gui/CCReporterDialog.py +++ b/src/Gui/CCReporterDialog.py @@ -36,10 +36,11 @@ class ReporterDialog(): self.report = report #Set the Glade file # FIXME add to path - self.gladefile = "%s%sreport.glade" % (sys.path[0],"/") - self.wTree = gtk.glade.XML(self.gladefile) + builderfile = "%s%sreport.glade" % (sys.path[0],"/") + self.builder = gtk.Builder() + self.builder.add_from_file(builderfile) #Get the Main Window, and connect the "destroy" event - self.window = self.wTree.get_widget("reporter_dialog") + self.window = self.builder.get_object("reporter_dialog") self.window.set_default_size(640, 480) self.window.connect("response", self.on_response, daemon) if parent: @@ -47,60 +48,89 @@ class ReporterDialog(): self.window.set_modal(True) # comment textview - self.tvComment = self.wTree.get_widget("tvComment") + self.tvComment = self.builder.get_object("tvComment") self.tvComment.connect("focus-in-event", self.on_comment_focus_cb) self.comment_changed = False # "how to reproduce" textview - self.tevHowToReproduce = self.wTree.get_widget("tevHowToReproduce") + self.tevHowToReproduce = self.builder.get_object("tevHowToReproduce") self.how_to_changed = False - self.tvReport = self.wTree.get_widget("tvReport") - - self.reportListStore = gtk.ListStore(str, str, bool, bool, bool) - # set filter - #self.modelfilter = self.reportListStore.filter_new() - #self.modelfilter.set_visible_func(self.filter_reports, None) - self.tvReport.set_model(self.reportListStore) - renderer = gtk.CellRendererText() - column = gtk.TreeViewColumn('Item', renderer, text=0) - self.tvReport.append_column(column) - - renderer = CellRenderers.MultilineCellRenderer() - renderer.props.editable = True - renderer.props.wrap_mode = pango.WRAP_WORD - renderer.props.wrap_width = 800 - - #renderer.props.wrap_mode = pango.WRAP_WORD - #renderer.props.wrap_width = 600 - column = gtk.TreeViewColumn('Value', renderer, text=1, editable=2) - self.tvReport.append_column(column) - renderer.connect('edited',self.column_edited,self.reportListStore) - # toggle - toggle_renderer = gtk.CellRendererToggle() - toggle_renderer.set_property('activatable', True) - toggle_renderer.connect( 'toggled', self.on_send_toggled, self.reportListStore ) - column = gtk.TreeViewColumn('Send', toggle_renderer) - column.add_attribute(toggle_renderer, "active", 3) - column.add_attribute(toggle_renderer, "visible", 4) - self.tvReport.insert_column(column,0) - # connect the signals - self.tvReport.connect_after("size-allocate", self.on_window_resize) - # start with the warning hidden, so it's not visible when there is no rating - self.wTree.get_widget("ebErrors").hide() - self.wTree.get_widget("bLog").connect("clicked", self.show_log_cb, log) + self.builder.get_object("ebErrors").hide() + self.builder.get_object("bLog").connect("clicked", self.show_log_cb, log) + self.builder.get_object("cbSendBacktrace").connect("toggled", self.on_send_backtrace_toggled) + self.allow_send() self.hydrate() - + + def check_backtrace(self): + print "checking backtrace" + + def warn_user(self, warnings): + # FIXME: show in lError + ebErrors = self.builder.get_object("ebErrors") + lErrors = self.builder.get_object("lErrors") + warning_lbl = None + for warning in warnings: + if warning_lbl: + warning_lbl += "\n* %s" % warning + else: + warning_lbl = "* %s" % warning + lErrors.set_label(warning_lbl) + ebErrors.show_all() + + def hide_warning(self): + ebErrors = self.builder.get_object("ebErrors") + lErrors = self.builder.get_object("lErrors") + ebErrors.hide() + + def allow_send(self): + self.hide_warning() + bSend = self.builder.get_object("bSend") + SendBacktrace = self.builder.get_object("cbSendBacktrace").get_active() + send = True + error_msgs = [] + try: + rating = self.report["rating"] + except: + rating = None + # active buttons acording to required fields + # if an backtrace has rating use it + if not SendBacktrace: + send = False + error_msgs.append(_("You must agree with submitting the backtrace.")) + # we have both SendBacktrace and rating + elif rating: + try: + package = self.report["package"][CD_CONTENT] + # if we don't have package for some reason + except: + package = None + # not usable report + if int(self.report["rating"][CD_CONTENT]) < 3: + if package: + error_msgs.append(_("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command: debuginfo-install %s \nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))])) + else: + error_msgs.append(_("The backtrace is unusable, you can't report this!")) + # probably usable 3 + elif int(self.report["rating"][CD_CONTENT]) < 4: + error_msgs.append(_("The backtrace is incomplete, please make sure you provide good steps to reproduce.")) + + if error_msgs: + self.warn_user(error_msgs) + bSend.set_sensitive(send) + + def on_send_backtrace_toggled(self, toggle_button): + self.allow_send() + def show_log_cb(self, widget, log): show_log(log, parent=self.window) # this callback is called when user press Cancel or Report button in Report dialog def on_response(self, dialog, response_id, daemon): # the button has been pressed (probably) - # print "response_id", response_id if response_id == gtk.RESPONSE_APPLY: if not (self.check_settings(daemon) and self.check_report()): dialog.stop_emission("response") - self.wTree.get_widget("bSend").stop_emission("clicked") + self.builder.get_object("bSend").stop_emission("clicked") if response_id == SHOW_LOG: # prevent dialog from quitting the run() dialog.stop_emission("response") @@ -113,16 +143,6 @@ class ReporterDialog(): widget.set_buffer(gtk.TextBuffer()) self.comment_changed = True - def on_window_resize(self, treeview, allocation): - # multine support - pass - #print allocation - - def column_edited(self, cell, path, new_text, model): - # 1 means the second cell - model[path][1] = new_text - return - def on_config_plugin_clicked(self, button, plugin, image): ui = PluginSettingsUI(plugin, parent=self.window) ui.hydrate() @@ -154,7 +174,6 @@ class ReporterDialog(): if reporter.Settings.check() == False: wrong_conf_plugs.append(reporter) - #gui_error_message(_("%s is not properly set!\nPlease check the settings and try to report again." % reporter)) if wrong_conf_plugs: gladefile = "%s%ssettings_wizard.glade" % (sys.path[0],"/") builder = gtk.Builder() @@ -187,8 +206,13 @@ class ReporterDialog(): def hydrate(self): self.editable = [] - self.reportListStore.clear() for item in self.report: + if item == "backtrace": + buff = gtk.TextBuffer() + tvBacktrace = self.builder.get_object("tvBacktrace") + buff.set_text(self.report[item][CD_CONTENT]) + tvBacktrace.set_buffer(buff) + continue if item == "Comment": buff = gtk.TextBuffer() comment = _("Brief description how to reproduce this or what you did...") @@ -217,60 +241,36 @@ class ReporterDialog(): self.tevHowToReproduce.set_buffer(buff) continue - # if an backtrace has rating use it - if item == "rating": - try: - package = self.report["package"][CD_CONTENT] - # if we don't have package for some reason - except: - package = None - ebErrors = self.wTree.get_widget("ebErrors") - fReproducer = self.wTree.get_widget("fReproducer") - fComments = self.wTree.get_widget("fComments") - lErrors = self.wTree.get_widget("lErrors") - bSend = self.wTree.get_widget("bSend") - # not usable report - if int(self.report[item][CD_CONTENT]) < 3: - ebErrors.show() - fReproducer.hide() - fComments.hide() - if package: - lErrors.set_markup( - _("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command: debuginfo-install %s \nthen use Refresh button to regenerate the backtrace." % package[0:package.rfind('-',0,package.rfind('-'))])) - else: - lErrors.set_markup(_("The backtrace is unusable, you can't report this!")) - bSend.set_sensitive(False) - # probably usable 3 - elif int(self.report[item][CD_CONTENT]) < 4: - ebErrors.show() - lErrors.set_markup(_("The backtrace is incomplete, please make sure you provide good steps to reproduce.")) - bSend.set_sensitive(True) - else: - ebErrors.hide() - fReproducer.show() - fComments.show() - bSend.set_sensitive(True) if self.report[item][CD_TYPE] != CD_SYS: # item name 0| value 1| editable? 2| toggled? 3| visible?(attachment)4 - if self.report[item][CD_EDITABLE] == 'y': - self.editable.append(item) - self.row_dict[item] = self.reportListStore.append([item, self.report[item][CD_CONTENT], - item in self.editable, True, - self.report[item][CD_TYPE] in [CD_ATT,CD_BIN]]) + # FIXME: handle editable fields + if self.report[item][CD_TYPE] in [CD_ATT,CD_BIN]: + self.builder.get_object("fAttachment").show() + vbAttachments = self.builder.get_object("vbAttachments") + toggle = gtk.CheckButton(self.report[item][CD_CONTENT]) + vbAttachments.pack_start(toggle) + # bind item to checkbox + toggle.item = item + toggle.show() + continue + item_label = self.builder.get_object("l%s" % item) + if item_label: + item_label.set_text(self.report[item][CD_CONTENT]) + else: + # no widget to show this item + # probably some new item need to adjust the GUI! + # FIXME: add some window+button to show all the info + # in raw form (smth like the old report dialog) + pass def dehydrate(self): - attributes = ["item", "content", "editable", "send", "attachment"] - for row in self.reportListStore: - rowe = dict(zip(attributes, row)) - if not rowe["editable"] and not rowe["attachment"]: - self.report[rowe["item"]][CD_CONTENT] = rowe["content"] - elif rowe["editable"] and not rowe["attachment"]: - self.report[rowe["item"]][CD_CONTENT] = rowe["content"] - elif (rowe["attachment"] or (rowe["editable"] and rowe["attachment"])) and rowe["send"]: - self.report[rowe["item"]][CD_CONTENT] = rowe["content"] - else: - del self.report[rowe["item"]] + # handle attachments + vbAttachments = self.builder.get_object("vbAttachments") + for attachment in vbAttachments.get_children(): + #print "%s file %s" % (["not sending","sending"][attachment.get_active()], attachment.get_label()) + del self.report[attachment.item] + # handle comment if self.comment_changed: buff = self.tvComment.get_buffer() @@ -283,22 +283,14 @@ class ReporterDialog(): self.report["How to reproduce"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] else: del self.report["How to reproduce"] + #handle backtrace + tev_backtrace = self.builder.get_object("tvBacktrace") + buff = tev_backtrace.get_buffer() + self.report["backtrace"] = [CD_TXT, 'y', buff.get_text(buff.get_start_iter(),buff.get_end_iter())] def check_report(self): - # FIXME: what to do if user press "Not to send BT and then press cancel" - # it uncheck the backtrace and let him to edit it, and then user might - # not noticed, that he is not sending the BT, so should we warn user about this - # or check the BT automatically? - attributes = ["item", "content", "editable", "send", "attachment"] - for row in self.reportListStore: - rowe = dict(zip(attributes, row)) - if (rowe["attachment"] or (rowe["editable"] and rowe["attachment"])) and rowe["send"]: - result = gui_question_dialog(_("WARNING, you're about to send data which might contain sensitive information.\n" - "Do you really want to send %s?\n" % rowe["item"]), self.window) - if result == gtk.RESPONSE_NO: - row[attributes.index("send")] = False - if result in (gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT): - return False + # FIXME: check the report for passwords and some other potentially + # sensitive info self.dehydrate() return True diff --git a/src/Gui/report.glade b/src/Gui/report.glade index 0eae1f1..d3bf5eb 100644 --- a/src/Gui/report.glade +++ b/src/Gui/report.glade @@ -1,225 +1,580 @@ - - - - - 6 - Report - True - center-on-parent - 400 - 400 + + + + + 5 + Automatic Bug Reporting Tool normal False - + True vertical - 12 + 2 - + True vertical - 12 - + True - vertical - 12 + 0 + none - + True - 0 - none + 12 - + True - 12 - + True - True - automatic - automatic - in + vertical - + True - True - + 0 + <span fgcolor="blue">Package:</span> + True + + + 0 + + + + + True + 0 + <span fgcolor="blue">Component:</span> + True + + + 1 + + + + + True + 0 + <span fgcolor="blue">Executable:</span> + True + + + 2 + - + + + True + 0 + <span fgcolor="blue">Cmdline:</span> + True + + + 3 + + + + + 0 + - - - - - True - <b>Following items will be sent</b> - True - - - label_item - + + + True + vertical + True + + + True + 0 + 5 + N/A + + + 0 + + + + + True + 0 + 5 + N/A + + + 1 + + + + + True + 0 + 5 + N/A + + + 2 + + + + + True + 0 + 5 + N/A + + + 3 + + + + + 1 + + + + + True + vertical + + + True + 0 + <span fgcolor="blue">Architecture:</span> + True + + + 0 + + + + + True + 0 + <span fgcolor="blue">Kernel:</span> + True + + + 1 + + + + + True + 0 + <span fgcolor="blue">Release:</span> + True + + + 2 + + + + + True + 0 + <span fgcolor="blue">Reason:</span> + True + + + 3 + + + + + 2 + + + + + True + vertical + + + True + 0 + 5 + N/A + + + 0 + + + + + True + 0 + 5 + N/A + + + 1 + + + + + True + 0 + 5 + N/A + + + 2 + + + + + True + 0 + 5 + N/A + + + 3 + + + + + 3 + + + - - - 0 - + + + + True + 5 + <b>General information</b> + True + + + + + False + False + 0 + + + + + True + 0 + none - + True - 0 - none + 12 - + True - 12 + vertical - + True True automatic automatic - + + 200 True - queue - - - True - True - word-char - - - + True + - + + + 0 + - - - - - True - <b>How to reproduce (in a few simple steps)</b> - True - - - label_item - + + + I agree to submit this backtrace, which could contain sensitive data + True + True + False + True + + + False + 1 + + + - - - False - False - 1 - + + + + True + 5 + <b>Backtrace</b> + True + + + + + 1 + + + + + True + 0 + none - + True - 0 - none + 12 - + True - 12 + vertical + 12 - + True - True - automatic - automatic + vertical + 12 + + + True + 0 + none + + + True + 12 + + + True + True + automatic + automatic + + + True + queue + + + True + True + word-char + + + + + + + + + + + True + <b>How to reproduce (in a few simple steps)</b> + True + + + + + False + False + 0 + + - + True - queue + 0 + none - + True - True - word-char - + 12 + + + True + True + automatic + automatic + + + True + queue + + + True + True + word-char + + + + + + + - + + + True + <b>Comment</b> + True + + + + + False + False + 1 + - + + + 0 + - + + + + + + True + 5 + <b>User information</b> + True + + + + + 2 + + + + + 0 + none + + + True + 12 - + True - <b>Comment</b> - True - - - label_item - + vertical + + + + - - - False - False - 2 - + + + + + True + <b>Attachments</b> + True + - + - 0 + 3 - + True - 12 - + + True + + + + + + 0 + + + + True gtk-dialog-warning 6 - + False False - 0 + 1 - + True - - True - + vertical + + + True + <b>Please fix the following problems</b> + True + + + 0 + + + + + True + + True + True + + + 1 + + + - 1 + 2 + + + + + True + + + + + + 3 - + False False - 1 + 4 - + - 0 + 1 - + True end - + Log - -60 True True True - + False False @@ -227,14 +582,13 @@ - + gtk-cancel - -6 True True True True - + False False @@ -242,14 +596,13 @@ - + gtk-refresh - -50 True True True True - + False False @@ -257,27 +610,32 @@ - + Send - -10 True True True - + False False 3 - + False end - 1 + 0 - + - - + + bLog + bCancel + bRefresh + bSend + + + -- cgit