|
Packit |
8ea169 |
/*
|
|
Packit |
8ea169 |
* Copyright (C) 2012 Red Hat
|
|
Packit |
8ea169 |
*
|
|
Packit |
8ea169 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8ea169 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8ea169 |
* the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
8ea169 |
* (at your option) any later version.
|
|
Packit |
8ea169 |
*
|
|
Packit |
8ea169 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8ea169 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8ea169 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8ea169 |
* GNU General Public License for more details.
|
|
Packit |
8ea169 |
*
|
|
Packit |
8ea169 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8ea169 |
* along with this program; if not, write to the Free Software
|
|
Packit |
8ea169 |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
8ea169 |
#include <config.h>
|
|
Packit |
8ea169 |
#endif
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#include "abrt-config-widget.h"
|
|
Packit |
8ea169 |
#include <satyr/utils.h>
|
|
Packit |
8ea169 |
#include <gio/gdesktopappinfo.h>
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#include "libabrt.h"
|
|
Packit |
8ea169 |
#include <assert.h>
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#define ABRT_CONFIG_WIDGET_GET_PRIVATE(o) \
|
|
Packit |
8ea169 |
(G_TYPE_INSTANCE_GET_PRIVATE((o), TYPE_ABRT_CONFIG_WIDGET, AbrtConfigWidgetPrivate))
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#define WID(s) GTK_WIDGET(gtk_builder_get_object(self->priv->builder, s))
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#define UI_FILE_NAME "abrt-config-widget.glade"
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* AbrtConfigWidgetPrivate:
|
|
Packit |
8ea169 |
* + AbrtConfigWidgetOption == "abrt-option" of GtkSwitch
|
|
Packit |
8ea169 |
* + AbrtConfigWidgetOption == "abrt-option" of GtkSwitch
|
|
Packit |
8ea169 |
* + ...
|
|
Packit |
8ea169 |
*
|
|
Packit |
8ea169 |
* + AbrtAppConfiguration == config of AbrtConfigWidgetOption
|
|
Packit |
8ea169 |
* + AbrtAppConfiguration == config of AbrtConfigWidgetOption
|
|
Packit |
8ea169 |
* + ...
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* This structure represents either an ABRT configuration file or a GSettings
|
|
Packit |
8ea169 |
* schema.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
typedef struct {
|
|
Packit |
8ea169 |
char *app_name; ///< e.g abrt-applet, org.gnome.desktop.privacy
|
|
Packit |
8ea169 |
map_string_t *settings; ///< ABRT configuration file
|
|
Packit |
8ea169 |
GSettings *glib_settings; ///< GSettings
|
|
Packit |
8ea169 |
} AbrtAppConfiguration;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* This structure represents a single switch.
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
typedef struct {
|
|
Packit |
8ea169 |
const char *name; ///< e.g. ask_steal_dir, report-technical-problems
|
|
Packit |
8ea169 |
GtkSwitch *switch_widget;
|
|
Packit |
8ea169 |
GtkWidget *radio_button_widget[3];
|
|
Packit |
8ea169 |
int default_value;
|
|
Packit |
8ea169 |
int current_value;
|
|
Packit |
8ea169 |
AbrtAppConfiguration *config;
|
|
Packit |
8ea169 |
} AbrtConfigWidgetOption;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Each configuration option has its own number. */
|
|
Packit |
8ea169 |
enum AbrtOptions
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
_ABRT_OPT_BEGIN_,
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
_ABRT_OPT_SWITCH_BEGIN_= _ABRT_OPT_BEGIN_,
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ABRT_OPT_STEAL_DIRECTORY= _ABRT_OPT_BEGIN_,
|
|
Packit |
8ea169 |
ABRT_OPT_PRIVATE_TICKET,
|
|
Packit |
8ea169 |
ABRT_OPT_SEND_UREPORT,
|
|
Packit |
8ea169 |
ABRT_OPT_SHORTENED_REPORTING,
|
|
Packit |
8ea169 |
ABRT_OPT_SILENT_SHORTENED_REPORTING,
|
|
Packit |
8ea169 |
ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS,
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
_ABRT_OPT_SWITCH_END_,
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
_ABRT_RADIOBUTTON_OPT_BEGIN_= _ABRT_OPT_SWITCH_END_,
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
ABRT_OPT_UPLOAD_COREDUMP= _ABRT_OPT_SWITCH_END_,
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
_ABRT_OPT_END_,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
enum AbrtRadioButtonOptions
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
_ABRT_RADIOBUTTON_OPT_ = -1,
|
|
Packit |
8ea169 |
ABRT_RADIOBUTTON_OPT_NEVER = 0,
|
|
Packit |
8ea169 |
ABRT_RADIOBUTTON_OPT_ALWAYS = 1,
|
|
Packit |
8ea169 |
ABRT_RADIOBUTTON_OPT_ASK = 2,
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* This structure holds private data of AbrtConfigWidget
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
struct AbrtConfigWidgetPrivate {
|
|
Packit |
8ea169 |
GtkBuilder *builder;
|
|
Packit |
8ea169 |
AbrtAppConfiguration *report_gtk_conf;
|
|
Packit |
8ea169 |
AbrtAppConfiguration *abrt_applet_conf;
|
|
Packit |
8ea169 |
AbrtAppConfiguration *privacy_gsettings;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Static array for all switches */
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption options[_ABRT_OPT_END_];
|
|
Packit |
8ea169 |
};
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
G_DEFINE_TYPE(AbrtConfigWidget, abrt_config_widget, GTK_TYPE_BOX)
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
enum {
|
|
Packit |
8ea169 |
SN_CHANGED,
|
|
Packit |
8ea169 |
SN_LAST_SIGNAL
|
|
Packit |
8ea169 |
} SignalNumber;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static guint s_signals[SN_LAST_SIGNAL] = { 0 };
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void abrt_config_widget_finalize(GObject *object);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* New ABRT configuration file wrapper
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
static AbrtAppConfiguration *
|
|
Packit |
8ea169 |
abrt_app_configuration_new(const char *app_name)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
AbrtAppConfiguration *conf = xmalloc(sizeof(*conf));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
conf->app_name = xstrdup(app_name);
|
|
Packit |
8ea169 |
conf->settings = new_map_string();
|
|
Packit |
8ea169 |
conf->glib_settings = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if(!load_app_conf_file(conf->app_name, conf->settings)) {
|
|
Packit |
8ea169 |
g_warning("Failed to load config for '%s'", conf->app_name);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return conf;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* New GSettings wrapper
|
|
Packit |
8ea169 |
*/
|
|
Packit |
8ea169 |
static AbrtAppConfiguration *
|
|
Packit |
8ea169 |
abrt_app_configuration_new_glib(const char *schema)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
AbrtAppConfiguration *conf = xmalloc(sizeof(*conf));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
conf->app_name = xstrdup(schema);
|
|
Packit |
8ea169 |
conf->settings = NULL;
|
|
Packit |
8ea169 |
conf->glib_settings = g_settings_new(conf->app_name);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
return conf;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
abrt_app_configuration_set_value(AbrtAppConfiguration *conf, const char *name, const char *value)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (conf->settings)
|
|
Packit |
8ea169 |
set_app_user_setting(conf->settings, name, value);
|
|
Packit |
8ea169 |
else if (conf->glib_settings)
|
|
Packit |
8ea169 |
g_settings_set_boolean(conf->glib_settings, name, string_to_bool(value));
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
assert(!"BUG: not properly initialized AbrtAppConfiguration");
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static const char *
|
|
Packit |
8ea169 |
abrt_app_configuration_get_value(AbrtAppConfiguration *conf, const char *name)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (conf->settings)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
const char *val = get_app_user_setting(conf->settings, name);
|
|
Packit |
8ea169 |
return (val == NULL || strcmp(val, "") == 0) ? NULL : val;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (conf->glib_settings)
|
|
Packit |
8ea169 |
return g_settings_get_boolean(conf->glib_settings, name) ? "yes" : "no";
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
assert(!"BUG: not properly initialized AbrtAppConfiguration");
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
abrt_app_configuration_save(AbrtAppConfiguration *conf)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (conf->settings)
|
|
Packit |
8ea169 |
save_app_conf_file(conf->app_name, conf->settings);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* No need to save GSettings because changes are applied instantly */
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
abrt_app_configuration_free(AbrtAppConfiguration *conf)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (!conf)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free(conf->app_name);
|
|
Packit |
8ea169 |
conf->app_name = (void *)0xDEADBEAF;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (conf->settings)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
free_map_string(conf->settings);
|
|
Packit |
8ea169 |
conf->settings = (void *)0xDEADBEAF;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (conf->glib_settings)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_object_unref(conf->glib_settings);
|
|
Packit |
8ea169 |
conf->glib_settings = (void *)0xDEADBEAF;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
abrt_config_widget_class_init(AbrtConfigWidgetClass *klass)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
object_class->finalize = abrt_config_widget_finalize;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_type_class_add_private(klass, sizeof(AbrtConfigWidgetPrivate));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
s_signals[SN_CHANGED] = g_signal_new ("changed",
|
|
Packit |
8ea169 |
G_TYPE_FROM_CLASS (klass),
|
|
Packit |
8ea169 |
G_SIGNAL_RUN_LAST,
|
|
Packit |
8ea169 |
G_STRUCT_OFFSET(AbrtConfigWidgetClass, changed),
|
|
Packit |
8ea169 |
/*accumulator*/NULL, /*accu_data*/NULL,
|
|
Packit |
8ea169 |
g_cclosure_marshal_VOID__VOID,
|
|
Packit |
8ea169 |
G_TYPE_NONE, /*n_params*/0);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
abrt_config_widget_finalize(GObject *object)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
AbrtConfigWidget *self;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self = ABRT_CONFIG_WIDGET(object);
|
|
Packit |
8ea169 |
if(self->priv->builder) {
|
|
Packit |
8ea169 |
g_object_unref(self->priv->builder);
|
|
Packit |
8ea169 |
self->priv->builder = NULL;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Clean up */
|
|
Packit |
8ea169 |
abrt_app_configuration_free(self->priv->report_gtk_conf);
|
|
Packit |
8ea169 |
self->priv->report_gtk_conf = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
abrt_app_configuration_free(self->priv->abrt_applet_conf);
|
|
Packit |
8ea169 |
self->priv->abrt_applet_conf = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
abrt_app_configuration_free(self->priv->privacy_gsettings);
|
|
Packit |
8ea169 |
self->priv->privacy_gsettings = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
G_OBJECT_CLASS(abrt_config_widget_parent_class)->finalize(object);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
emit_change(AbrtConfigWidget *config)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
g_signal_emit(config, s_signals[SN_CHANGED], 0);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
on_switch_activate(GObject *object,
|
|
Packit |
8ea169 |
GParamSpec *spec,
|
|
Packit |
8ea169 |
AbrtConfigWidget *config)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption *option = g_object_get_data(G_OBJECT(object), "abrt-option");
|
|
Packit |
8ea169 |
if (option->config == NULL)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
const gboolean state = gtk_switch_get_active(GTK_SWITCH(object));
|
|
Packit |
8ea169 |
const char *const val = state ? "yes" : "no";
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
log_debug("%s : %s", option->name, val);
|
|
Packit |
8ea169 |
abrt_app_configuration_set_value(option->config, option->name, val);
|
|
Packit |
8ea169 |
abrt_app_configuration_save(option->config);
|
|
Packit |
8ea169 |
emit_change(config);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
on_radio_button_toggle(GObject *object,
|
|
Packit |
8ea169 |
AbrtConfigWidget *config)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* inactive radio button */
|
|
Packit |
8ea169 |
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(object)) == false)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption *option = g_object_get_data(G_OBJECT(object), "abrt-option");
|
|
Packit |
8ea169 |
if (option->config == NULL)
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* get active radio button */
|
|
Packit |
8ea169 |
const char *val = g_object_get_data(G_OBJECT(object), "abrt-triple-switch-value");
|
|
Packit |
8ea169 |
log_debug("%s : %s", option->name, val);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
abrt_app_configuration_set_value(option->config, option->name, val);
|
|
Packit |
8ea169 |
abrt_app_configuration_save(option->config);
|
|
Packit |
8ea169 |
emit_change(config);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
update_option_switch_current_value(AbrtConfigWidget *self, enum AbrtOptions opid)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
assert((opid >= _ABRT_OPT_SWITCH_BEGIN_ && opid < _ABRT_OPT_SWITCH_END_) || !"Out of range Option ID value");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption *option = &(self->priv->options[opid]);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
const char *val = NULL;
|
|
Packit |
8ea169 |
if (option->config != NULL)
|
|
Packit |
8ea169 |
val = abrt_app_configuration_get_value(option->config, option->name);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
option->current_value = val ? string_to_bool(val) : option->default_value;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
update_option_radio_button_current_value(AbrtConfigWidget *self, enum AbrtOptions opid)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
assert((opid >= _ABRT_RADIOBUTTON_OPT_BEGIN_ && opid < _ABRT_OPT_END_) || !"Out of range Option ID value");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption *option = &(self->priv->options[opid]);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
const char *val = NULL;
|
|
Packit |
8ea169 |
if (option->config != NULL)
|
|
Packit |
8ea169 |
val = abrt_app_configuration_get_value(option->config, option->name);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
if (val == NULL)
|
|
Packit |
8ea169 |
option->current_value = option->default_value;
|
|
Packit |
8ea169 |
else if (string_to_bool(val))
|
|
Packit |
8ea169 |
option->current_value = ABRT_RADIOBUTTON_OPT_ALWAYS;
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
option->current_value = ABRT_RADIOBUTTON_OPT_NEVER;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
connect_switch_with_option(AbrtConfigWidget *self, enum AbrtOptions opid, const char *switch_name)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
assert((opid >= _ABRT_OPT_SWITCH_BEGIN_ && opid < _ABRT_OPT_SWITCH_END_) || !"Out of range Option ID value");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption *option = &(self->priv->options[opid]);
|
|
Packit |
8ea169 |
update_option_switch_current_value(self, opid);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GtkSwitch *gsw = GTK_SWITCH(WID(switch_name));
|
|
Packit |
8ea169 |
option->switch_widget = gsw;
|
|
Packit |
8ea169 |
gtk_switch_set_active(gsw, (gboolean)option->current_value);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(gsw), "abrt-option", option);
|
|
Packit |
8ea169 |
g_signal_connect(G_OBJECT(gsw), "notify::active",
|
|
Packit |
8ea169 |
G_CALLBACK(on_switch_activate), self);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* If the option has no config, make the corresponding insensitive. */
|
|
Packit |
8ea169 |
gtk_widget_set_sensitive(GTK_WIDGET(gsw), option->config != NULL);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
connect_radio_buttons_with_option(AbrtConfigWidget *self, enum AbrtOptions opid,
|
|
Packit |
8ea169 |
const char *btn_always_name, const char *btn_never_name,
|
|
Packit |
8ea169 |
const char *btn_ask_name)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
assert((opid >= _ABRT_RADIOBUTTON_OPT_BEGIN_ && opid < _ABRT_OPT_END_) || !"Out of range Option ID value");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtConfigWidgetOption *option = &(self->priv->options[opid]);
|
|
Packit |
8ea169 |
update_option_radio_button_current_value(self, opid);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GtkWidget *btn_always = WID(btn_always_name);
|
|
Packit |
8ea169 |
GtkWidget *btn_never = WID(btn_never_name);
|
|
Packit |
8ea169 |
GtkWidget *btn_ask = WID(btn_ask_name);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
option->radio_button_widget[ABRT_RADIOBUTTON_OPT_ALWAYS] = btn_always;
|
|
Packit |
8ea169 |
option->radio_button_widget[ABRT_RADIOBUTTON_OPT_NEVER] = btn_never;
|
|
Packit |
8ea169 |
option->radio_button_widget[ABRT_RADIOBUTTON_OPT_ASK] = btn_ask;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GtkWidget *active_button = option->radio_button_widget[option->current_value];
|
|
Packit |
8ea169 |
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(active_button), TRUE);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(btn_always), "abrt-option", option);
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(btn_always), "abrt-triple-switch-value", (char *)"yes");
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(btn_never), "abrt-option", option);
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(btn_never), "abrt-triple-switch-value", (char *)"no");
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(btn_ask), "abrt-option", option);
|
|
Packit |
8ea169 |
g_object_set_data(G_OBJECT(btn_ask), "abrt-triple-switch-value", NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
g_signal_connect(btn_always, "toggled", G_CALLBACK(on_radio_button_toggle), self);
|
|
Packit |
8ea169 |
g_signal_connect(btn_never, "toggled", G_CALLBACK(on_radio_button_toggle), self);
|
|
Packit |
8ea169 |
g_signal_connect(btn_ask, "toggled", G_CALLBACK(on_radio_button_toggle), self);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* If the option has no config, make the corresponding insensitive. */
|
|
Packit |
8ea169 |
gtk_widget_set_sensitive(GTK_WIDGET(btn_always), option->config != NULL);
|
|
Packit |
8ea169 |
gtk_widget_set_sensitive(GTK_WIDGET(btn_never), option->config != NULL);
|
|
Packit |
8ea169 |
gtk_widget_set_sensitive(GTK_WIDGET(btn_ask), option->config != NULL);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
pp_launcher_clicked(GtkButton *launcher, gpointer *unused_data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GDesktopAppInfo *app = g_object_get_data(G_OBJECT(launcher), "launched-app");
|
|
Packit |
8ea169 |
GError *err = NULL;
|
|
Packit |
8ea169 |
if (!g_app_info_launch(G_APP_INFO(app), NULL, NULL, &err))
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
perror_msg("Could not launch '%s': %s",
|
|
Packit |
8ea169 |
g_desktop_app_info_get_filename(G_DESKTOP_APP_INFO (app)),
|
|
Packit |
8ea169 |
err->message);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
os_release_callback(char *key, char *value, void *data)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
if (strcmp(key, "PRIVACY_POLICY") == 0)
|
|
Packit |
8ea169 |
*(char **)data = value;
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
free(value);
|
|
Packit |
8ea169 |
free(key);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
static void
|
|
Packit |
8ea169 |
abrt_config_widget_init(AbrtConfigWidget *self)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
GError *error = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv = ABRT_CONFIG_WIDGET_GET_PRIVATE(self);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv->builder = gtk_builder_new();
|
|
Packit |
8ea169 |
gtk_builder_set_translation_domain(self->priv->builder, GETTEXT_PACKAGE);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
gtk_builder_add_from_file(self->priv->builder, UI_FILE_NAME, &error);
|
|
Packit |
8ea169 |
if(error != NULL) {
|
|
Packit |
8ea169 |
log_debug("Failed to load '%s': %s", UI_FILE_NAME, error->message);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
error = NULL;
|
|
Packit |
8ea169 |
gtk_builder_add_from_file(self->priv->builder, ABRT_UI_DIR "/" UI_FILE_NAME, &error);
|
|
Packit |
8ea169 |
if(error != NULL) {
|
|
Packit |
8ea169 |
g_warning("Failed to load '%s': %s", ABRT_UI_DIR "/" UI_FILE_NAME, error->message);
|
|
Packit |
8ea169 |
g_error_free(error);
|
|
Packit |
8ea169 |
return;
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Load configuration */
|
|
Packit |
8ea169 |
load_abrt_conf();
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv->report_gtk_conf = abrt_app_configuration_new("report-gtk");
|
|
Packit |
8ea169 |
self->priv->abrt_applet_conf = abrt_app_configuration_new("abrt-applet");
|
|
Packit |
8ea169 |
self->priv->privacy_gsettings = abrt_app_configuration_new_glib("org.gnome.desktop.privacy");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Initialize options */
|
|
Packit |
8ea169 |
/* report-gtk */
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_STEAL_DIRECTORY].name = "ask_steal_dir";
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_STEAL_DIRECTORY].default_value = TRUE;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_STEAL_DIRECTORY].config = self->priv->report_gtk_conf;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].name = "abrt_analyze_upload_coredump";
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].default_value = ABRT_RADIOBUTTON_OPT_ASK;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_UPLOAD_COREDUMP].config = self->priv->report_gtk_conf;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_PRIVATE_TICKET].name = CREATE_PRIVATE_TICKET;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_PRIVATE_TICKET].default_value = FALSE;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_PRIVATE_TICKET].config = self->priv->report_gtk_conf;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* abrt-applet */
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SEND_UREPORT].name = "report-technical-problems";
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SEND_UREPORT].default_value =
|
|
Packit |
8ea169 |
string_to_bool(abrt_app_configuration_get_value(self->priv->privacy_gsettings,
|
|
Packit |
8ea169 |
"report-technical-problems"));
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Get the container widget for the lauch button and warnings */
|
|
Packit |
8ea169 |
GtkWidget *hbox_auto_reporting = WID("hbox_auto_reporting");
|
|
Packit |
8ea169 |
assert(hbox_auto_reporting);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Be able to use another desktop file while debugging */
|
|
Packit |
8ea169 |
const char *gpp_app = getenv("ABRT_PRIVACY_APP_DESKTOP");
|
|
Packit |
8ea169 |
if (gpp_app == NULL)
|
|
Packit |
8ea169 |
gpp_app = "gnome-privacy-panel.desktop";
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GDesktopAppInfo *app = g_desktop_app_info_new(gpp_app);
|
|
Packit |
8ea169 |
char *message = NULL;
|
|
Packit |
8ea169 |
char *markup = NULL;
|
|
Packit |
8ea169 |
if (!app)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Make the switch editable */
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SEND_UREPORT].config = self->priv->privacy_gsettings;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
char *os_release = xmalloc_open_read_close("/etc/os-release", /*no size limit*/NULL);
|
|
Packit |
8ea169 |
char *privacy_policy = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Try to get the value of PRIVACY_POLICY from /etc/os-release */
|
|
Packit |
8ea169 |
sr_parse_os_release(os_release, os_release_callback, (void *)&privacy_policy);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
message = xasprintf(_("The configuration option above has been moved to GSettings and "
|
|
Packit |
8ea169 |
"the switch is linked to the value of the setting 'report-technical-problems' "
|
|
Packit |
8ea169 |
"from the schema 'org.gnome.desktop.privacy'."));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Do not add Privacy Policy link if /etc/os-release does not contain PRIVACY_POLICY */
|
|
Packit |
8ea169 |
if (privacy_policy != NULL)
|
|
Packit |
8ea169 |
markup = xasprintf("%s\n\nPrivacy Policy", message, privacy_policy);
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
markup = xasprintf("%s", message);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free(privacy_policy);
|
|
Packit |
8ea169 |
free(os_release);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
else
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
/* Make the switch read-only */
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SEND_UREPORT].config = NULL;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
message = xasprintf(_("The configuration option above can be configured in"));
|
|
Packit |
8ea169 |
markup = xasprintf("%s", message);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GtkWidget *launcher = gtk_button_new_with_label(g_app_info_get_display_name(G_APP_INFO(app)));
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Here we could pass the launcher to pp_launcher_clicked() as the
|
|
Packit |
8ea169 |
* 4th argument of g_signal_connect() but we would leek the
|
|
Packit |
8ea169 |
* launcher's memory. Therefore we need to find a way how to free
|
|
Packit |
8ea169 |
* the launcher when it is not needed anymore. GtkWidget inherits
|
|
Packit |
8ea169 |
* from GObject which offers a functionality for attaching an
|
|
Packit |
8ea169 |
* arbitrary data to its instances. The last argument is a function
|
|
Packit |
8ea169 |
* called to destroy the arbirarty data when the instance is being
|
|
Packit |
8ea169 |
* destroyed. */
|
|
Packit |
8ea169 |
g_object_set_data_full(G_OBJECT(launcher), "launched-app", app, g_object_unref);
|
|
Packit |
8ea169 |
g_signal_connect(launcher, "clicked", G_CALLBACK(pp_launcher_clicked), NULL);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Make the launcher button narrow, otherwise it would expand to
|
|
Packit |
8ea169 |
* the width of the warninig. */
|
|
Packit |
8ea169 |
gtk_widget_set_hexpand(launcher, FALSE);
|
|
Packit |
8ea169 |
gtk_widget_set_vexpand(launcher, FALSE);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Make the launcher button aligned on center of the warning. */
|
|
Packit |
8ea169 |
gtk_widget_set_halign(launcher, GTK_ALIGN_CENTER);
|
|
Packit |
8ea169 |
gtk_widget_set_valign(launcher, GTK_ALIGN_CENTER);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
gtk_box_pack_end(GTK_BOX(hbox_auto_reporting), launcher, false, false, 0);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
GtkWidget *lbl = gtk_label_new(message);
|
|
Packit |
8ea169 |
gtk_label_set_markup(GTK_LABEL(lbl), markup);
|
|
Packit |
8ea169 |
/* Do not expand the window by too long warning. */
|
|
Packit |
8ea169 |
gtk_label_set_line_wrap(GTK_LABEL(lbl), TRUE);
|
|
Packit |
8ea169 |
/* Let users to copy the warning. */
|
|
Packit |
8ea169 |
gtk_label_set_selectable(GTK_LABEL(lbl), TRUE);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
free(markup);
|
|
Packit |
8ea169 |
free(message);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
gtk_box_pack_start(GTK_BOX(hbox_auto_reporting), lbl, false, false, 0);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SHORTENED_REPORTING].name = "ShortenedReporting";
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SHORTENED_REPORTING].default_value = g_settings_shortenedreporting;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SHORTENED_REPORTING].config = self->priv->abrt_applet_conf;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SILENT_SHORTENED_REPORTING].name = "SilentShortenedReporting";
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SILENT_SHORTENED_REPORTING].default_value = FALSE;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_SILENT_SHORTENED_REPORTING].config = self->priv->abrt_applet_conf;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS].name = "NotifyIncompleteProblems";
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS].default_value = FALSE;
|
|
Packit |
8ea169 |
self->priv->options[ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS].config = self->priv->abrt_applet_conf;
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Connect radio buttons with options */
|
|
Packit |
8ea169 |
connect_radio_buttons_with_option(self, ABRT_OPT_UPLOAD_COREDUMP,
|
|
Packit |
8ea169 |
"bg_always", "bg_never", "bg_ask" );
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Connect widgets with options */
|
|
Packit |
8ea169 |
connect_switch_with_option(self, ABRT_OPT_STEAL_DIRECTORY, "switch_steal_directory");
|
|
Packit |
8ea169 |
connect_switch_with_option(self, ABRT_OPT_PRIVATE_TICKET, "switch_private_ticket");
|
|
Packit |
8ea169 |
connect_switch_with_option(self, ABRT_OPT_SEND_UREPORT, "switch_send_ureport");
|
|
Packit |
8ea169 |
connect_switch_with_option(self, ABRT_OPT_SHORTENED_REPORTING, "switch_shortened_reporting");
|
|
Packit |
8ea169 |
connect_switch_with_option(self, ABRT_OPT_SILENT_SHORTENED_REPORTING, "switch_silent_shortened_reporting");
|
|
Packit |
8ea169 |
connect_switch_with_option(self, ABRT_OPT_NOTIFY_INCOMPLETE_PROBLEMS, "switch_notify_incomplete_problems");
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
#if ((GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION < 13) || (GTK_MAJOR_VERSION == 3 && GTK_MINOR_VERSION == 13 && GTK_MICRO_VERSION == 1))
|
|
Packit |
8ea169 |
/* https://developer.gnome.org/gtk3/3.13/GtkWidget.html#gtk-widget-reparent */
|
|
Packit |
8ea169 |
/* gtk_widget_reparent has been deprecated since version 3.13.2 and should not be used in newly-written code. */
|
|
Packit |
8ea169 |
gtk_widget_reparent(WID("grid"), GTK_WIDGET(self));
|
|
Packit |
8ea169 |
#else
|
|
Packit |
8ea169 |
gtk_container_remove(GTK_CONTAINER(WID("window1")), WID("grid"));
|
|
Packit |
8ea169 |
gtk_container_add(GTK_CONTAINER(self), WID("grid"));
|
|
Packit |
8ea169 |
#endif
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
/* Set the initial state of the properties */
|
|
Packit |
8ea169 |
gtk_widget_show_all(GTK_WIDGET(self));
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
AbrtConfigWidget *
|
|
Packit |
8ea169 |
abrt_config_widget_new()
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
return g_object_new(TYPE_ABRT_CONFIG_WIDGET, NULL);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
void
|
|
Packit |
8ea169 |
abrt_config_widget_reset_to_defaults(AbrtConfigWidget *self)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
for(unsigned i = _ABRT_OPT_SWITCH_BEGIN_; i < _ABRT_OPT_SWITCH_END_; ++i)
|
|
Packit |
8ea169 |
gtk_switch_set_active(self->priv->options[i].switch_widget, self->priv->options[i].default_value);
|
|
Packit |
8ea169 |
|
|
Packit |
8ea169 |
for(unsigned i = _ABRT_RADIOBUTTON_OPT_BEGIN_; i < _ABRT_OPT_END_; ++i)
|
|
Packit |
8ea169 |
{
|
|
Packit |
8ea169 |
unsigned default_value = self->priv->options[i].default_value;
|
|
Packit |
8ea169 |
GtkWidget *radio_button = self->priv->options[i].radio_button_widget[default_value];
|
|
Packit |
8ea169 |
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio_button), TRUE);
|
|
Packit |
8ea169 |
}
|
|
Packit |
8ea169 |
}
|