>From 3e77c034f7ef07e0b91f454d2b6c9451532f9a67 Mon Sep 17 00:00:00 2001
From: Jiri Moskovcak <jmoskovc@redhat.com>
Date: Wed, 26 May 2010 13:47:09 +0200
Subject: [PATCH] GUI: enabled the new wizard style

---
 src/Gui/CCDBusBackend.py      |    6 +-
 src/Gui/CCDump.py             |   16 ++
 src/Gui/CCMainWindow.py       |   15 ++-
 src/Gui/CReporterAssistant.py |  390 ++++++++++++++++++++++++++++++++++-------
 src/Gui/Makefile.am           |    3 +-
 src/Gui/progress_window.glade |    1 -
 6 files changed, 354 insertions(+), 77 deletions(-)

diff --git a/src/Gui/CCDBusBackend.py b/src/Gui/CCDBusBackend.py
index 1122f05..75ebdd5 100644
--- a/src/Gui/CCDBusBackend.py
+++ b/src/Gui/CCDBusBackend.py
@@ -166,9 +166,9 @@ class DBusManager(gobject.GObject):
 
     def jobdone_cb(self):
         log1("Our job for crash_id %s is done", self.job_crash_id)
-        dump = self.daemon().CreateReport(self.job_crash_id)
-        if dump:
-            self.emit("analyze-complete", dump)
+        report = self.daemon().CreateReport(self.job_crash_id)
+        if report:
+            self.emit("analyze-complete", report)
         else:
             # FIXME: BUG: BarWindow remains. (how2reproduce: delete "component" in a dump dir and try to report it)
             self.emit("abrt-error", _("Daemon didn't return valid report info\nDebuginfo is missing?"))
diff --git a/src/Gui/CCDump.py b/src/Gui/CCDump.py
index 913e40a..23535bf 100644
--- a/src/Gui/CCDump.py
+++ b/src/Gui/CCDump.py
@@ -62,6 +62,9 @@ class Dump():
         else:
             self.__dict__[name] = value
 
+    def __str__(self):
+        return "Dump instance"
+
     def getUUID(self):
         return self.UUID
 
@@ -129,3 +132,16 @@ class Dump():
 
     def get_kernel(self):
         return self.kernel
+
+    def get_backtrace(self):
+        try:
+            return self.backtrace
+        except KeyError:
+            return None
+
+    def get_rating(self):
+        try:
+            return self.rating
+        except KeyError:
+            return None
+
diff --git a/src/Gui/CCMainWindow.py b/src/Gui/CCMainWindow.py
index 16314bb..658fdca 100644
--- a/src/Gui/CCMainWindow.py
+++ b/src/Gui/CCMainWindow.py
@@ -22,6 +22,7 @@ from CC_gui_functions import *
 from CCDumpList import getDumpList
 from CCDump import *   # FILENAME_xxx, CD_xxx
 from CCReporterDialog import ReporterDialog, ReporterSelector
+from CReporterAssistant import ReporterAssistant
 from PluginsSettingsDialog import PluginsSettingsDialog
 from SettingsDialog import SettingsDialog
 from PluginList import getPluginInfoList
@@ -371,8 +372,11 @@ class MainWindow():
             return
         dump = dumpsListStore.get_value(dumpsListStore.get_iter(path[0]), dumpsListStore.get_n_columns()-1)
 
-        rs = ReporterSelector(dump, self.ccdaemon, parent=self.window)
-        rs.show()
+        # Do we want to let user decide which UI they want to use?
+        #rs = ReporterSelector(dump, self.ccdaemon, parent=self.window)
+        #rs.show()
+        assistant = ReporterAssistant(dump, self.ccdaemon, parent=self.window)
+        assistant.hydrate()
 
     def delete_event_cb(self, widget, event, data=None):
         gtk.main_quit()
@@ -437,8 +441,11 @@ if __name__ == "__main__":
             gui_error_message(_("No such crash in database, probably wrong crashid."
                                 "\ncrashid=%s" % crashid))
             sys.exit()
-        rs = ReporterSelector(crashdump, daemon, parent=None)
-        rs.show()
+        assistant = ReporterAssistant(crashdump, daemon, parent=None)
+        assistant.hydrate()
+        # Do we want to let the users to decide which UI to use?
+#        rs = ReporterSelector(crashdump, daemon, parent=None)
+#        rs.show()
     else:
         cc = MainWindow(daemon)
         cc.hydrate()
diff --git a/src/Gui/CReporterAssistant.py b/src/Gui/CReporterAssistant.py
index e457ef2..f77fe38 100644
--- a/src/Gui/CReporterAssistant.py
+++ b/src/Gui/CReporterAssistant.py
@@ -2,6 +2,7 @@ import gtk
 from PluginList import getPluginInfoList
 from abrt_utils import _, log, log1, log2, get_verbose_level, g_verbose, warn
 from CCDump import *   # FILENAME_xxx, CD_xxx
+from PluginSettingsUI import PluginSettingsUI
 import sys
 import gobject
 from CC_gui_functions import *
@@ -12,18 +13,21 @@ PAGE_BACKTRACE_APPROVAL = 1
 PAGE_EXTRA_INFO = 2
 PAGE_CONFIRM = 3
 PAGE_REPORT_DONE = 4
+NO_PROBLEMS_DETECTED = -50
 HOW_TO_HINT_TEXT = "1.\n2.\n3.\n"
+COMMENT_HINT_TEXT = _("Brief description how to reproduce this or what you did...")
 
 class ReporterAssistant():
-    def __init__(self, dump, daemon, log=None, parent=None):
-        self.report = None
+    def __init__(self, report, daemon, log=None, parent=None):
         self.connected_signals = []
         self.plugins_cb = []
         self.daemon = daemon
         self.updates = ""
         self.pdict = {}
-        self.dump = dump
+        self.report = report
         self.parent = parent
+        self.show_hint_comment = False
+        self.selected_reporters = []
         """ create the assistant """
         self.assistant = gtk.Assistant()
         self.assistant.set_icon_name("abrt")
@@ -35,13 +39,15 @@ class ReporterAssistant():
         if parent:
             self.assistant.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
             self.assistant.set_transient_for(parent)
+        else:
+            # if we don't have parent we want to quit the mainloop on close
+            self.assistant.set_position(gtk.WIN_POS_CENTER)
 
         ### progress bar window
         self.builder = gtk.Builder()
         builderfile = "%s/progress_window.glade" % sys.path[0]
         self.builder.add_from_file(builderfile)
         self.pBarWindow = self.builder.get_object("pBarWindow")
-        print self.pBarWindow
         if self.pBarWindow:
             self.connect_signal(self.pBarWindow, "delete_event", self.sw_delete_event_cb)
             if parent:
@@ -61,20 +67,48 @@ class ReporterAssistant():
         self.pBar.pulse()
         return True
 
+    def on_show_bt_clicked(self, button):
+        viewer = gtk.Window()
+        viewer.set_icon_name("abrt")
+        viewer.set_default_size(600,500)
+        viewer.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+        viewer.set_transient_for(self.assistant)
+        hbox = gtk.HBox()
+        viewer.add(hbox)
+        bt_tev = gtk.TextView()
+        backtrace_scroll_w = gtk.ScrolledWindow()
+        backtrace_scroll_w.add(bt_tev)
+        backtrace_scroll_w.set_policy(gtk.POLICY_AUTOMATIC,
+                                      gtk.POLICY_AUTOMATIC)
+        bt_tev.set_buffer(self.backtrace_buff)
+        hbox.pack_start(backtrace_scroll_w)
+        viewer.show_all()
+
     def on_report_done_cb(self, daemon, result):
-        try:
-            gobject.source_remove(self.timer)
-        except:
-            pass
-        self.pBarWindow.hide()
-        gui_report_dialog(result, self.parent)
+        self.hide_progress()
+        STATUS = 0
+        MESSAGE = 1
+        # 0 means not succesfull
+        #if report_status_dict[plugin][STATUS] == '0':
+        # this first one is actually a fallback to set at least
+        # a raw text in case when set_markup() fails
+        for plugin, res in result.iteritems():
+            self.bug_reports.set_text(result[plugin][MESSAGE])
+            self.bug_reports.set_markup("<span foreground='red'>%s</span>" % markup_escape_text(result[plugin][MESSAGE]))
+            # if the report was not succesful then this won't pass so this runs only
+            # if report succeds and gets overwriten by the status message
+            if result[plugin][STATUS] == '1':
+                self.bug_reports.set_markup(tag_urls_in_text(result[plugin][MESSAGE]))
+
+            #if len(result[plugin][1]) > MAX_WIDTH:
+            #    self.bug_reports.set_tooltip_text(result[plugin][1])
+            #gui_report_dialog(result, self.parent)
 
     def cleanup_and_exit(self):
-        if not self.parent.get_property("visible"):
-            self.disconnect_signals()
-            # if the reporter selector doesn't have a parent
-            if not self.parent.get_transient_for():
-                gtk.main_quit()
+        self.disconnect_signals()
+        self.assistant.destroy()
+        if not self.parent:
+            gtk.main_quit()
 
     def update_cb(self, daemon, message):
         self.updates += message
@@ -113,43 +147,228 @@ class ReporterAssistant():
             obj.disconnect(signal_id)
 
     def on_cancel_clicked(self, assistant, user_data=None):
-        self.disconnect_signals()
-        self.assistant.destroy()
+        self.cleanup_and_exit()
 
     def on_close_clicked(self, assistant, user_data=None):
-        self.disconnect_signals()
-        self.assistant.destroy()
+        self.cleanup_and_exit()
 
     def on_apply_clicked(self, assistant, user_data=None):
-        self.dehydrate()
+        self.send_report(self.result)
+
+    def hide_progress(self):
+        try:
+            gobject.source_remove(self.timer)
+        except:
+            pass
+        self.pBarWindow.hide()
+
+    def on_config_plugin_clicked(self, button, parent, plugin, image):
+        ui = PluginSettingsUI(plugin, parent=parent)
+        ui.hydrate()
+        response = ui.run()
+        if response == gtk.RESPONSE_APPLY:
+            ui.dehydrate()
+            if plugin.Settings.check():
+                try:
+                    plugin.save_settings_on_client_side()
+                except Exception, e:
+                    gui_error_message(_("Can't save plugin settings:\n %s" % e))
+                box = image.get_parent()
+                im = gtk.Image()
+                im.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_MENU)
+                box.remove(image)
+                box.pack_start(im, expand = False, fill = False)
+                im.show()
+                image.destroy()
+                button.set_sensitive(False)
+        elif response == gtk.RESPONSE_CANCEL:
+            log1("cancel")
+        ui.destroy()
+
+    def check_settings(self, reporters):
+        wrong_conf_plugs = []
+        for reporter in reporters:
+            if reporter.Settings.check() == False:
+                wrong_conf_plugs.append(reporter)
+
+        if wrong_conf_plugs:
+            gladefile = "%s%ssettings_wizard.glade" % (sys.path[0],"/")
+            builder = gtk.Builder()
+            builder.add_from_file(gladefile)
+            dialog = builder.get_object("WrongSettings")
+            vbWrongSettings = builder.get_object("vbWrongSettings")
+            for plugin in wrong_conf_plugs:
+                hbox = gtk.HBox()
+                hbox.set_spacing(6)
+                image = gtk.Image()
+                image.set_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_MENU)
+                button = gtk.Button(_("Configure %s options" % plugin.getName()))
+                button.connect("clicked", self.on_config_plugin_clicked, dialog, plugin, image)
+                hbox.pack_start(button)
+                hbox.pack_start(image, expand = False, fill = False)
+                vbWrongSettings.pack_start(hbox)
+            vbWrongSettings.show_all()
+            dialog.set_transient_for(self.assistant)
+            dialog.set_modal(True)
+            response = dialog.run()
+            dialog.destroy()
+            if response == gtk.RESPONSE_YES:
+                return True
+            else:
+                # user cancelled reporting
+                return False
+
+        else:
+            return NO_PROBLEMS_DETECTED
+    def warn_user(self, warnings):
+        # FIXME: show in lError
+        #self.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
+        # fallback
+        self.lbl_errors.set_label(warning_lbl)
+        self.lbl_errors.set_markup(warning_lbl)
+        self.errors_hbox.show_all()
+        #fErrors.show_all()
+
+    def hide_warning(self):
+        self.errors_hbox.hide()
+
+    def allow_send(self, send_toggle):
+        self.hide_warning()
+        #bSend = self.builder.get_object("bSend")
+        SendBacktrace = send_toggle.get_active()
+        send = True
+        error_msgs = []
+        try:
+            rating = int(self.report.get_rating())
+        except Exception,ex:
+            print ex
+            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 check backtrace for sensitive data"))
+        # we have both SendBacktrace and rating
+        if rating != None:
+            try:
+                package = self.result[FILENAME_PACKAGE][CD_CONTENT]
+            # if we don't have package for some reason
+            except:
+                package = None
+            # not usable report
+            if int(self.result[FILENAME_RATING][CD_CONTENT]) < 3:
+                if package:
+                    error_msgs.append(_("Reporting disabled because the backtrace is unusable.\nPlease try to install debuginfo manually using command: <b>debuginfo-install %s</b> \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!"))
+                send = False
+            # probably usable 3
+            elif int(self.result[FILENAME_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)
+        self.assistant.set_page_complete(self.pdict_get_page(PAGE_BACKTRACE_APPROVAL), send)
+        #self.assistant.set_page_complete(page, togglebutton.get_active())
+        #if not send:
+        #    bSend.set_tooltip_text(_("Reporting disabled, please fix the problems shown above."))
+        #else:
+        #    bSend.set_tooltip_text(_("Sends the report using selected plugin."))
 
     def on_page_prepare(self, assistant, page):
+        # this is where dehydrate happens
+        if page == self.pdict_get_page(PAGE_EXTRA_INFO):
+            # howto
+            buff = gtk.TextBuffer()
+            try:
+                buff.set_text(self.result[FILENAME_REPRODUCE][CD_CONTENT])
+            except KeyError:
+                buff.set_text(HOW_TO_HINT_TEXT)
+            self.howto_tev.set_buffer(buff)
+
+            # comment
+            buff = gtk.TextBuffer()
+            try:
+                buff.set_text(self.result[FILENAME_COMMENT][CD_CONTENT])
+            except KeyError:
+                buff.set_text(COMMENT_HINT_TEXT)
+                self.show_hint_comment = True
+            self.comment_tev.set_buffer(buff)
         if page == self.pdict_get_page(PAGE_CONFIRM):
-            #backtrace_buff = self.backtrace_tev.get_buffer()
-            #backtrace_text = backtrace_buff.get_text(backtrace_buff.get_start_iter(), backtrace_buff.get_end_iter())
+            # howto
             howto_buff = self.howto_tev.get_buffer()
             howto_text = howto_buff.get_text(howto_buff.get_start_iter(), howto_buff.get_end_iter())
-            self.steps.set_text(howto_text)
+
+            if howto_text != HOW_TO_HINT_TEXT:
+                # user has changed the steps to reproduce
+                self.steps.set_text(howto_text)
+                self.result[FILENAME_REPRODUCE] = [CD_TXT, 'y', howto_text]
+            else:
+                self.steps.set_text(_("You didn't provide any steps to reproduce."))
+            #comment
             comment_buff = self.comment_tev.get_buffer()
             comment_text = comment_buff.get_text(comment_buff.get_start_iter(), comment_buff.get_end_iter())
-            self.comments.set_text(comment_text)
-        #elif page == self.pdict_get_page(PAGE_BACKTRACE_APPROVAL):
-        #    self.backtrace_buff.set_text(self.report[FILENAME_BACKTRACE][CD_CONTENT])
+            if not self.show_hint_comment:
+                self.comments.set_text(comment_text)
+                self.result[FILENAME_COMMENT] = [CD_TXT, 'y', comment_text]
+            else:
+                self.comments.set_text(_("You didn't provide any comments."))
+            # backtrace
+            backtrace_text = self.backtrace_buff.get_text(self.backtrace_buff.get_start_iter(), self.backtrace_buff.get_end_iter())
+            self.result[FILENAME_REPRODUCE] = [CD_TXT, 'y', backtrace_text]
+
+        if page == self.pdict_get_page(PAGE_BACKTRACE_APPROVAL):
+            self.allow_send(self.backtrace_cb)
+
+    def send_report(self, report):
+        try:
+            self.pBarWindow.show_all()
+            self.timer = gobject.timeout_add(100, self.progress_update_cb)
+            pluginlist = getPluginInfoList(self.daemon)
+            reporters_settings = pluginlist.getReporterPluginsSettings()
+            log2("Report(report, reporters, settings):")
+            log2("  result:%s", str(report))
+            # Careful, this will print reporters_settings["Password"] too
+            log2("  settings:%s", str(reporters_settings))
+            self.daemon.Report(report, self.selected_reporters, reporters_settings)
+            log2("Report() returned")
+            #self.hydrate()
+        except Exception, ex:
+            self.hide_progress()
+            gui_error_message(_("Reporting failed!\n%s" % ex))
 
-    def on_plugin_toggled(self, togglebutton, plugins, page):
+    def on_plugin_toggled(self, plugin, plugins, reporter, page):
         complete = False
-        for plugin in plugins:
-            if plugin.get_active() is True:
-                complete = True
-                break
+        if plugin.get_active():
+            log1("Plugin >>%s<< activated" % reporter)
+            self.selected_reporters.append(reporter)
+            check_result = self.check_settings([reporter])
+            if check_result == NO_PROBLEMS_DETECTED:
+                pass
+            elif check_result:
+                page_n = self.assistant.get_current_page()
+                self.assistant.set_page_complete(page, True)
+                self.assistant.set_current_page(page_n+1)
+        else:
+            self.selected_reporters.remove(reporter)
+            log1("Plugin >>%s<< de-activated" % reporter)
+        if self.selected_reporters:
+            complete = True
+        log1("Selected reporters: %s" % [str(x) for x in self.selected_reporters])
         self.assistant.set_page_complete(page, complete)
 
     def on_bt_toggled(self, togglebutton, page):
-        self.assistant.set_page_complete(page, togglebutton.get_active())
+        self.allow_send(togglebutton)
 
     def pdict_add_page(self, page, name):
         # FIXME try, except??
-        print "adding %s" % name
         if name not in self.pdict:
             self.pdict[name] = page
         else:
@@ -185,7 +404,7 @@ class ReporterAssistant():
                                     "you'd rather not share\n\n"
                                     "Select where you would like to report the "
                                     "bug, and press 'Forward' to continue.")
-                                    % self.dump.getPackageName())
+                                    % self.report.getPackageName())
         page.pack_start(lbl_default_info, expand=True, fill=True)
         vbox_plugins = gtk.VBox()
         page.pack_start(vbox_plugins)
@@ -198,17 +417,28 @@ class ReporterAssistant():
         self.reporters = []
         AnalyzerActionsAndReporters = self.settings["AnalyzerActionsAndReporters"]
         try:
-            reporters = AnalyzerActionsAndReporters[self.dump.getAnalyzerName()]
+            reporters = None
+            try:
+                reporters = AnalyzerActionsAndReporters[self.report.getAnalyzerName()+":"+self.report.getPackageName()]
+                log1("Found per-package reporters, "
+                     "using it instead of the common reporter")
+            except KeyError:
+                pass
+            # the package specific reporter has higher priority,
+            # so don't overwrite it if it's set
+            if not reporters:
+                reporters = AnalyzerActionsAndReporters[self.report.getAnalyzerName()]
             for reporter_name in reporters.split(','):
                 reporter = pluginlist.getReporterByName(reporter_name)
                 if reporter:
                     self.reporters.append(reporter)
         except KeyError:
             # Analyzer has no associated reporters.
+            # but we don't care, maybe user just want to read the backtrace??
             pass
         for reporter in self.reporters:
             cb = gtk.CheckButton(str(reporter))
-            cb.connect("toggled", self.on_plugin_toggled, plugins_cb, page)
+            cb.connect("toggled", self.on_plugin_toggled, plugins_cb, reporter, page)
             plugins_cb.append(cb)
             vbox_plugins.pack_start(cb, fill=True, expand=False)
         self.assistant.insert_page(page, PAGE_REPORTER_SELECTOR)
@@ -217,6 +447,18 @@ class ReporterAssistant():
         self.assistant.set_page_title(page, _("Send a bug report"))
         page.show_all()
 
+    def on_bt_copy(self, button, bt_text_view):
+        buff = bt_text_view.get_buffer()
+        bt_text = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
+        clipboard = gtk.clipboard_get()
+        clipboard.set_text(bt_text)
+
+    def on_comment_focus_cb(self, widget, event):
+        if self.show_hint_comment:
+            # clear "hint" text by supplying a fresh, empty TextBuffer
+            widget.set_buffer(gtk.TextBuffer())
+            self.show_hint_comment = True
+
     def prepare_page_2(self):
         page = gtk.VBox(spacing=10)
         page.set_border_width(10)
@@ -249,24 +491,39 @@ class ReporterAssistant():
         hbox_bt.pack_start(vbox_bt)
         backtrace_alignment = gtk.Alignment()
         hbox_bt.pack_start(backtrace_alignment, expand=False, padding=10)
+        # bad backtrace, reporting disabled
         vbox_bt.pack_start(backtrace_scroll_w)
+        # warnings about wrong bt
+        self.errors_hbox = gtk.HBox()
+        self.warning_image = gtk.Image()
+        self.warning_image.set_from_stock(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_DIALOG)
+        self.lbl_errors = gtk.Label()
+        self.lbl_errors.set_line_wrap(True)
+        #self.lbl_errors.set_alignment(0.0, 0.0)
+        self.lbl_errors.set_justify(gtk.JUSTIFY_FILL)
+        self.lbl_errors.set_size_request(600, -1)
+        self.errors_hbox.pack_start(self.warning_image, False, False)
+        self.errors_hbox.pack_start(self.lbl_errors)
+        ###
+        vbox_bt.pack_start(self.errors_hbox, False, False)
         hbox_buttons = gtk.HBox(homogeneous=True)
         button_alignment = gtk.Alignment()
         b_refresh = gtk.Button(_("Refresh"))
         b_refresh.connect("clicked", self.hydrate, 1)
         b_copy = gtk.Button(_("Copy"))
+        b_copy.connect("clicked", self.on_bt_copy, self.backtrace_tev)
         hbox_buttons.pack_start(button_alignment)
         hbox_buttons.pack_start(b_refresh, expand=False, fill=True)
         hbox_buttons.pack_start(b_copy, expand=False, fill=True)
         vbox_bt.pack_start(hbox_buttons, expand=False, fill=False)
-        backtrace_cb = gtk.CheckButton(_("I agree with submitting the backtrace"))
-        backtrace_cb.connect("toggled", self.on_bt_toggled, page)
+        self.backtrace_cb = gtk.CheckButton(_("I agree with submitting the backtrace"))
+        self.backtrace_cb.connect("toggled", self.on_bt_toggled, page)
         self.assistant.insert_page(page, PAGE_BACKTRACE_APPROVAL)
         self.pdict_add_page(page, PAGE_BACKTRACE_APPROVAL)
         self.assistant.set_page_type(page, gtk.ASSISTANT_PAGE_CONTENT)
         self.assistant.set_page_title(page, _("Approve backtrace"))
         page.pack_start(hbox_bt)
-        page.pack_start(backtrace_cb, expand=False, fill=False)
+        page.pack_start(self.backtrace_cb, expand=False, fill=False)
         page.show_all()
 
     def prepare_page_3(self):
@@ -308,6 +565,7 @@ class ReporterAssistant():
         comment_lbl.set_alignment(0.0, 0.0)
         comment_lbl.set_justify(gtk.JUSTIFY_FILL)
         self.comment_tev = gtk.TextView()
+        self.comment_tev.connect("focus-in-event", self.on_comment_focus_cb)
         comment_scroll_w = gtk.ScrolledWindow()
         comment_scroll_w.add(self.comment_tev)
         comment_scroll_w.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
@@ -381,15 +639,15 @@ class ReporterAssistant():
         summary_table_left = gtk.Table(rows=4, columns=2)
         summary_table_right = gtk.Table(rows=4, columns=2)
         # left table
-        add_info_to_table(summary_table_left, _("Component"), "%s" % self.dump.get_component())
-        add_info_to_table(summary_table_left, _("Package"), "%s" % self.dump.getPackageName())
-        add_info_to_table(summary_table_left, _("Executable"), "%s" % self.dump.getExecutable())
-        add_info_to_table(summary_table_left, _("Cmdline"), "%s" % self.dump.get_cmdline())
+        add_info_to_table(summary_table_left, _("Component"), "%s" % self.report.get_component())
+        add_info_to_table(summary_table_left, _("Package"), "%s" % self.report.getPackageName())
+        add_info_to_table(summary_table_left, _("Executable"), "%s" % self.report.getExecutable())
+        add_info_to_table(summary_table_left, _("Cmdline"), "%s" % self.report.get_cmdline())
         #right table
-        add_info_to_table(summary_table_right, _("Architecture"), "%s" % self.dump.get_arch())
-        add_info_to_table(summary_table_right, _("Kernel"), "%s" % self.dump.get_kernel())
-        add_info_to_table(summary_table_right, _("Release"),"%s" % self.dump.get_release())
-        add_info_to_table(summary_table_right, _("Reason"), "%s" % self.dump.get_reason())
+        add_info_to_table(summary_table_right, _("Architecture"), "%s" % self.report.get_arch())
+        add_info_to_table(summary_table_right, _("Kernel"), "%s" % self.report.get_kernel())
+        add_info_to_table(summary_table_right, _("Release"),"%s" % self.report.get_release())
+        add_info_to_table(summary_table_right, _("Reason"), "%s" % self.report.get_reason())
 
         summary_hbox = gtk.HBox(spacing=5, homogeneous=True)
         left_table_vbox = gtk.VBox()
@@ -404,6 +662,7 @@ class ReporterAssistant():
         backtrace_lbl.set_alignment(0.0, 0.5)
         backtrace_lbl.set_justify(gtk.JUSTIFY_LEFT)
         backtrace_show_btn = gtk.Button(_("Click to view ..."))
+        backtrace_show_btn.connect("clicked", self.on_show_bt_clicked)
         backtrace_hbox = gtk.HBox(homogeneous=True)
         hb = gtk.HBox()
         hb.pack_start(backtrace_lbl)
@@ -435,7 +694,7 @@ class ReporterAssistant():
         comments_lbl.set_markup(_("<b>Comments:</b>"))
         comments_lbl.set_alignment(0.0, 0.0)
         comments_lbl.set_justify(gtk.JUSTIFY_LEFT)
-        self.comments = gtk.Label(_("This bug really sucks!"))
+        self.comments = gtk.Label(_("No comment provided!"))
         comments_hbox = gtk.HBox(spacing=10)
         comments_hbox.pack_start(comments_lbl)
         comments_hbox.pack_start(self.comments)
@@ -468,38 +727,36 @@ class ReporterAssistant():
         bug_reports_lbl.set_alignment(0.0, 0.0)
         bug_reports_lbl.set_justify(gtk.JUSTIFY_LEFT)
         bug_reports_lbl.set_markup(_("<b>Bug reports:</b>"))
-        bug_reports = gtk.Label()
-        bug_reports.set_alignment(0.0, 0.0)
-        bug_reports.set_justify(gtk.JUSTIFY_LEFT)
-        bug_reports.set_markup(
-            "<a href=\"https://bugzilla.redhat.com/show_bug.cgi?id=578425\">"
-            "https://bugzilla.redhat.com/show_bug.cgi?id=578425</a>")
-        bug_reports_vbox = gtk.VBox(spacing=5)
-        bug_reports_vbox.pack_start(bug_reports_lbl)
-        bug_reports_vbox.pack_start(bug_reports)
+        self.bug_reports = gtk.Label()
+        self.bug_reports.set_alignment(0.0, 0.0)
+        self.bug_reports.set_justify(gtk.JUSTIFY_LEFT)
+        self.bug_reports.set_markup(_("Not reported"))
+        self.bug_reports_vbox = gtk.VBox(spacing=5)
+        self.bug_reports_vbox.pack_start(bug_reports_lbl)
+        self.bug_reports_vbox.pack_start(self.bug_reports)
         page.pack_start(report_done_lbl, expand=False)
-        page.pack_start(bug_reports_vbox, expand=False)
+        page.pack_start(self.bug_reports_vbox, expand=False)
         page.show_all()
 
     def __del__(self):
         print "wizard: about to be deleted"
 
-    def on_analyze_complete_cb(self, daemon, report, pBarWindow):
+    def on_analyze_complete_cb(self, daemon, result, pBarWindow):
         try:
             gobject.source_remove(self.timer)
         except:
             pass
         self.pBarWindow.hide()
-        if not report:
+        if not result:
             gui_error_message(_("Unable to get report!\nDebuginfo is missing?"))
             return
-        self.report = report
+        self.result = result
         # set the backtrace text
-        self.backtrace_buff.set_text(self.report[FILENAME_BACKTRACE][CD_CONTENT])
+        self.backtrace_buff.set_text(self.result[FILENAME_BACKTRACE][CD_CONTENT])
+        self.allow_send(self.backtrace_cb)
         self.show()
 
     def hydrate(self, button=None, force=0):
-        print "force: %i:" % force
         if not force:
             self.prepare_page_1()
             self.prepare_page_2()
@@ -512,11 +769,11 @@ class ReporterAssistant():
         self.pBarWindow.show_all()
         self.timer = gobject.timeout_add(100, self.progress_update_cb)
 
-        # show the report window with selected dump
+        # show the report window with selected report
         # when getReport is done it emits "analyze-complete" and on_analyze_complete_cb is called
         # FIXME: does it make sense to change it to use callback rather then signal emitting?
         try:
-            self.daemon.start_job("%s:%s" % (self.dump.getUID(), self.dump.getUUID()), force)
+            self.daemon.start_job("%s:%s" % (self.report.getUID(), self.report.getUUID()), force)
         except Exception, ex:
             # FIXME #3  dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply
             # do this async and wait for yum to end with debuginfoinstal
@@ -526,9 +783,6 @@ class ReporterAssistant():
             gui_error_message(_("Error getting the report: %s" % ex))
             return
 
-    def dehydrate(self):
-        print "dehydrate"
-
     def show(self):
         self.assistant.show()
 
diff --git a/src/Gui/Makefile.am b/src/Gui/Makefile.am
index 54fc5fd..1588b1f 100644
--- a/src/Gui/Makefile.am
+++ b/src/Gui/Makefile.am
@@ -8,7 +8,8 @@ PYTHON_FILES = CCDBusBackend.py CCDumpList.py CCDump.py CC_gui_functions.py \
                SettingsDialog.py ABRTPlugin.py PluginList.py PluginSettingsUI.py \
                PluginsSettingsDialog.py ConfBackend.py CReporterAssistant.py
 
-GLADE_FILES = ccgui.glade report.glade settings.glade dialogs.glade settings_wizard.glade
+GLADE_FILES = ccgui.glade report.glade settings.glade dialogs.glade \
+              settings_wizard.glade progress_window.glade
 
 EXTRA_DIST = $(PYTHON_FILES) $(GLADE_FILES) abrt-gui abrt.desktop
 
diff --git a/src/Gui/progress_window.glade b/src/Gui/progress_window.glade
index ae76130..6734537 100644
--- a/src/Gui/progress_window.glade
+++ b/src/Gui/progress_window.glade
@@ -6,7 +6,6 @@
     <property name="width_request">500</property>
     <property name="border_width">12</property>
     <property name="title" translatable="yes">Please wait..</property>
-    <property name="resizable">False</property>
     <property name="modal">True</property>
     <property name="window_position">center-on-parent</property>
     <property name="icon_name">abrt</property>
-- 
1.7.0.1

