From 8db880a2c6add7137aac9f8562ae73aef3e1e436 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Wed, 30 Jul 2014 13:53:02 +0200 Subject: [PATCH 20/20] gui: add "Repeat" button If an event run fails, the button allows users to modify the configuration and re-run the event. v2: - add a help text explaining what to do before clicking "Repeat" button Related to rhbz#1069917 Signed-off-by: Jakub Filak --- src/gui-wizard-gtk/wizard.c | 83 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c index e803394..e4718bf 100644 --- a/src/gui-wizard-gtk/wizard.c +++ b/src/gui-wizard-gtk/wizard.c @@ -68,6 +68,7 @@ static GtkWidget *g_btn_stop; static GtkWidget *g_btn_close; static GtkWidget *g_btn_next; static GtkWidget *g_btn_onfail; +static GtkWidget *g_btn_repeat; static GtkBox *g_box_events; static GtkBox *g_box_workflows; @@ -1573,24 +1574,31 @@ static void show_next_step_button() gtk_widget_show(g_btn_next); } -static void terminate_event_chain() +enum { + TERMINATE_NOFLAGS = 0, + TERMINATE_WITH_RERUN = 1 << 0, +}; + +static void terminate_event_chain(int flags) { if (g_expert_mode) return; + hide_next_step_button(); + if ((flags & TERMINATE_WITH_RERUN)) + return; + free(g_event_selected); g_event_selected = NULL; g_list_free_full(g_auto_event_list, free); g_auto_event_list = NULL; - - hide_next_step_button(); } -static void cancel_processing(GtkLabel *status_label, const char *message) +static void cancel_processing(GtkLabel *status_label, const char *message, int terminate_flags) { gtk_label_set_text(status_label, message ? message : _("Processing was canceled")); - terminate_event_chain(); + terminate_event_chain(terminate_flags); } static void update_command_run_log(const char* message, struct analyze_event_data *evd) @@ -1755,6 +1763,25 @@ static void on_btn_failed_cb(GtkButton *button) gtk_widget_hide(GTK_WIDGET(button)); } +static gint select_next_page_no(gint current_page_no, gpointer data); +static void on_page_prepare(GtkNotebook *assistant, GtkWidget *page, gpointer user_data); + +static void on_btn_repeat_cb(GtkButton *button) +{ + g_auto_event_list = g_list_prepend(g_auto_event_list, g_event_selected); + g_event_selected = NULL; + + show_next_step_button(); + clear_warnings(); + + const gint current_page_no = gtk_notebook_get_current_page(g_assistant); + const int next_page_no = select_next_page_no(pages[PAGENO_SUMMARY].page_no, NULL); + if (current_page_no == next_page_no) + on_page_prepare(g_assistant, gtk_notebook_get_nth_page(g_assistant, next_page_no), NULL); + else + gtk_notebook_set_current_page(g_assistant, next_page_no); +} + static void on_failed_event(const char *event_name) { /* Don't show the 'on failure' button if the processed event @@ -1764,14 +1791,25 @@ static void on_failed_event(const char *event_name) return; add_warning( -_("Processing of the problem failed. This can have many reasons but there are two most common:\n"\ +_("Processing of the problem failed. This can have many reasons but there are three most common:\n"\ "\t▫ network connection problems\n"\ -"\t▫ corrupted problem data\n")); +"\t▫ corrupted problem data\n"\ +"\t▫ invalid configuration" +)); + + if (!g_expert_mode) + { + add_warning( +_("If you want to update the configuration and try to report again, please open Preferences item\n" +"in the application menu and after applying the configuration changes click Repeat button.")); + gtk_widget_show(g_btn_repeat); + } add_warning( -_("If you want to help us, please click on the upload button and provide all problem data for a deep analysis.\n"\ -"Before you do that, please consider the security risks. Problem data may contain sensitive information like passwords.\n"\ -"The uploaded data are stored in a protected storage and only a limited number of persons can read them.")); +_("If you are sure that this problem is not caused by network problems neither by invalid configuration\n" +"and want to help us, please click on the upload button and provide all problem data for a deep analysis.\n"\ +"Before you do that, please consider the security risks. Problem data may contain sensitive information like\n"\ +"passwords. The uploaded data are stored in a protected storage and only a limited number of persons can read them.")); show_warnings(); @@ -1798,7 +1836,7 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g retval = 0; run_state->process_status = 0; stop_requested = true; - terminate_event_chain(); + terminate_event_chain(TERMINATE_NOFLAGS); } unexport_event_config(evd->env_list); @@ -1887,17 +1925,17 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g gtk_widget_show(GTK_WIDGET(g_img_process_fail)); /* 256 means NOT_REPORTABLE */ if (retval == 256) - cancel_processing(g_lbl_event_log, _("Processing was interrupted because the problem is not reportable.")); + cancel_processing(g_lbl_event_log, _("Processing was interrupted because the problem is not reportable."), TERMINATE_NOFLAGS); else { /* We use SIGTERM to stop event processing on user's request. * So SIGTERM is not a failure. */ if (retval == EXIT_CANCEL_BY_USER || WTERMSIG(run_state->process_status) == SIGTERM) - cancel_processing(g_lbl_event_log, /* default message */ NULL); + cancel_processing(g_lbl_event_log, /* default message */ NULL, TERMINATE_NOFLAGS); else { - cancel_processing(g_lbl_event_log, _("Processing failed.")); + cancel_processing(g_lbl_event_log, _("Processing failed."), TERMINATE_WITH_RERUN); on_failed_event(evd->event_name); } } @@ -2036,7 +2074,7 @@ static void start_event_run(const char *event_name) char *msg = xasprintf(_("No processing for event '%s' is defined"), event_name); append_to_textview(g_tv_event_log, msg); free(msg); - cancel_processing(g_lbl_event_log, _("Processing failed.")); + cancel_processing(g_lbl_event_log, _("Processing failed."), TERMINATE_NOFLAGS); return; } @@ -2047,7 +2085,7 @@ static void start_event_run(const char *event_name) free_run_event_state(state); if (!g_expert_mode) { - cancel_processing(g_lbl_event_log, _("Processing interrupted: can't continue without writable directory.")); + cancel_processing(g_lbl_event_log, _("Processing interrupted: can't continue without writable directory."), TERMINATE_NOFLAGS); } return; /* user refused to steal, or write error, etc... */ } @@ -2534,8 +2572,6 @@ static gboolean highlight_forbidden(void) return result; } -static gint select_next_page_no(gint current_page_no, gpointer data); - static char *get_next_processed_event(GList **events_list) { if (!events_list || !*events_list) @@ -2647,6 +2683,8 @@ static void on_page_prepare(GtkNotebook *assistant, GtkWidget *page, gpointer us } gtk_widget_hide(g_btn_onfail); + if (!g_expert_mode) + gtk_widget_hide(g_btn_repeat); /* Save text fields if changed */ /* Must be called before any GUI operation because the following two * functions causes recreating of the text items tabs, thus all updates to @@ -2867,7 +2905,7 @@ static gint select_next_page_no(gint current_page_no, gpointer data) { free(event); - cancel_processing(g_lbl_event_log, /* default message */ NULL); + cancel_processing(g_lbl_event_log, /* default message */ NULL, TERMINATE_NOFLAGS); current_page_no = pages[PAGENO_EVENT_PROGRESS].page_no - 1; goto again; } @@ -2880,7 +2918,7 @@ static gint select_next_page_no(gint current_page_no, gpointer data) "(it is likely a known problem). %s"), problem_data_get_content_or_NULL(g_cd, FILENAME_NOT_REPORTABLE) ); - cancel_processing(g_lbl_event_log, msg); + cancel_processing(g_lbl_event_log, msg, TERMINATE_NOFLAGS); free(msg); current_page_no = pages[PAGENO_EVENT_PROGRESS].page_no - 1; goto again; @@ -3453,6 +3491,8 @@ void create_assistant(GtkApplication *app, bool expert_mode) g_btn_onfail = gtk_button_new_with_label(_("Upload for analysis")); gtk_button_set_image(GTK_BUTTON(g_btn_onfail), gtk_image_new_from_icon_name("go-up", GTK_ICON_SIZE_BUTTON)); gtk_widget_set_no_show_all(g_btn_onfail, true); /* else gtk_widget_hide won't work */ + g_btn_repeat = gtk_button_new_with_label(_("Repeat")); + gtk_widget_set_no_show_all(g_btn_repeat, true); /* else gtk_widget_hide won't work */ g_btn_next = gtk_button_new_with_mnemonic(_("_Forward")); gtk_button_set_image(GTK_BUTTON(g_btn_next), gtk_image_new_from_icon_name("go-next", GTK_ICON_SIZE_BUTTON)); gtk_widget_set_no_show_all(g_btn_next, true); /* else gtk_widget_hide won't work */ @@ -3461,6 +3501,7 @@ void create_assistant(GtkApplication *app, bool expert_mode) gtk_box_pack_start(g_box_buttons, g_btn_close, false, false, 5); gtk_box_pack_start(g_box_buttons, g_btn_stop, false, false, 5); gtk_box_pack_start(g_box_buttons, g_btn_onfail, false, false, 5); + gtk_box_pack_start(g_box_buttons, g_btn_repeat, false, false, 5); /* Btns above are to the left, the rest are to the right: */ #if ((GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 13) || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION == 13 && GTK_MICRO_VERSION < 5)) GtkWidget *w = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); @@ -3514,6 +3555,7 @@ void create_assistant(GtkApplication *app, bool expert_mode) gtk_widget_show_all(GTK_WIDGET(g_box_buttons)); gtk_widget_hide(g_btn_stop); gtk_widget_hide(g_btn_onfail); + gtk_widget_hide(g_btn_repeat); gtk_widget_show(g_btn_next); g_wnd_assistant = GTK_WINDOW(gtk_application_window_new(app)); @@ -3534,6 +3576,7 @@ void create_assistant(GtkApplication *app, bool expert_mode) g_signal_connect(g_btn_close, "clicked", G_CALLBACK(assistant_quit_cb), g_wnd_assistant); g_signal_connect(g_btn_stop, "clicked", G_CALLBACK(on_btn_cancel_event), NULL); g_signal_connect(g_btn_onfail, "clicked", G_CALLBACK(on_btn_failed_cb), NULL); + g_signal_connect(g_btn_repeat, "clicked", G_CALLBACK(on_btn_repeat_cb), NULL); g_signal_connect(g_btn_next, "clicked", G_CALLBACK(on_next_btn_cb), NULL); g_signal_connect(g_wnd_assistant, "destroy", G_CALLBACK(assistant_quit_cb), g_wnd_assistant); -- 2.0.4