From b89e812251efdbbc83ed84932c7dc0d0852d153c Mon Sep 17 00:00:00 2001 From: Matej Habrnal Date: Mon, 8 Jun 2015 10:31:07 +0200 Subject: [PATCH] configui: add option always generate backtrace locally The option 'Ask before uploading coredump' is replaced by 'Upload coredump for backtrace generation'. The new config option allows the user to choose the option always generate the backtrace locally ('Never'). Related to rhbz#986876 Related to abrt/gnome-abrt#131 Signed-off-by: Matej Habrnal Signed-off-by: Jakub Filak --- src/configuration-gui/abrt-config-widget.c | 152 ++++++++++++++++++++++--- src/configuration-gui/abrt-config-widget.glade | 119 +++++++++++++------ 2 files changed, 219 insertions(+), 52 deletions(-) diff --git a/src/configuration-gui/abrt-config-widget.c b/src/configuration-gui/abrt-config-widget.c index 664180d..7d2430b 100644 --- a/src/configuration-gui/abrt-config-widget.c +++ b/src/configuration-gui/abrt-config-widget.c @@ -38,10 +38,11 @@ typedef struct { } AbrtAppConfiguration; typedef struct { - const char *name; - GtkSwitch *widget; - gboolean default_value; - gboolean current_value; + const char *name; ///< e.g. ask_steal_dir, report-technical-problems + GtkSwitch *switch_widget; + GtkWidget *radio_button_widget[3]; + int default_value; + int current_value; AbrtAppConfiguration *config; } AbrtConfigWidgetOption; @@ -49,17 +50,34 @@ enum AbrtOptions { _ABRT_OPT_BEGIN_, - ABRT_OPT_UPLOAD_COREDUMP = _ABRT_OPT_BEGIN_, - ABRT_OPT_STEAL_DIRECTORY, + _ABRT_OPT_SWITCH_BEGIN_= _ABRT_OPT_BEGIN_, + + ABRT_OPT_STEAL_DIRECTORY= _ABRT_OPT_BEGIN_, ABRT_OPT_PRIVATE_TICKET, ABRT_OPT_SEND_UREPORT, ABRT_OPT_SHORTENED_REPORTING, ABRT_OPT_SILENT_SHORTENED_REPORTING, ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS, + _ABRT_OPT_SWITCH_END_, + + _ABRT_RADIOBUTTON_OPT_BEGIN_= _ABRT_OPT_SWITCH_END_, + + ABRT_OPT_UPLOAD_COREDUMP= _ABRT_OPT_SWITCH_END_, + _ABRT_OPT_END_, }; +enum AbrtRadioButtonOptions +{ + _ABRT_RADIOBUTTON_OPT_ = -1, + ABRT_RADIOBUTTON_OPT_NEVER = 0, + ABRT_RADIOBUTTON_OPT_ALWAYS = 1, + ABRT_RADIOBUTTON_OPT_ASK = 2, +}; + +/* This structure holds private data of AbrtConfigWidget + */ struct AbrtConfigWidgetPrivate { GtkBuilder *builder; AbrtAppConfiguration *report_gtk_conf; @@ -103,7 +121,13 @@ abrt_app_configuration_set_value(AbrtAppConfiguration *conf, const char *name, c static const char * abrt_app_configuration_get_value(AbrtAppConfiguration *conf, const char *name) { - return get_app_user_setting(conf->settings, name); + if (conf->settings) + { + const char *val = get_app_user_setting(conf->settings, name); + return (val == NULL || strcmp(val, "") == 0) ? NULL : val; + } + + assert(!"BUG: not properly initialized AbrtAppConfiguration"); } static void @@ -186,9 +210,30 @@ on_switch_activate(GObject *object, } static void -update_option_current_value(AbrtConfigWidget *self, enum AbrtOptions opid) +on_radio_button_toggle(GObject *object, + AbrtConfigWidget *config) { - assert((opid >= _ABRT_OPT_BEGIN_ && opid < _ABRT_OPT_END_) || !"Out of range Option ID value"); + /* inactive radio button */ + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(object)) == false) + return; + + AbrtConfigWidgetOption *option = g_object_get_data(G_OBJECT(object), "abrt-option"); + if (option->config == NULL) + return; + + /* get active radio button */ + const char *val = g_object_get_data(G_OBJECT(object), "abrt-triple-switch-value"); + log_debug("%s : %s", option->name, val); + + abrt_app_configuration_set_value(option->config, option->name, val); + abrt_app_configuration_save(option->config); + emit_change(config); +} + +static void +update_option_switch_current_value(AbrtConfigWidget *self, enum AbrtOptions opid) +{ + assert((opid >= _ABRT_OPT_SWITCH_BEGIN_ && opid < _ABRT_OPT_SWITCH_END_) || !"Out of range Option ID value"); AbrtConfigWidgetOption *option = &(self->priv->options[opid]); const char *val = abrt_app_configuration_get_value(option->config, option->name); @@ -196,19 +241,80 @@ update_option_current_value(AbrtConfigWidget *self, enum AbrtOptions opid) } static void +update_option_radio_button_current_value(AbrtConfigWidget *self, enum AbrtOptions opid) +{ + assert((opid >= _ABRT_RADIOBUTTON_OPT_BEGIN_ && opid < _ABRT_OPT_END_) || !"Out of range Option ID value"); + + AbrtConfigWidgetOption *option = &(self->priv->options[opid]); + + const char *val = NULL; + if (option->config != NULL) + val = abrt_app_configuration_get_value(option->config, option->name); + + if (val == NULL) + option->current_value = option->default_value; + else if (string_to_bool(val)) + option->current_value = ABRT_RADIOBUTTON_OPT_ALWAYS; + else + option->current_value = ABRT_RADIOBUTTON_OPT_NEVER; +} + +static void connect_switch_with_option(AbrtConfigWidget *self, enum AbrtOptions opid, const char *switch_name) { - assert((opid >= _ABRT_OPT_BEGIN_ && opid < _ABRT_OPT_END_) || !"Out of range Option ID value"); + assert((opid >= _ABRT_OPT_SWITCH_BEGIN_ && opid < _ABRT_OPT_SWITCH_END_) || !"Out of range Option ID value"); AbrtConfigWidgetOption *option = &(self->priv->options[opid]); - update_option_current_value(self, opid); + update_option_switch_current_value(self, opid); GtkSwitch *gsw = GTK_SWITCH(WID(switch_name)); - option->widget = gsw; - gtk_switch_set_active(gsw, option->current_value); + option->switch_widget = gsw; + gtk_switch_set_active(gsw, (gboolean)option->current_value); + g_object_set_data(G_OBJECT(gsw), "abrt-option", option); g_signal_connect(G_OBJECT(gsw), "notify::active", G_CALLBACK(on_switch_activate), self); + + /* If the option has no config, make the corresponding insensitive. */ + gtk_widget_set_sensitive(GTK_WIDGET(gsw), option->config != NULL); +} + +static void +connect_radio_buttons_with_option(AbrtConfigWidget *self, enum AbrtOptions opid, + const char *btn_always_name, const char *btn_never_name, + const char *btn_ask_name) +{ + assert((opid >= _ABRT_RADIOBUTTON_OPT_BEGIN_ && opid < _ABRT_OPT_END_) || !"Out of range Option ID value"); + + AbrtConfigWidgetOption *option = &(self->priv->options[opid]); + update_option_radio_button_current_value(self, opid); + + GtkWidget *btn_always = WID(btn_always_name); + GtkWidget *btn_never = WID(btn_never_name); + GtkWidget *btn_ask = WID(btn_ask_name); + + option->radio_button_widget[ABRT_RADIOBUTTON_OPT_ALWAYS] = btn_always; + option->radio_button_widget[ABRT_RADIOBUTTON_OPT_NEVER] = btn_never; + option->radio_button_widget[ABRT_RADIOBUTTON_OPT_ASK] = btn_ask; + + GtkWidget *active_button = option->radio_button_widget[option->current_value]; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(active_button), TRUE); + + g_object_set_data(G_OBJECT(btn_always), "abrt-option", option); + g_object_set_data(G_OBJECT(btn_always), "abrt-triple-switch-value", (char *)"yes"); + g_object_set_data(G_OBJECT(btn_never), "abrt-option", option); + g_object_set_data(G_OBJECT(btn_never), "abrt-triple-switch-value", (char *)"no"); + g_object_set_data(G_OBJECT(btn_ask), "abrt-option", option); + g_object_set_data(G_OBJECT(btn_ask), "abrt-triple-switch-value", NULL); + + g_signal_connect(btn_always, "toggled", G_CALLBACK(on_radio_button_toggle), self); + g_signal_connect(btn_never, "toggled", G_CALLBACK(on_radio_button_toggle), self); + g_signal_connect(btn_ask, "toggled", G_CALLBACK(on_radio_button_toggle), self); + + /* If the option has no config, make the corresponding insensitive. */ + gtk_widget_set_sensitive(GTK_WIDGET(btn_always), option->config != NULL); + gtk_widget_set_sensitive(GTK_WIDGET(btn_never), option->config != NULL); + gtk_widget_set_sensitive(GTK_WIDGET(btn_ask), option->config != NULL); } static void @@ -246,8 +352,8 @@ abrt_config_widget_init(AbrtConfigWidget *self) self->priv->options[ABRT_OPT_STEAL_DIRECTORY].default_value = TRUE; self->priv->options[ABRT_OPT_STEAL_DIRECTORY].config = self->priv->report_gtk_conf; - self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].name = "abrt_analyze_smart_ask_upload_coredump"; - self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].default_value = TRUE; + self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].name = "abrt_analyze_upload_coredump"; + self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].default_value = ABRT_RADIOBUTTON_OPT_ASK; self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].config = self->priv->report_gtk_conf; self->priv->options[ABRT_OPT_PRIVATE_TICKET].name = CREATE_PRIVATE_TICKET; @@ -271,8 +377,11 @@ abrt_config_widget_init(AbrtConfigWidget *self) self->priv->options[ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS].default_value = FALSE; self->priv->options[ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS].config = self->priv->abrt_applet_conf; + /* Connect radio buttons with options */ + connect_radio_buttons_with_option(self, ABRT_OPT_UPLOAD_COREDUMP, + "bg_always", "bg_never", "bg_ask" ); + /* Connect widgets with options */ - connect_switch_with_option(self, ABRT_OPT_UPLOAD_COREDUMP, "switch_upload_coredump"); connect_switch_with_option(self, ABRT_OPT_STEAL_DIRECTORY, "switch_steal_directory"); connect_switch_with_option(self, ABRT_OPT_PRIVATE_TICKET, "switch_private_ticket"); connect_switch_with_option(self, ABRT_OPT_SEND_UREPORT, "switch_send_ureport"); @@ -302,6 +411,13 @@ abrt_config_widget_new() void abrt_config_widget_reset_to_defaults(AbrtConfigWidget *self) { - for(unsigned i = _ABRT_OPT_BEGIN_; i < _ABRT_OPT_END_; ++i) - gtk_switch_set_active(self->priv->options[i].widget, self->priv->options[i].default_value); + for(unsigned i = _ABRT_OPT_SWITCH_BEGIN_; i < _ABRT_OPT_SWITCH_END_; ++i) + gtk_switch_set_active(self->priv->options[i].switch_widget, self->priv->options[i].default_value); + + for(unsigned i = _ABRT_RADIOBUTTON_OPT_BEGIN_; i < _ABRT_OPT_END_; ++i) + { + unsigned default_value = self->priv->options[i].default_value; + GtkWidget *radio_button = self->priv->options[i].radio_button_widget[default_value]; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE); + } } diff --git a/src/configuration-gui/abrt-config-widget.glade b/src/configuration-gui/abrt-config-widget.glade index 3aa566c..30737ff 100644 --- a/src/configuration-gui/abrt-config-widget.glade +++ b/src/configuration-gui/abrt-config-widget.glade @@ -49,21 +49,6 @@ - - True - True - end - center - 10 - - - 1 - 0 - 1 - 1 - - - True True @@ -163,7 +148,7 @@ True False - The coredump file is necessary for generating stack trace which is time and space consuming operation. ABRT provides a service which generates the stack trace from the coredump but you have to upload the coredump to this service. With this option disabled ABRT will upload the coredump without asking. + The coredump file is necessary for generating stack trace which is time and space consuming operation. ABRT provides a service which generates the stack trace from the coredump but you have to upload the coredump to this service. With option 'Always' ABRT will always upload the coredump without asking. With option 'Never' the stack trace will be always generated locally. With option 'Ask' ABRT will always ask the user. end 5 1 @@ -241,24 +226,6 @@ - - True - False - start - True - 10 - Ask before uploading coredump - - - - - 0 - 0 - 1 - 1 - - - True False @@ -352,6 +319,90 @@ 1 + + + True + False + end + center + False + False + immediate + expand + + + Always + True + True + False + 0 + True + False + bg_ask + + + True + True + 2 + True + + + + + Never + True + True + False + 0 + True + False + bg_ask + + + True + True + 2 + + + + + Ask + True + True + False + 0 + True + False + + + False + True + 2 + + + + + 1 + 0 + + + + + True + False + start + True + 10 + Upload coredump for backtrace generation + + + 0 + 0 + + + + + -- 2.1.0