[LIBREPORT PATCH 1/2] - implemented saving/loading configuratio for workflows - related to trac#822
by Jiri Moskovcak
- configuration is shared with the events, so changes in events
are reflected in workflow and vice versa
---
src/gtk-helpers/config_dialog.c | 262 ++++++++++++++++++++++++-------
src/gtk-helpers/event_config_dialog.c | 158 +++++++------------
src/gtk-helpers/internal_libreport_gtk.h | 39 +++--
src/gtk-helpers/workflow_config_dialog.c | 83 +++++-----
src/gui-wizard-gtk/main.c | 2 +-
src/gui-wizard-gtk/wizard.c | 8 +-
src/include/event_config.h | 4 +-
src/include/internal_libreport.h | 2 +-
src/lib/event_config.c | 13 +-
src/lib/workflow.c | 17 +-
10 files changed, 367 insertions(+), 221 deletions(-)
diff --git a/src/gtk-helpers/config_dialog.c b/src/gtk-helpers/config_dialog.c
index 88d01ae..3c81d7c 100644
--- a/src/gtk-helpers/config_dialog.c
+++ b/src/gtk-helpers/config_dialog.c
@@ -34,19 +34,55 @@ enum
TYPE_POINTER
};
+struct config_dialog
+{
+ GtkWidget *dialog;
+ gpointer *data;
+ config_save_fun_t save_data;
+};
+
GtkListStore *new_conf_liststore(void)
{
/* Create data store for the list and attach it
- * COLUMN_EVENT_UINAME -> name+description
- * COLUMN_EVENT_NAME -> event name so we can retrieve it from the row
+ * COLUMN_UINAME -> name+description
+ * COLUMN_NAME -> config name so we can retrieve it from the row
*/
return gtk_list_store_new(NUM_COLUMNS,
G_TYPE_STRING, /* Event name + description */
G_TYPE_STRING, /* event name */
- G_TYPE_POINTER
+ G_TYPE_POINTER, /* dialog */
+ G_TYPE_POINTER /* option_list */
);
}
+
+config_dialog_t *new_config_dialog(GtkWidget *dialog,
+ gpointer config_data,
+ config_save_fun_t save_fun)
+{
+ config_dialog_t *cdialog = (config_dialog_t *)xmalloc(sizeof(*cdialog));
+ cdialog->dialog = dialog;
+ cdialog->data = config_data;
+ cdialog->save_data = save_fun;
+ return cdialog;
+}
+
+void cdialog_set_widget(config_dialog_t *cdialog, GtkWidget *widget)
+{
+ //TODO destroy(cdialog-dialog) ??
+ cdialog->dialog = widget;
+}
+
+GtkWidget *cdialog_get_widget(config_dialog_t *cdialog)
+{
+ return cdialog->dialog;
+}
+
+gpointer cdialog_get_data(config_dialog_t *cdialog)
+{
+ return cdialog->data;
+}
+
static const void *get_column_value_from_row(GtkTreeView *treeview, int column, int type)
{
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
@@ -71,40 +107,39 @@ static const void *get_column_value_from_row(GtkTreeView *treeview, int column,
return retval;
}
-static void on_row_changed_cb(GtkTreeView *treeview, gpointer user_data)
+static void save_value_from_widget(gpointer data, gpointer user_data)
{
- VERB1 log("activated row: '%s'", (const char*)get_column_value_from_row(treeview, COLUMN_NAME, TYPE_STR));
+ option_widget_t *ow = (option_widget_t *)data;
- const void *dialog = get_column_value_from_row(treeview, CONFIG_DIALOG, TYPE_POINTER);
- gtk_widget_set_sensitive(GTK_WIDGET(user_data), dialog != NULL);
-}
-
-static void on_configure_button_cb(GtkWidget *button, gpointer user_data)
-{
- GtkTreeView *tv = (GtkTreeView *)user_data;
- const void * dialog = get_column_value_from_row(tv, CONFIG_DIALOG, TYPE_POINTER);
-
- if (dialog != NULL)
+ const char *val = NULL;
+ switch (ow->option->eo_type)
{
- int result = gtk_dialog_run(GTK_DIALOG(dialog));
- if (result == GTK_RESPONSE_APPLY)
- {
- //TODO: saving!!!
- g_print("apply\n");
- }
- //else if (result == GTK_RESPONSE_CANCEL)
- // log("log");
- gtk_widget_hide(GTK_WIDGET(dialog));
+ case OPTION_TYPE_TEXT:
+ case OPTION_TYPE_NUMBER:
+ case OPTION_TYPE_PASSWORD:
+ val = (char *)gtk_entry_get_text(GTK_ENTRY(ow->widget));
+ break;
+ case OPTION_TYPE_BOOL:
+ val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ow->widget)) ? "yes" : "no";
+ break;
+ default:
+ log("unsupported option type");
+ }
+ if (val)
+ {
+ free(ow->option->eo_value);
+ ow->option->eo_value = xstrdup(val);
+ VERB1 log("saved: %s:%s", ow->option->eo_name, ow->option->eo_value);
}
}
-static void on_close_list_cb(GtkWidget *button, gpointer user_data)
+void dehydrate_config_dialog(GList *option_widgets)
{
- GtkWidget *window = (GtkWidget *)user_data;
- gtk_widget_destroy(window);
+ if (option_widgets != NULL)
+ g_list_foreach(option_widgets, &save_value_from_widget, NULL);
}
-void add_item_to_config_liststore(gpointer dialog, gpointer inf, gpointer user_data)
+void add_item_to_config_liststore(gpointer cdialog, gpointer inf, gpointer user_data)
{
GtkListStore *list_store = (GtkListStore *)user_data;
config_item_info_t *info = (config_item_info_t *)inf;
@@ -115,24 +150,20 @@ void add_item_to_config_liststore(gpointer dialog, gpointer inf, gpointer user_d
label = xasprintf("<b>%s</b>\n%s",ci_get_screen_name(info), ci_get_description(info));
else
//if event has no xml description
- label = xasprintf("<b>%s</b>\nNo description available", ci_get_name(info));
+ label = xasprintf("<b>%s</b>\n%s", _("No description available"), ci_get_name(info));
GtkTreeIter iter;
gtk_list_store_append(list_store, &iter);
gtk_list_store_set(list_store, &iter,
COLUMN_UINAME, label,
COLUMN_NAME, ci_get_name(info),
- CONFIG_DIALOG, dialog,
+ CONFIG_DIALOG, cdialog,
-1);
free(label);
}
-GtkWidget *create_config_list_dialog(const char *column_label,
- GHashTable *items,
- GtkWindow *dialog,
- GHFunc item_to_config_info,
- GCallback on_config_cb,
- GCallback on_row_change)
+GtkWidget *create_config_tab_content(const char *column_label,
+ GtkListStore *store)
{
GtkWidget *main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
@@ -161,37 +192,148 @@ GtkWidget *create_config_list_dialog(const char *column_label,
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tv), TRUE);
// TODO: gtk_tree_view_set_headers_visible(FALSE)? We have only one column anyway...
- /* Create data store for the list and attach it
- * COLUMN_UINAME -> name+description
- * COLUMN_NAME -> workflow name so we can retrieve it from the row
- */
- GtkListStore *list_store = new_conf_liststore();
- gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(list_store));
+ gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(store));
+ gtk_container_add(GTK_CONTAINER(scroll), tv);
- g_hash_table_foreach(items,
- item_to_config_info,
- list_store);
-//TODO: can unref workflows_list_store? treeview holds one ref.
+ gtk_box_pack_start(GTK_BOX(main_vbox), scroll, true, true, 10);
+ return main_vbox;
+}
- /* Double click/Enter handler */
- //g_signal_connect(workflows_tv, "row-activated", G_CALLBACK(on_workflow_row_activated_cb), NULL);
+static void add_config_tabs(const char *name, GtkListStore *store, gpointer nb)
+{
+ GtkNotebook *ntb = (GtkNotebook *)nb;
- gtk_container_add(GTK_CONTAINER(scroll), tv);
+ GtkWidget *config_list_vbox = create_config_tab_content(
+ name,
+ store);
- GtkWidget *configure_btn = gtk_button_new_with_mnemonic(_("C_onfigure"));
- gtk_widget_set_sensitive(configure_btn, false);
- g_signal_connect(configure_btn, "clicked", G_CALLBACK(on_configure_button_cb), tv);
- g_signal_connect(tv, "cursor-changed", G_CALLBACK(on_row_changed_cb), configure_btn);
+ gtk_notebook_append_page(ntb, config_list_vbox, gtk_label_new(name));
+}
+
+static void on_configure_cb(GtkWidget *btn, gpointer user_data)
+{
+ GtkNotebook *nb = (GtkNotebook *)user_data;
+
+ guint current_page_n = gtk_notebook_get_current_page(nb);
+ GtkWidget *vbox = gtk_notebook_get_nth_page(nb, current_page_n);
+ GList *children = gtk_container_get_children(GTK_CONTAINER(vbox));
+ GtkScrolledWindow *sw = (GtkScrolledWindow *)children->data;
+ GtkTreeView *tv = (GtkTreeView *)gtk_bin_get_child(GTK_BIN(sw));
+ config_dialog_t *cdialog = (config_dialog_t *)get_column_value_from_row(tv, CONFIG_DIALOG, TYPE_POINTER);
+ const char *name = (const char *)get_column_value_from_row(tv, COLUMN_NAME, TYPE_STR);
+
+ if (cdialog == NULL || cdialog->dialog == NULL)
+ {
+ log("There is no configurable option for: '%s'", name);
+ return;
+ }
+
+ int result = gtk_dialog_run(GTK_DIALOG(cdialog->dialog));
+ if (result == GTK_RESPONSE_APPLY)
+ {
+ if (cdialog->save_data)
+ cdialog->save_data(cdialog->data, name);
+ }
+ else if (result == GTK_RESPONSE_CANCEL)
+ VERB1 log("Cancelling on user request");
+
+ gtk_widget_hide(GTK_WIDGET(cdialog->dialog));
+}
+
+static void on_close_cb(GtkWidget *btn, gpointer config_list_w)
+{
+ GtkWidget *w = (GtkWidget *)config_list_w;
+ gtk_widget_hide(w);
+}
+
+GtkWindow *create_config_list_window(GHashTable *configs, GtkWindow *parent)
+{
+
+ // config window
+ GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width(GTK_CONTAINER(window), 5);
+ gtk_window_set_title(GTK_WINDOW(window), _("Configuration"));
+ gtk_window_set_default_size(GTK_WINDOW(window), 450, 400);
+ gtk_window_set_position(GTK_WINDOW(window), parent
+ ? GTK_WIN_POS_CENTER_ON_PARENT
+ : GTK_WIN_POS_CENTER);
+
+ if (parent != NULL)
+ {
+ gtk_window_set_modal(GTK_WINDOW(window), true);
+ gtk_window_set_transient_for(GTK_WINDOW(window), parent);
+ }
+
+ //g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+ GtkWidget *main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
+ GtkWidget *config_nb = gtk_notebook_new();
+ gtk_box_pack_start(GTK_BOX(main_vbox), config_nb, 1, 1, 0);
+
+ /* we can't use this, because we want the workflows first and hashtable
+ * doesn't return the items in the order they were added
+ */
+ //g_hash_table_foreach(configs, (GHFunc)add_config_tabs, config_nb);
+
+ gpointer config = g_hash_table_lookup(configs, _("Workflows"));
+ if (config != NULL);
+ add_config_tabs(_("Workflows"), config, config_nb);
+
+ config = g_hash_table_lookup(configs, _("Events"));
+ if (config != NULL);
+ add_config_tabs(_("Events"), config, config_nb);
+
+ //buttons
+ GtkWidget *btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
+ GtkWidget *configure_btn = gtk_button_new_with_mnemonic(_("C_onfigure"));
+ GtkWidget *align = gtk_alignment_new(0, 0, 0, 0);
GtkWidget *close_btn = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
- g_signal_connect(close_btn, "clicked", G_CALLBACK(on_close_list_cb), dialog);
+ GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
+ //force apply and close to have the same size
+ gtk_size_group_add_widget(sg, close_btn);
+ gtk_size_group_add_widget(sg, configure_btn);
- GtkWidget *btnbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_end(GTK_BOX(btnbox), close_btn, false, false, 0);
- gtk_box_pack_end(GTK_BOX(btnbox), configure_btn, false, false, 0);
+ g_signal_connect(configure_btn, "clicked", (GCallback)on_configure_cb, config_nb);
+ g_signal_connect(close_btn, "clicked", (GCallback)on_close_cb, window);
- gtk_box_pack_start(GTK_BOX(main_vbox), scroll, true, true, 10);
- gtk_box_pack_start(GTK_BOX(main_vbox), btnbox, false, false, 0);
+ gtk_box_pack_start(GTK_BOX(btn_box), close_btn, 0, 0, 5);
+ gtk_box_pack_start(GTK_BOX(btn_box), align, true, true, 5);
+ gtk_box_pack_start(GTK_BOX(btn_box), configure_btn, 0, 0, 5);
- return main_vbox;
+
+ gtk_box_pack_start(GTK_BOX(main_vbox), btn_box, 0, 0, 0);
+ gtk_container_add(GTK_CONTAINER(window), main_vbox);
+
+ //gtk_widget_show_all(window);
+ return GTK_WINDOW(window);
+}
+
+/* Name | vbox with the gtk_Tree
+ * <String name, GtkWidget *vbox>
+*/
+
+void show_config_list_dialog(GtkWindow *parent)
+{
+ GHashTable *confs = g_hash_table_new_full(
+ /*hash_func*/ g_str_hash,
+ /*key_equal_func:*/ g_str_equal,
+ /*key_destroy_func:*/ g_free,
+ /*value_destroy_func:*/ NULL);
+
+
+ //TODO: free the hashtables somewhere!!
+ GHashTable *events = load_event_config_data();
+ load_event_config_data_from_user_storage(events);
+
+ GHashTable *workflows = load_workflow_config_data(WORKFLOWS_DIR);
+ load_workflow_config_data_from_user_storage(workflows);
+ GtkListStore *workflows_store = add_workflows_to_liststore(workflows);
+ g_hash_table_insert(confs, _("Workflows"), workflows_store);
+
+ GtkListStore *events_store = add_events_to_liststore(events);
+ g_hash_table_insert(confs, _("Events"), events_store);
+
+ GtkWindow *window = create_config_list_window(confs, parent);
+ gtk_widget_show_all(GTK_WIDGET(window));
}
diff --git a/src/gtk-helpers/event_config_dialog.c b/src/gtk-helpers/event_config_dialog.c
index 01527ec..82d07df 100644
--- a/src/gtk-helpers/event_config_dialog.c
+++ b/src/gtk-helpers/event_config_dialog.c
@@ -20,7 +20,8 @@
#include "internal_libreport_gtk.h"
static GtkWindow *g_event_list_window;
-static GList *option_widget_list;
+static GList *g_option_list = NULL;
+
static bool has_password_option;
enum
@@ -30,14 +31,6 @@ enum
NUM_COLUMNS
};
-typedef struct
-{
- event_option_t *option;
- GtkWidget *widget;
-} option_widget_t;
-
-int show_event_config_dialog(const char *event_name, GtkWindow *parent);
-
static GtkWidget *gtk_label_new_justify_left(const gchar *label_str)
{
GtkWidget *label = gtk_label_new(label_str);
@@ -48,12 +41,14 @@ static GtkWidget *gtk_label_new_justify_left(const gchar *label_str)
return label;
}
-static void add_option_widget(GtkWidget *widget, event_option_t *option)
+GList *add_option_widget(GList *options, GtkWidget *widget, event_option_t *option)
{
- option_widget_t *ow = (option_widget_t *)xmalloc(sizeof(option_widget_t));
+ option_widget_t *ow = (option_widget_t *)xmalloc(sizeof(*ow));
ow->widget = widget;
ow->option = option;
- option_widget_list = g_list_prepend(option_widget_list, ow);
+ options = g_list_prepend(options, ow);
+
+ return options;
}
static void on_show_pass_cb(GtkToggleButton *tb, gpointer user_data)
@@ -75,6 +70,23 @@ static unsigned add_one_row_to_grid(GtkGrid *table)
return rows;
}
+void save_data_from_event_config_dialog(GList *widgets, event_config_t *ec)
+{
+ dehydrate_config_dialog(widgets);
+ const char *const store_passwords_s = get_user_setting("store_passwords");
+ save_event_config_data_to_user_storage(ec_get_name(ec),
+ ec,
+ !(store_passwords_s && !strcmp(store_passwords_s, "no")));
+}
+
+static void save_data_from_event_dialog_name(GList *widgets, const char *name)
+{
+ event_config_t *ec = get_event_config(name);
+
+ save_data_from_event_config_dialog(widgets, ec);
+}
+
+
static void add_option_to_table(gpointer data, gpointer user_data)
{
event_option_t *option = data;
@@ -116,7 +128,7 @@ static void add_option_to_table(gpointer data, gpointer user_data)
gtk_grid_attach(option_table, option_input,
/*left,top:*/ 1, last_row,
/*width,height:*/ 1, 1);
- add_option_widget(option_input, option);
+ g_option_list = add_option_widget(g_option_list, option_input, option);
if (option->eo_type == OPTION_TYPE_PASSWORD)
{
gtk_entry_set_visibility(GTK_ENTRY(option_input), 0);
@@ -151,7 +163,7 @@ static void add_option_to_table(gpointer data, gpointer user_data)
if (option->eo_value != NULL)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(option_input),
string_to_bool(option->eo_value));
- add_option_widget(option_input, option);
+ g_option_list = add_option_widget(g_option_list, option_input, option);
break;
default:
@@ -177,39 +189,7 @@ static void add_option_to_table(gpointer data, gpointer user_data)
free(option_label);
}
-static void save_value_from_widget(gpointer data, gpointer user_data)
-{
- option_widget_t *ow = (option_widget_t *)data;
-
- const char *val = NULL;
- switch (ow->option->eo_type)
- {
- case OPTION_TYPE_TEXT:
- case OPTION_TYPE_NUMBER:
- case OPTION_TYPE_PASSWORD:
- val = (char *)gtk_entry_get_text(GTK_ENTRY(ow->widget));
- break;
- case OPTION_TYPE_BOOL:
- val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ow->widget)) ? "yes" : "no";
- break;
- default:
- log("unsupported option type");
- }
- if (val)
- {
- free(ow->option->eo_value);
- ow->option->eo_value = xstrdup(val);
- VERB1 log("saved: %s:%s", ow->option->eo_name, ow->option->eo_value);
- }
-}
-
-static void dehydrate_config_dialog()
-{
- if (option_widget_list != NULL)
- g_list_foreach(option_widget_list, &save_value_from_widget, NULL);
-}
-
-GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *content)
+config_dialog_t *create_event_config_dialog_content(event_config_t *event, GtkWidget *content)
{
if (content == NULL)
content = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -238,6 +218,13 @@ GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *
g_object_set_data(G_OBJECT(option_table), "advanced-options", adv_option_table);
has_password_option = false;
+ /* it's already stored in config_dialog_t from the previous call
+ * we need to set it to null so we create a new list for the actual
+ * event_config
+ * note: say *NO* to the global variables!
+ */
+ g_option_list = NULL;
+ /* this fills the g_option_list, so we can use it for new_config_dialog */
g_list_foreach(event->options, &add_option_to_table, option_table);
/* if there is at least one password option, add checkbox to disable storing passwords */
@@ -275,17 +262,17 @@ GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *
gtk_widget_show_all(content); //make it all visible
- return content;
+ //g_option_list is filled on
+ config_dialog_t *cdialog = new_config_dialog(NULL,
+ g_option_list,
+ (config_save_fun_t)save_data_from_event_dialog_name
+ );
+
+ return cdialog;
}
-GtkWidget *create_config_dialog(const char *event_name, GtkWindow *parent)
+config_dialog_t *create_event_config_dialog(const char *event_name, GtkWindow *parent)
{
- if (option_widget_list != NULL)
- {
- g_list_free(option_widget_list);
- option_widget_list = NULL;
- }
-
event_config_t *event = get_event_config(event_name);
if(!ec_is_configurable(event))
@@ -320,26 +307,30 @@ GtkWidget *create_config_dialog(const char *event_name, GtkWindow *parent)
}
GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- content = create_event_config_dialog_content(event, content);
+ config_dialog_t *cdialog = create_event_config_dialog_content(event, content);
+ cdialog_set_widget(cdialog, dialog);
- return dialog;
+ return cdialog;
}
-static void add_event_to_liststore(gpointer key, gpointer value, gpointer user_data)
+static void add_event_to_liststore(gpointer key, gpointer value, gpointer list_store)
{
config_item_info_t *info = ec_get_config_info((event_config_t *)value);
- GtkWidget *dialog = create_config_dialog(key, NULL);
- add_item_to_config_liststore(dialog, info, user_data);
+ config_dialog_t *cdialog = create_event_config_dialog(key, NULL);
+
+ add_item_to_config_liststore(cdialog, info, list_store);
}
-int show_event_config_dialog(const char *event_name, GtkWindow *parent)
+GtkListStore *add_events_to_liststore(GHashTable *events)
{
- if (option_widget_list != NULL)
- {
- g_list_free(option_widget_list);
- option_widget_list = NULL;
- }
+ GtkListStore *list_store = new_conf_liststore();
+ g_hash_table_foreach(events, (GHFunc)add_event_to_liststore, list_store);
+
+ return list_store;
+}
+int show_event_config_dialog(const char *event_name, GtkWindow *parent)
+{
event_config_t *event = get_event_config(event_name);
GtkWindow *parent_window = parent ? parent : g_event_list_window;
@@ -371,14 +362,14 @@ int show_event_config_dialog(const char *event_name, GtkWindow *parent)
}
GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- content = create_event_config_dialog_content(event, content);
+ content = cdialog_get_widget(create_event_config_dialog_content(event, content));
gtk_widget_show_all(content);
int result = gtk_dialog_run(GTK_DIALOG(dialog));
if (result == GTK_RESPONSE_APPLY)
{
- dehydrate_config_dialog();
+ dehydrate_config_dialog(g_option_list);
const char *const store_passwords_s = get_user_setting("store_passwords");
save_event_config_data_to_user_storage(event_name,
get_event_config(event_name),
@@ -390,34 +381,3 @@ int show_event_config_dialog(const char *event_name, GtkWindow *parent)
return result;
}
-void show_events_list_dialog(GtkWindow *parent)
-{
- /*remove this line if we want to reload the config
- *everytime we show the config dialog
- */
- if (g_event_config_list == NULL)
- {
- load_event_config_data();
- load_event_config_data_from_user_storage(g_event_config_list);
- }
-
- GtkWidget *event_list_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- g_event_list_window = (GtkWindow*)event_list_window;
- gtk_window_set_title(g_event_list_window, _("Event Configuration"));
- gtk_window_set_default_size(g_event_list_window, 450, 400);
- gtk_window_set_position(g_event_list_window, parent ? GTK_WIN_POS_CENTER_ON_PARENT : GTK_WIN_POS_CENTER);
- if (parent != NULL)
- {
- gtk_window_set_transient_for(g_event_list_window, parent);
- // modal = parent window can't steal focus
- gtk_window_set_modal(g_event_list_window, true);
- gtk_window_set_icon_name(g_event_list_window,
- gtk_window_get_icon_name(parent));
- }
-
- GtkWidget *main_vbox = create_config_list_dialog(_("Event"), g_event_config_list, GTK_WINDOW(event_list_window), &add_event_to_liststore, NULL, NULL);
-
- gtk_container_add(GTK_CONTAINER(event_list_window), main_vbox);
-
- gtk_widget_show_all(event_list_window);
-}
diff --git a/src/gtk-helpers/internal_libreport_gtk.h b/src/gtk-helpers/internal_libreport_gtk.h
index 5e631cb..c59158e 100644
--- a/src/gtk-helpers/internal_libreport_gtk.h
+++ b/src/gtk-helpers/internal_libreport_gtk.h
@@ -27,6 +27,15 @@
extern "C" {
#endif
+typedef struct config_dialog config_dialog_t;
+typedef void (* config_save_fun_t)(gpointer data, const char *event_name);
+
+typedef struct
+{
+ event_option_t *option;
+ GtkWidget *widget;
+} option_widget_t;
+
#define make_label_autowrap_on_resize libreport_make_label_autowrap_on_resize
void make_label_autowrap_on_resize(GtkLabel *label);
@@ -51,22 +60,28 @@ void save_event_config_data_to_user_storage(const char *event_name,
int show_event_config_dialog(const char *event_name, GtkWindow *parent);
#define create_event_config_dialog_content libreport_create_event_config_dialog_content
-GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *content);
+config_dialog_t *create_event_config_dialog_content(event_config_t *event, GtkWidget *content);
+
+//#define show_workflow_list_dialog libreport_show_workflow_list_dialog
+//void show_workflow_list_dialog(GtkWindow *parent);
-#define show_workflow_list_dialog libreport_show_workflow_list_dialog
-void show_workflow_list_dialog(GtkWindow *parent);
+void save_data_from_event_config_dialog(GList *widgets, event_config_t *ec);
#define add_item_to_config_liststore libreport_add_item_to_config_liststore
-void add_item_to_config_liststore(gpointer key, gpointer value, gpointer user_data);
-
-#define create_config_list_dialog libreport_create_config_list_dialog
-GtkWidget *create_config_list_dialog(const char *column_label,
- GHashTable *items,
- GtkWindow *dialog,
- GHFunc item_to_config_info,
- GCallback on_config_cb,
- GCallback on_row_change);
+void add_item_to_config_liststore(gpointer cdialog, gpointer inf, gpointer user_data);
+
GtkListStore *new_conf_liststore(void);
+void show_config_list_dialog(GtkWindow *parent);
+GtkListStore *add_events_to_liststore(GHashTable *events);
+GtkListStore *add_workflows_to_liststore(GHashTable *workflows);
+config_dialog_t *new_config_dialog(GtkWidget *dialog, gpointer config_data, config_save_fun_t save_fun);
+void load_workflow_config_data_from_user_storage(GHashTable *workflows);
+
+void cdialog_set_widget(config_dialog_t *cdialog, GtkWidget *widget);
+GtkWidget *cdialog_get_widget(config_dialog_t *cdialog);
+gpointer cdialog_get_data(config_dialog_t *cdialog);
+
+void dehydrate_config_dialog(GList *option_widgets);
char * tag_url(const char* line, const char* prefix);
diff --git a/src/gtk-helpers/workflow_config_dialog.c b/src/gtk-helpers/workflow_config_dialog.c
index de10134..93dd622 100644
--- a/src/gtk-helpers/workflow_config_dialog.c
+++ b/src/gtk-helpers/workflow_config_dialog.c
@@ -27,13 +27,42 @@ enum
};
static GtkWindow *g_parent_window;
+static GHashTable *g_events_options = NULL;
static void create_event_config_dialog_content_cb(event_config_t *ec, gpointer content)
{
- create_event_config_dialog_content(ec, (GtkWidget *)content);
+ if (ec->options)
+ {
+ GtkWidget *ev_lbl = gtk_label_new(ec_get_screen_name(ec));
+ gtk_box_pack_start(GTK_BOX(content), ev_lbl, false, false, 0);
+ }
+
+ config_dialog_t *cdialog = create_event_config_dialog_content(ec, (GtkWidget *)content);
+ if (g_events_options == NULL)
+ {
+ g_events_options = g_hash_table_new_full(
+ /*hash_func*/ g_str_hash,
+ /*key_equal_func:*/ g_str_equal,
+ /*key_destroy_func:*/ g_free,
+ /*value_destroy_func:*/ NULL);
+ }
+ g_hash_table_insert(g_events_options, ec, cdialog);
+
}
-GtkWidget *create_workflow_config_dialog(const char *workflow_name, GtkWindow *parent)
+static void save_event_config_data_foreach(event_config_t *ec,
+ config_dialog_t *cdialog,
+ gpointer user_data)
+{
+ save_data_from_event_config_dialog(cdialog_get_data(cdialog), ec);
+}
+
+void save_data_from_worfklow_dialog(gpointer data, /* not needed */ const char *name)
+{
+ g_hash_table_foreach((GHashTable *)data, (GHFunc)save_event_config_data_foreach, NULL);
+}
+
+config_dialog_t *create_workflow_config_dialog(const char *workflow_name, GtkWindow *parent)
{
workflow_t *workflow = get_workflow(workflow_name);
GList *events = wf_get_event_list(workflow);
@@ -61,16 +90,28 @@ GtkWidget *create_workflow_config_dialog(const char *workflow_name, GtkWindow *p
GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ g_events_options = NULL;
g_list_foreach(events, (GFunc)create_event_config_dialog_content_cb, content);
- return dialog;
+ config_dialog_t *cdialog = new_config_dialog(dialog,
+ g_events_options,
+ (config_save_fun_t)save_data_from_worfklow_dialog);
+ return cdialog;
}
static void add_workflow_to_liststore(gpointer key, gpointer value, gpointer user_data)
{
config_item_info_t *info = workflow_get_config_info((workflow_t *)value);
- GtkWidget *dialog = create_workflow_config_dialog(key, g_parent_window);
- add_item_to_config_liststore(dialog, info, user_data);
+ config_dialog_t *cdialog = create_workflow_config_dialog(key, g_parent_window);
+ add_item_to_config_liststore(cdialog, info, user_data);
+}
+
+GtkListStore *add_workflows_to_liststore(GHashTable *workflows)
+{
+ GtkListStore *list_store = new_conf_liststore();
+ g_hash_table_foreach(workflows, (GHFunc)add_workflow_to_liststore, list_store);
+
+ return list_store;
}
static void load_single_event_config_foreach(event_config_t *ec, gpointer user_data)
@@ -83,35 +124,7 @@ static void load_events_foreach_workflow(const char *name, workflow_t *workflow,
g_list_foreach(wf_get_event_list(workflow), (GFunc)load_single_event_config_foreach, NULL);
}
-void show_workflow_list_dialog(GtkWindow *parent)
+void load_workflow_config_data_from_user_storage(GHashTable *workflows)
{
- g_parent_window = parent;
- //g_verbose = 3;
- if (g_workflow_list == NULL)
- {
- VERB1 log("workflow list is empty - reloading");
- load_workflow_config_data(WORKFLOWS_DIR);
- }
-
- g_hash_table_foreach(g_workflow_list, (GHFunc)load_events_foreach_workflow, NULL);
-
- GtkWindow *workflow_list_window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
- gtk_window_set_title(workflow_list_window, _("Workflow Configuration"));
- gtk_window_set_default_size(workflow_list_window, 450, 400);
- gtk_window_set_position(workflow_list_window, parent ? GTK_WIN_POS_CENTER_ON_PARENT : GTK_WIN_POS_CENTER);
- if (parent != NULL)
- {
- gtk_window_set_transient_for(workflow_list_window, parent);
- // modal = parent window can't steal focus
- gtk_window_set_modal(workflow_list_window, true);
- gtk_window_set_icon_name(workflow_list_window,
- gtk_window_get_icon_name(parent));
- }
-
- GtkWidget *main_vbox = create_config_list_dialog(_("Workflow"), g_workflow_list, workflow_list_window, add_workflow_to_liststore, NULL, NULL);
-
- gtk_container_add(GTK_CONTAINER(workflow_list_window), main_vbox);
-
- gtk_widget_show_all(GTK_WIDGET(workflow_list_window));
-
+ g_hash_table_foreach(workflows, (GHFunc)load_events_foreach_workflow, NULL);
}
diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c
index 03f8fd2..b47687b 100644
--- a/src/gui-wizard-gtk/main.c
+++ b/src/gui-wizard-gtk/main.c
@@ -140,7 +140,7 @@ int main(int argc, char **argv)
/* load /etc/abrt/events/foo.{conf,xml} stuff
and $XDG_CACHE_HOME/abrt/events/foo.conf */
- load_event_config_data();
+ g_event_config_list = load_event_config_data();
load_event_config_data_from_user_storage(g_event_config_list);
load_user_settings("report-gtk");
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index dae4e80..0abcbba 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -1522,9 +1522,6 @@ static bool is_processing_finished()
static void hide_next_step_button()
{
- if(gtk_widget_get_visible(GTK_WIDGET(g_btn_next)) == false)
- return
-
/* replace 'Forward' with 'Close' button */
/* 1. hide next button */
gtk_widget_hide(g_btn_next);
@@ -1534,9 +1531,6 @@ static void hide_next_step_button()
static void show_next_step_button()
{
- if(gtk_widget_get_visible(GTK_WIDGET(g_btn_next)) == true)
- return
-
gtk_box_reorder_child(g_box_buttons, g_btn_close, 0);
gtk_widget_show(g_btn_next);
}
@@ -2044,7 +2038,7 @@ static void on_no_comment_toggled(GtkToggleButton *togglebutton, gpointer user_d
static void on_show_event_list_cb(GtkWidget *button, gpointer user_data)
{
- show_events_list_dialog(GTK_WINDOW(g_wnd_assistant));
+ show_config_list_dialog(GTK_WINDOW(g_wnd_assistant));
}
#if 0
diff --git a/src/include/event_config.h b/src/include/event_config.h
index 68463d3..24e1eac 100644
--- a/src/include/event_config.h
+++ b/src/include/event_config.h
@@ -103,12 +103,14 @@ void free_event_config(event_config_t *p);
void load_event_description_from_file(event_config_t *event_config, const char* filename);
// (Re)loads data from /etc/abrt/events/*.{conf,xml}
-void load_event_config_data(void);
+GHashTable *load_event_config_data(void);
/* Frees all loaded data */
void free_event_config_data(void);
event_config_t *get_event_config(const char *event_name);
event_option_t *get_event_option_from_list(const char *option_name, GList *event_options);
+/* for debugging */
+void ec_print(event_config_t *ec);
extern GHashTable *g_event_config_list; // for iterating through entire list of all loaded configs
diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
index 4f85b2a..88a1f25 100644
--- a/src/include/internal_libreport.h
+++ b/src/include/internal_libreport.h
@@ -644,7 +644,7 @@ file_obj_t *new_file_obj(const char* fullpath, const char* filename);
#define free_file_obj libreport_free_file_obj
void free_file_obj(file_obj_t *f);
#define load_workflow_config_data libreport_load_workflow_config_data
-void load_workflow_config_data(const char* path);
+GHashTable *load_workflow_config_data(const char* path);
/* Connect to abrtd over unix domain socket, issue DELETE command */
int delete_dump_dir_possibly_using_abrtd(const char *dump_dir_name);
diff --git a/src/lib/event_config.c b/src/lib/event_config.c
index e6ae269..88041ff 100644
--- a/src/lib/event_config.c
+++ b/src/lib/event_config.c
@@ -79,6 +79,15 @@ bool ec_is_configurable(event_config_t* ec)
return g_list_length(ec->options) > 0;
}
+void ec_print(event_config_t *ec)
+{
+ printf("%s\n\t%s\n\t%s\n",
+ ec_get_name(ec),
+ ec_get_screen_name(ec),
+ ec_get_description(ec)
+ );
+}
+
void free_event_option(event_option_t *p)
{
if (!p)
@@ -183,7 +192,7 @@ static void load_config_files(const char *dir_path)
}
/* (Re)loads data from /etc/abrt/events/foo.{xml,conf} and $XDG_CACHE_HOME/abrt/events/foo.conf */
-void load_event_config_data(void)
+GHashTable *load_event_config_data(void)
{
free_event_config_data();
@@ -227,6 +236,8 @@ void load_event_config_data(void)
cachedir = concat_path_file(g_get_user_cache_dir(), "abrt/events");
load_config_files(cachedir);
free(cachedir);
+
+ return g_event_config_list;
}
/* Frees all loaded data */
diff --git a/src/lib/workflow.c b/src/lib/workflow.c
index 1b92283..6fa2634 100644
--- a/src/lib/workflow.c
+++ b/src/lib/workflow.c
@@ -53,10 +53,14 @@ static void free_workflow_cb(const char *name, workflow_t *w, gpointer user_data
free_workflow(w);
}
-void free_workflow_list(GHashTable *wl)
+void free_workflow_list(GHashTable **wl)
{
- g_hash_table_foreach(wl, (GHFunc)free_workflow_cb, NULL);
- g_hash_table_destroy(wl);
+ if(*wl != NULL)
+ {
+ g_hash_table_foreach(*wl, (GHFunc)free_workflow_cb, NULL);
+ g_hash_table_destroy(*wl);
+ *wl = NULL;
+ }
}
workflow_t *get_workflow(const char *name)
@@ -74,8 +78,11 @@ workflow_t *get_workflow(const char *name)
return g_hash_table_lookup(g_workflow_list, name);
}
-void load_workflow_config_data(const char* path)
+GHashTable *load_workflow_config_data(const char* path)
{
+ if (g_workflow_list)
+ return g_workflow_list;
+
if (g_workflow_list == NULL)
{
g_workflow_list = g_hash_table_new_full(
@@ -104,6 +111,8 @@ void load_workflow_config_data(const char* path)
workflow_files = g_list_next(workflow_files);
}
free_file_list(workflow_files);
+
+ return g_workflow_list;
}
config_item_info_t *workflow_get_config_info(workflow_t *w)
--
1.8.0.1
11 years, 6 months
[LIBREPORT PATCH] reflect recent libreport API changes .trac#822
by Jiri Moskovcak
---
src/gui-gtk/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c
index 75ef8a1..5179b6b 100644
--- a/src/gui-gtk/main.c
+++ b/src/gui-gtk/main.c
@@ -799,7 +799,7 @@ static void on_menu_about_cb(GtkMenuItem *menuitem, gpointer unused)
static void show_events_list_dialog_cb(GtkMenuItem *menuitem, gpointer user_data)
{
- show_events_list_dialog(GTK_WINDOW(g_main_window));
+ show_config_list_dialog(GTK_WINDOW(g_main_window));
}
static void add_columns(GtkTreeView *treeview)
--
1.8.0.1
11 years, 6 months
[ABRT PATCH] Destkop Session Autoreporting
by Jakub Filak
Desktop Session Autoreporting is in a state when it could be merged into the
main branch.
Key features:
* autoreporting can be configured in /etc/abrt/abrt.conf
* a user can ovveride that configuration by abrt-applet's configuration
* in case of no system configuration, ureports are automatically send once user Starts Autoreporting
* deffered problem processing if network is unavailable
* no keyring unlock dialogue if no ureport configuration saved
Jakub Filak (1):
desktop session autoreporting
abrt.spec.in | 1 +
configure.ac | 1 +
src/applet/Makefile.am | 3 +
src/applet/applet.c | 789 ++++++++++++++++++++++++++++++++++--------
src/daemon/abrt.conf | 4 +
src/include/libabrt.h | 2 +
src/lib/abrt_conf.c | 8 +
src/plugins/ccpp_event.conf | 3 +
src/plugins/koops_event.conf | 3 +
src/plugins/python_event.conf | 3 +
src/plugins/xorg_event.conf | 3 +
11 files changed, 684 insertions(+), 136 deletions(-)
--
1.7.11.7
11 years, 6 months
[Automatic Bug Reporting Tool - ABRT] #893: Libreport - unclear wording and dead links when used in Anaconda
by fedora-badges
#893: Libreport - unclear wording and dead links when used in Anaconda
-----------------------+------------------------------
Reporter: jjr | Owner: crash-catcher@…
Type: defect | Status: new
Priority: major | Milestone: Fedora18
Component: libreport | Version:
Keywords: | Blocked By:
Blocking: |
-----------------------+------------------------------
I've encountered the following issues while documenting the traceback
reporting procedure for the Installation Guide in Fedora 18 Beta, which
now runs with libreport:
- when 'Report Bug' is selected, the first screen reads: "Wrong setting
detected for Bugzilla" and presents a 'Configure Bugzilla' button. This
implies that there is somehow a way for Bugzilla settings to have been
provided, when this is not possible during a fresh installation. Could
something along the lines of "No Bugzilla settings detected" be displayed
instead to avoid confusion? I understand that this wording may be
essential for other deployments of libreport though.
- in the 'Wrong settings detected for Bugzilla' dialog, there is a
hyperlink called "Read more about this configuration". Clicking it doesn't
produce anything in Anaconda. Jakub Filak tells me this should open a
browser, but because this is (I believe) not possible in Anaconda, the
link is essentially dead. Can it somehow be removed in Anaconda or an
informational dialog be generated?
- in the Bugzilla configuration dialog that follows, there is a hyperlink
"here" in the text "You can create bugzilla.redhat.com account here." This
also doesn't produce anything because Anaconda doesn't or can't open a
browser. Unless there is somehow a way to open Bugzilla in Anaconda, it
would be better to at least provide pop-up information that, when lacking
Internet access, the user will need to create an account on another system
and then return to complete the reporting procedure. If not, can this text
be removed from libreport in Anaconda?
--
Ticket URL: <https://fedorahosted.org/abrt/ticket/893>
Automatic Bug Reporting Tool - ABRT <http://fedorahoted.org/abrt/>
Automatic bug reporting tool
11 years, 6 months
[LIBREPORT PATCH 1/2] - implemented saving/loading configuratio for workflows - related to trac#822
by Jiri Moskovcak
- configuration is shared with the events, so changes in events
are reflected in workflow and vice versa
---
src/gtk-helpers/config_dialog.c | 262 ++++++++++++++++++++++++-------
src/gtk-helpers/event_config_dialog.c | 158 +++++++------------
src/gtk-helpers/internal_libreport_gtk.h | 39 +++--
src/gtk-helpers/workflow_config_dialog.c | 83 +++++-----
src/gui-wizard-gtk/main.c | 2 +-
src/gui-wizard-gtk/wizard.c | 8 +-
src/include/event_config.h | 4 +-
src/include/internal_libreport.h | 2 +-
src/lib/event_config.c | 13 +-
src/lib/workflow.c | 17 +-
10 files changed, 367 insertions(+), 221 deletions(-)
diff --git a/src/gtk-helpers/config_dialog.c b/src/gtk-helpers/config_dialog.c
index 88d01ae..3c81d7c 100644
--- a/src/gtk-helpers/config_dialog.c
+++ b/src/gtk-helpers/config_dialog.c
@@ -34,19 +34,55 @@ enum
TYPE_POINTER
};
+struct config_dialog
+{
+ GtkWidget *dialog;
+ gpointer *data;
+ config_save_fun_t save_data;
+};
+
GtkListStore *new_conf_liststore(void)
{
/* Create data store for the list and attach it
- * COLUMN_EVENT_UINAME -> name+description
- * COLUMN_EVENT_NAME -> event name so we can retrieve it from the row
+ * COLUMN_UINAME -> name+description
+ * COLUMN_NAME -> config name so we can retrieve it from the row
*/
return gtk_list_store_new(NUM_COLUMNS,
G_TYPE_STRING, /* Event name + description */
G_TYPE_STRING, /* event name */
- G_TYPE_POINTER
+ G_TYPE_POINTER, /* dialog */
+ G_TYPE_POINTER /* option_list */
);
}
+
+config_dialog_t *new_config_dialog(GtkWidget *dialog,
+ gpointer config_data,
+ config_save_fun_t save_fun)
+{
+ config_dialog_t *cdialog = (config_dialog_t *)xmalloc(sizeof(*cdialog));
+ cdialog->dialog = dialog;
+ cdialog->data = config_data;
+ cdialog->save_data = save_fun;
+ return cdialog;
+}
+
+void cdialog_set_widget(config_dialog_t *cdialog, GtkWidget *widget)
+{
+ //TODO destroy(cdialog-dialog) ??
+ cdialog->dialog = widget;
+}
+
+GtkWidget *cdialog_get_widget(config_dialog_t *cdialog)
+{
+ return cdialog->dialog;
+}
+
+gpointer cdialog_get_data(config_dialog_t *cdialog)
+{
+ return cdialog->data;
+}
+
static const void *get_column_value_from_row(GtkTreeView *treeview, int column, int type)
{
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
@@ -71,40 +107,39 @@ static const void *get_column_value_from_row(GtkTreeView *treeview, int column,
return retval;
}
-static void on_row_changed_cb(GtkTreeView *treeview, gpointer user_data)
+static void save_value_from_widget(gpointer data, gpointer user_data)
{
- VERB1 log("activated row: '%s'", (const char*)get_column_value_from_row(treeview, COLUMN_NAME, TYPE_STR));
+ option_widget_t *ow = (option_widget_t *)data;
- const void *dialog = get_column_value_from_row(treeview, CONFIG_DIALOG, TYPE_POINTER);
- gtk_widget_set_sensitive(GTK_WIDGET(user_data), dialog != NULL);
-}
-
-static void on_configure_button_cb(GtkWidget *button, gpointer user_data)
-{
- GtkTreeView *tv = (GtkTreeView *)user_data;
- const void * dialog = get_column_value_from_row(tv, CONFIG_DIALOG, TYPE_POINTER);
-
- if (dialog != NULL)
+ const char *val = NULL;
+ switch (ow->option->eo_type)
{
- int result = gtk_dialog_run(GTK_DIALOG(dialog));
- if (result == GTK_RESPONSE_APPLY)
- {
- //TODO: saving!!!
- g_print("apply\n");
- }
- //else if (result == GTK_RESPONSE_CANCEL)
- // log("log");
- gtk_widget_hide(GTK_WIDGET(dialog));
+ case OPTION_TYPE_TEXT:
+ case OPTION_TYPE_NUMBER:
+ case OPTION_TYPE_PASSWORD:
+ val = (char *)gtk_entry_get_text(GTK_ENTRY(ow->widget));
+ break;
+ case OPTION_TYPE_BOOL:
+ val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ow->widget)) ? "yes" : "no";
+ break;
+ default:
+ log("unsupported option type");
+ }
+ if (val)
+ {
+ free(ow->option->eo_value);
+ ow->option->eo_value = xstrdup(val);
+ VERB1 log("saved: %s:%s", ow->option->eo_name, ow->option->eo_value);
}
}
-static void on_close_list_cb(GtkWidget *button, gpointer user_data)
+void dehydrate_config_dialog(GList *option_widgets)
{
- GtkWidget *window = (GtkWidget *)user_data;
- gtk_widget_destroy(window);
+ if (option_widgets != NULL)
+ g_list_foreach(option_widgets, &save_value_from_widget, NULL);
}
-void add_item_to_config_liststore(gpointer dialog, gpointer inf, gpointer user_data)
+void add_item_to_config_liststore(gpointer cdialog, gpointer inf, gpointer user_data)
{
GtkListStore *list_store = (GtkListStore *)user_data;
config_item_info_t *info = (config_item_info_t *)inf;
@@ -115,24 +150,20 @@ void add_item_to_config_liststore(gpointer dialog, gpointer inf, gpointer user_d
label = xasprintf("<b>%s</b>\n%s",ci_get_screen_name(info), ci_get_description(info));
else
//if event has no xml description
- label = xasprintf("<b>%s</b>\nNo description available", ci_get_name(info));
+ label = xasprintf("<b>%s</b>\n%s", _("No description available"), ci_get_name(info));
GtkTreeIter iter;
gtk_list_store_append(list_store, &iter);
gtk_list_store_set(list_store, &iter,
COLUMN_UINAME, label,
COLUMN_NAME, ci_get_name(info),
- CONFIG_DIALOG, dialog,
+ CONFIG_DIALOG, cdialog,
-1);
free(label);
}
-GtkWidget *create_config_list_dialog(const char *column_label,
- GHashTable *items,
- GtkWindow *dialog,
- GHFunc item_to_config_info,
- GCallback on_config_cb,
- GCallback on_row_change)
+GtkWidget *create_config_tab_content(const char *column_label,
+ GtkListStore *store)
{
GtkWidget *main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL);
@@ -161,37 +192,148 @@ GtkWidget *create_config_list_dialog(const char *column_label,
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tv), TRUE);
// TODO: gtk_tree_view_set_headers_visible(FALSE)? We have only one column anyway...
- /* Create data store for the list and attach it
- * COLUMN_UINAME -> name+description
- * COLUMN_NAME -> workflow name so we can retrieve it from the row
- */
- GtkListStore *list_store = new_conf_liststore();
- gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(list_store));
+ gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(store));
+ gtk_container_add(GTK_CONTAINER(scroll), tv);
- g_hash_table_foreach(items,
- item_to_config_info,
- list_store);
-//TODO: can unref workflows_list_store? treeview holds one ref.
+ gtk_box_pack_start(GTK_BOX(main_vbox), scroll, true, true, 10);
+ return main_vbox;
+}
- /* Double click/Enter handler */
- //g_signal_connect(workflows_tv, "row-activated", G_CALLBACK(on_workflow_row_activated_cb), NULL);
+static void add_config_tabs(const char *name, GtkListStore *store, gpointer nb)
+{
+ GtkNotebook *ntb = (GtkNotebook *)nb;
- gtk_container_add(GTK_CONTAINER(scroll), tv);
+ GtkWidget *config_list_vbox = create_config_tab_content(
+ name,
+ store);
- GtkWidget *configure_btn = gtk_button_new_with_mnemonic(_("C_onfigure"));
- gtk_widget_set_sensitive(configure_btn, false);
- g_signal_connect(configure_btn, "clicked", G_CALLBACK(on_configure_button_cb), tv);
- g_signal_connect(tv, "cursor-changed", G_CALLBACK(on_row_changed_cb), configure_btn);
+ gtk_notebook_append_page(ntb, config_list_vbox, gtk_label_new(name));
+}
+
+static void on_configure_cb(GtkWidget *btn, gpointer user_data)
+{
+ GtkNotebook *nb = (GtkNotebook *)user_data;
+
+ guint current_page_n = gtk_notebook_get_current_page(nb);
+ GtkWidget *vbox = gtk_notebook_get_nth_page(nb, current_page_n);
+ GList *children = gtk_container_get_children(GTK_CONTAINER(vbox));
+ GtkScrolledWindow *sw = (GtkScrolledWindow *)children->data;
+ GtkTreeView *tv = (GtkTreeView *)gtk_bin_get_child(GTK_BIN(sw));
+ config_dialog_t *cdialog = (config_dialog_t *)get_column_value_from_row(tv, CONFIG_DIALOG, TYPE_POINTER);
+ const char *name = (const char *)get_column_value_from_row(tv, COLUMN_NAME, TYPE_STR);
+
+ if (cdialog == NULL || cdialog->dialog == NULL)
+ {
+ log("There is no configurable option for: '%s'", name);
+ return;
+ }
+
+ int result = gtk_dialog_run(GTK_DIALOG(cdialog->dialog));
+ if (result == GTK_RESPONSE_APPLY)
+ {
+ if (cdialog->save_data)
+ cdialog->save_data(cdialog->data, name);
+ }
+ else if (result == GTK_RESPONSE_CANCEL)
+ VERB1 log("Cancelling on user request");
+
+ gtk_widget_hide(GTK_WIDGET(cdialog->dialog));
+}
+
+static void on_close_cb(GtkWidget *btn, gpointer config_list_w)
+{
+ GtkWidget *w = (GtkWidget *)config_list_w;
+ gtk_widget_hide(w);
+}
+
+GtkWindow *create_config_list_window(GHashTable *configs, GtkWindow *parent)
+{
+
+ // config window
+ GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_container_set_border_width(GTK_CONTAINER(window), 5);
+ gtk_window_set_title(GTK_WINDOW(window), _("Configuration"));
+ gtk_window_set_default_size(GTK_WINDOW(window), 450, 400);
+ gtk_window_set_position(GTK_WINDOW(window), parent
+ ? GTK_WIN_POS_CENTER_ON_PARENT
+ : GTK_WIN_POS_CENTER);
+
+ if (parent != NULL)
+ {
+ gtk_window_set_modal(GTK_WINDOW(window), true);
+ gtk_window_set_transient_for(GTK_WINDOW(window), parent);
+ }
+
+ //g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+
+ GtkWidget *main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
+ GtkWidget *config_nb = gtk_notebook_new();
+ gtk_box_pack_start(GTK_BOX(main_vbox), config_nb, 1, 1, 0);
+
+ /* we can't use this, because we want the workflows first and hashtable
+ * doesn't return the items in the order they were added
+ */
+ //g_hash_table_foreach(configs, (GHFunc)add_config_tabs, config_nb);
+
+ gpointer config = g_hash_table_lookup(configs, _("Workflows"));
+ if (config != NULL);
+ add_config_tabs(_("Workflows"), config, config_nb);
+
+ config = g_hash_table_lookup(configs, _("Events"));
+ if (config != NULL);
+ add_config_tabs(_("Events"), config, config_nb);
+
+ //buttons
+ GtkWidget *btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,5);
+ GtkWidget *configure_btn = gtk_button_new_with_mnemonic(_("C_onfigure"));
+ GtkWidget *align = gtk_alignment_new(0, 0, 0, 0);
GtkWidget *close_btn = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
- g_signal_connect(close_btn, "clicked", G_CALLBACK(on_close_list_cb), dialog);
+ GtkSizeGroup *sg = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
+ //force apply and close to have the same size
+ gtk_size_group_add_widget(sg, close_btn);
+ gtk_size_group_add_widget(sg, configure_btn);
- GtkWidget *btnbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
- gtk_box_pack_end(GTK_BOX(btnbox), close_btn, false, false, 0);
- gtk_box_pack_end(GTK_BOX(btnbox), configure_btn, false, false, 0);
+ g_signal_connect(configure_btn, "clicked", (GCallback)on_configure_cb, config_nb);
+ g_signal_connect(close_btn, "clicked", (GCallback)on_close_cb, window);
- gtk_box_pack_start(GTK_BOX(main_vbox), scroll, true, true, 10);
- gtk_box_pack_start(GTK_BOX(main_vbox), btnbox, false, false, 0);
+ gtk_box_pack_start(GTK_BOX(btn_box), close_btn, 0, 0, 5);
+ gtk_box_pack_start(GTK_BOX(btn_box), align, true, true, 5);
+ gtk_box_pack_start(GTK_BOX(btn_box), configure_btn, 0, 0, 5);
- return main_vbox;
+
+ gtk_box_pack_start(GTK_BOX(main_vbox), btn_box, 0, 0, 0);
+ gtk_container_add(GTK_CONTAINER(window), main_vbox);
+
+ //gtk_widget_show_all(window);
+ return GTK_WINDOW(window);
+}
+
+/* Name | vbox with the gtk_Tree
+ * <String name, GtkWidget *vbox>
+*/
+
+void show_config_list_dialog(GtkWindow *parent)
+{
+ GHashTable *confs = g_hash_table_new_full(
+ /*hash_func*/ g_str_hash,
+ /*key_equal_func:*/ g_str_equal,
+ /*key_destroy_func:*/ g_free,
+ /*value_destroy_func:*/ NULL);
+
+
+ //TODO: free the hashtables somewhere!!
+ GHashTable *events = load_event_config_data();
+ load_event_config_data_from_user_storage(events);
+
+ GHashTable *workflows = load_workflow_config_data(WORKFLOWS_DIR);
+ load_workflow_config_data_from_user_storage(workflows);
+ GtkListStore *workflows_store = add_workflows_to_liststore(workflows);
+ g_hash_table_insert(confs, _("Workflows"), workflows_store);
+
+ GtkListStore *events_store = add_events_to_liststore(events);
+ g_hash_table_insert(confs, _("Events"), events_store);
+
+ GtkWindow *window = create_config_list_window(confs, parent);
+ gtk_widget_show_all(GTK_WIDGET(window));
}
diff --git a/src/gtk-helpers/event_config_dialog.c b/src/gtk-helpers/event_config_dialog.c
index 01527ec..82d07df 100644
--- a/src/gtk-helpers/event_config_dialog.c
+++ b/src/gtk-helpers/event_config_dialog.c
@@ -20,7 +20,8 @@
#include "internal_libreport_gtk.h"
static GtkWindow *g_event_list_window;
-static GList *option_widget_list;
+static GList *g_option_list = NULL;
+
static bool has_password_option;
enum
@@ -30,14 +31,6 @@ enum
NUM_COLUMNS
};
-typedef struct
-{
- event_option_t *option;
- GtkWidget *widget;
-} option_widget_t;
-
-int show_event_config_dialog(const char *event_name, GtkWindow *parent);
-
static GtkWidget *gtk_label_new_justify_left(const gchar *label_str)
{
GtkWidget *label = gtk_label_new(label_str);
@@ -48,12 +41,14 @@ static GtkWidget *gtk_label_new_justify_left(const gchar *label_str)
return label;
}
-static void add_option_widget(GtkWidget *widget, event_option_t *option)
+GList *add_option_widget(GList *options, GtkWidget *widget, event_option_t *option)
{
- option_widget_t *ow = (option_widget_t *)xmalloc(sizeof(option_widget_t));
+ option_widget_t *ow = (option_widget_t *)xmalloc(sizeof(*ow));
ow->widget = widget;
ow->option = option;
- option_widget_list = g_list_prepend(option_widget_list, ow);
+ options = g_list_prepend(options, ow);
+
+ return options;
}
static void on_show_pass_cb(GtkToggleButton *tb, gpointer user_data)
@@ -75,6 +70,23 @@ static unsigned add_one_row_to_grid(GtkGrid *table)
return rows;
}
+void save_data_from_event_config_dialog(GList *widgets, event_config_t *ec)
+{
+ dehydrate_config_dialog(widgets);
+ const char *const store_passwords_s = get_user_setting("store_passwords");
+ save_event_config_data_to_user_storage(ec_get_name(ec),
+ ec,
+ !(store_passwords_s && !strcmp(store_passwords_s, "no")));
+}
+
+static void save_data_from_event_dialog_name(GList *widgets, const char *name)
+{
+ event_config_t *ec = get_event_config(name);
+
+ save_data_from_event_config_dialog(widgets, ec);
+}
+
+
static void add_option_to_table(gpointer data, gpointer user_data)
{
event_option_t *option = data;
@@ -116,7 +128,7 @@ static void add_option_to_table(gpointer data, gpointer user_data)
gtk_grid_attach(option_table, option_input,
/*left,top:*/ 1, last_row,
/*width,height:*/ 1, 1);
- add_option_widget(option_input, option);
+ g_option_list = add_option_widget(g_option_list, option_input, option);
if (option->eo_type == OPTION_TYPE_PASSWORD)
{
gtk_entry_set_visibility(GTK_ENTRY(option_input), 0);
@@ -151,7 +163,7 @@ static void add_option_to_table(gpointer data, gpointer user_data)
if (option->eo_value != NULL)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(option_input),
string_to_bool(option->eo_value));
- add_option_widget(option_input, option);
+ g_option_list = add_option_widget(g_option_list, option_input, option);
break;
default:
@@ -177,39 +189,7 @@ static void add_option_to_table(gpointer data, gpointer user_data)
free(option_label);
}
-static void save_value_from_widget(gpointer data, gpointer user_data)
-{
- option_widget_t *ow = (option_widget_t *)data;
-
- const char *val = NULL;
- switch (ow->option->eo_type)
- {
- case OPTION_TYPE_TEXT:
- case OPTION_TYPE_NUMBER:
- case OPTION_TYPE_PASSWORD:
- val = (char *)gtk_entry_get_text(GTK_ENTRY(ow->widget));
- break;
- case OPTION_TYPE_BOOL:
- val = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ow->widget)) ? "yes" : "no";
- break;
- default:
- log("unsupported option type");
- }
- if (val)
- {
- free(ow->option->eo_value);
- ow->option->eo_value = xstrdup(val);
- VERB1 log("saved: %s:%s", ow->option->eo_name, ow->option->eo_value);
- }
-}
-
-static void dehydrate_config_dialog()
-{
- if (option_widget_list != NULL)
- g_list_foreach(option_widget_list, &save_value_from_widget, NULL);
-}
-
-GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *content)
+config_dialog_t *create_event_config_dialog_content(event_config_t *event, GtkWidget *content)
{
if (content == NULL)
content = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
@@ -238,6 +218,13 @@ GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *
g_object_set_data(G_OBJECT(option_table), "advanced-options", adv_option_table);
has_password_option = false;
+ /* it's already stored in config_dialog_t from the previous call
+ * we need to set it to null so we create a new list for the actual
+ * event_config
+ * note: say *NO* to the global variables!
+ */
+ g_option_list = NULL;
+ /* this fills the g_option_list, so we can use it for new_config_dialog */
g_list_foreach(event->options, &add_option_to_table, option_table);
/* if there is at least one password option, add checkbox to disable storing passwords */
@@ -275,17 +262,17 @@ GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *
gtk_widget_show_all(content); //make it all visible
- return content;
+ //g_option_list is filled on
+ config_dialog_t *cdialog = new_config_dialog(NULL,
+ g_option_list,
+ (config_save_fun_t)save_data_from_event_dialog_name
+ );
+
+ return cdialog;
}
-GtkWidget *create_config_dialog(const char *event_name, GtkWindow *parent)
+config_dialog_t *create_event_config_dialog(const char *event_name, GtkWindow *parent)
{
- if (option_widget_list != NULL)
- {
- g_list_free(option_widget_list);
- option_widget_list = NULL;
- }
-
event_config_t *event = get_event_config(event_name);
if(!ec_is_configurable(event))
@@ -320,26 +307,30 @@ GtkWidget *create_config_dialog(const char *event_name, GtkWindow *parent)
}
GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- content = create_event_config_dialog_content(event, content);
+ config_dialog_t *cdialog = create_event_config_dialog_content(event, content);
+ cdialog_set_widget(cdialog, dialog);
- return dialog;
+ return cdialog;
}
-static void add_event_to_liststore(gpointer key, gpointer value, gpointer user_data)
+static void add_event_to_liststore(gpointer key, gpointer value, gpointer list_store)
{
config_item_info_t *info = ec_get_config_info((event_config_t *)value);
- GtkWidget *dialog = create_config_dialog(key, NULL);
- add_item_to_config_liststore(dialog, info, user_data);
+ config_dialog_t *cdialog = create_event_config_dialog(key, NULL);
+
+ add_item_to_config_liststore(cdialog, info, list_store);
}
-int show_event_config_dialog(const char *event_name, GtkWindow *parent)
+GtkListStore *add_events_to_liststore(GHashTable *events)
{
- if (option_widget_list != NULL)
- {
- g_list_free(option_widget_list);
- option_widget_list = NULL;
- }
+ GtkListStore *list_store = new_conf_liststore();
+ g_hash_table_foreach(events, (GHFunc)add_event_to_liststore, list_store);
+
+ return list_store;
+}
+int show_event_config_dialog(const char *event_name, GtkWindow *parent)
+{
event_config_t *event = get_event_config(event_name);
GtkWindow *parent_window = parent ? parent : g_event_list_window;
@@ -371,14 +362,14 @@ int show_event_config_dialog(const char *event_name, GtkWindow *parent)
}
GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- content = create_event_config_dialog_content(event, content);
+ content = cdialog_get_widget(create_event_config_dialog_content(event, content));
gtk_widget_show_all(content);
int result = gtk_dialog_run(GTK_DIALOG(dialog));
if (result == GTK_RESPONSE_APPLY)
{
- dehydrate_config_dialog();
+ dehydrate_config_dialog(g_option_list);
const char *const store_passwords_s = get_user_setting("store_passwords");
save_event_config_data_to_user_storage(event_name,
get_event_config(event_name),
@@ -390,34 +381,3 @@ int show_event_config_dialog(const char *event_name, GtkWindow *parent)
return result;
}
-void show_events_list_dialog(GtkWindow *parent)
-{
- /*remove this line if we want to reload the config
- *everytime we show the config dialog
- */
- if (g_event_config_list == NULL)
- {
- load_event_config_data();
- load_event_config_data_from_user_storage(g_event_config_list);
- }
-
- GtkWidget *event_list_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- g_event_list_window = (GtkWindow*)event_list_window;
- gtk_window_set_title(g_event_list_window, _("Event Configuration"));
- gtk_window_set_default_size(g_event_list_window, 450, 400);
- gtk_window_set_position(g_event_list_window, parent ? GTK_WIN_POS_CENTER_ON_PARENT : GTK_WIN_POS_CENTER);
- if (parent != NULL)
- {
- gtk_window_set_transient_for(g_event_list_window, parent);
- // modal = parent window can't steal focus
- gtk_window_set_modal(g_event_list_window, true);
- gtk_window_set_icon_name(g_event_list_window,
- gtk_window_get_icon_name(parent));
- }
-
- GtkWidget *main_vbox = create_config_list_dialog(_("Event"), g_event_config_list, GTK_WINDOW(event_list_window), &add_event_to_liststore, NULL, NULL);
-
- gtk_container_add(GTK_CONTAINER(event_list_window), main_vbox);
-
- gtk_widget_show_all(event_list_window);
-}
diff --git a/src/gtk-helpers/internal_libreport_gtk.h b/src/gtk-helpers/internal_libreport_gtk.h
index 5e631cb..c59158e 100644
--- a/src/gtk-helpers/internal_libreport_gtk.h
+++ b/src/gtk-helpers/internal_libreport_gtk.h
@@ -27,6 +27,15 @@
extern "C" {
#endif
+typedef struct config_dialog config_dialog_t;
+typedef void (* config_save_fun_t)(gpointer data, const char *event_name);
+
+typedef struct
+{
+ event_option_t *option;
+ GtkWidget *widget;
+} option_widget_t;
+
#define make_label_autowrap_on_resize libreport_make_label_autowrap_on_resize
void make_label_autowrap_on_resize(GtkLabel *label);
@@ -51,22 +60,28 @@ void save_event_config_data_to_user_storage(const char *event_name,
int show_event_config_dialog(const char *event_name, GtkWindow *parent);
#define create_event_config_dialog_content libreport_create_event_config_dialog_content
-GtkWidget *create_event_config_dialog_content(event_config_t *event, GtkWidget *content);
+config_dialog_t *create_event_config_dialog_content(event_config_t *event, GtkWidget *content);
+
+//#define show_workflow_list_dialog libreport_show_workflow_list_dialog
+//void show_workflow_list_dialog(GtkWindow *parent);
-#define show_workflow_list_dialog libreport_show_workflow_list_dialog
-void show_workflow_list_dialog(GtkWindow *parent);
+void save_data_from_event_config_dialog(GList *widgets, event_config_t *ec);
#define add_item_to_config_liststore libreport_add_item_to_config_liststore
-void add_item_to_config_liststore(gpointer key, gpointer value, gpointer user_data);
-
-#define create_config_list_dialog libreport_create_config_list_dialog
-GtkWidget *create_config_list_dialog(const char *column_label,
- GHashTable *items,
- GtkWindow *dialog,
- GHFunc item_to_config_info,
- GCallback on_config_cb,
- GCallback on_row_change);
+void add_item_to_config_liststore(gpointer cdialog, gpointer inf, gpointer user_data);
+
GtkListStore *new_conf_liststore(void);
+void show_config_list_dialog(GtkWindow *parent);
+GtkListStore *add_events_to_liststore(GHashTable *events);
+GtkListStore *add_workflows_to_liststore(GHashTable *workflows);
+config_dialog_t *new_config_dialog(GtkWidget *dialog, gpointer config_data, config_save_fun_t save_fun);
+void load_workflow_config_data_from_user_storage(GHashTable *workflows);
+
+void cdialog_set_widget(config_dialog_t *cdialog, GtkWidget *widget);
+GtkWidget *cdialog_get_widget(config_dialog_t *cdialog);
+gpointer cdialog_get_data(config_dialog_t *cdialog);
+
+void dehydrate_config_dialog(GList *option_widgets);
char * tag_url(const char* line, const char* prefix);
diff --git a/src/gtk-helpers/workflow_config_dialog.c b/src/gtk-helpers/workflow_config_dialog.c
index de10134..93dd622 100644
--- a/src/gtk-helpers/workflow_config_dialog.c
+++ b/src/gtk-helpers/workflow_config_dialog.c
@@ -27,13 +27,42 @@ enum
};
static GtkWindow *g_parent_window;
+static GHashTable *g_events_options = NULL;
static void create_event_config_dialog_content_cb(event_config_t *ec, gpointer content)
{
- create_event_config_dialog_content(ec, (GtkWidget *)content);
+ if (ec->options)
+ {
+ GtkWidget *ev_lbl = gtk_label_new(ec_get_screen_name(ec));
+ gtk_box_pack_start(GTK_BOX(content), ev_lbl, false, false, 0);
+ }
+
+ config_dialog_t *cdialog = create_event_config_dialog_content(ec, (GtkWidget *)content);
+ if (g_events_options == NULL)
+ {
+ g_events_options = g_hash_table_new_full(
+ /*hash_func*/ g_str_hash,
+ /*key_equal_func:*/ g_str_equal,
+ /*key_destroy_func:*/ g_free,
+ /*value_destroy_func:*/ NULL);
+ }
+ g_hash_table_insert(g_events_options, ec, cdialog);
+
}
-GtkWidget *create_workflow_config_dialog(const char *workflow_name, GtkWindow *parent)
+static void save_event_config_data_foreach(event_config_t *ec,
+ config_dialog_t *cdialog,
+ gpointer user_data)
+{
+ save_data_from_event_config_dialog(cdialog_get_data(cdialog), ec);
+}
+
+void save_data_from_worfklow_dialog(gpointer data, /* not needed */ const char *name)
+{
+ g_hash_table_foreach((GHashTable *)data, (GHFunc)save_event_config_data_foreach, NULL);
+}
+
+config_dialog_t *create_workflow_config_dialog(const char *workflow_name, GtkWindow *parent)
{
workflow_t *workflow = get_workflow(workflow_name);
GList *events = wf_get_event_list(workflow);
@@ -61,16 +90,28 @@ GtkWidget *create_workflow_config_dialog(const char *workflow_name, GtkWindow *p
GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ g_events_options = NULL;
g_list_foreach(events, (GFunc)create_event_config_dialog_content_cb, content);
- return dialog;
+ config_dialog_t *cdialog = new_config_dialog(dialog,
+ g_events_options,
+ (config_save_fun_t)save_data_from_worfklow_dialog);
+ return cdialog;
}
static void add_workflow_to_liststore(gpointer key, gpointer value, gpointer user_data)
{
config_item_info_t *info = workflow_get_config_info((workflow_t *)value);
- GtkWidget *dialog = create_workflow_config_dialog(key, g_parent_window);
- add_item_to_config_liststore(dialog, info, user_data);
+ config_dialog_t *cdialog = create_workflow_config_dialog(key, g_parent_window);
+ add_item_to_config_liststore(cdialog, info, user_data);
+}
+
+GtkListStore *add_workflows_to_liststore(GHashTable *workflows)
+{
+ GtkListStore *list_store = new_conf_liststore();
+ g_hash_table_foreach(workflows, (GHFunc)add_workflow_to_liststore, list_store);
+
+ return list_store;
}
static void load_single_event_config_foreach(event_config_t *ec, gpointer user_data)
@@ -83,35 +124,7 @@ static void load_events_foreach_workflow(const char *name, workflow_t *workflow,
g_list_foreach(wf_get_event_list(workflow), (GFunc)load_single_event_config_foreach, NULL);
}
-void show_workflow_list_dialog(GtkWindow *parent)
+void load_workflow_config_data_from_user_storage(GHashTable *workflows)
{
- g_parent_window = parent;
- //g_verbose = 3;
- if (g_workflow_list == NULL)
- {
- VERB1 log("workflow list is empty - reloading");
- load_workflow_config_data(WORKFLOWS_DIR);
- }
-
- g_hash_table_foreach(g_workflow_list, (GHFunc)load_events_foreach_workflow, NULL);
-
- GtkWindow *workflow_list_window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
- gtk_window_set_title(workflow_list_window, _("Workflow Configuration"));
- gtk_window_set_default_size(workflow_list_window, 450, 400);
- gtk_window_set_position(workflow_list_window, parent ? GTK_WIN_POS_CENTER_ON_PARENT : GTK_WIN_POS_CENTER);
- if (parent != NULL)
- {
- gtk_window_set_transient_for(workflow_list_window, parent);
- // modal = parent window can't steal focus
- gtk_window_set_modal(workflow_list_window, true);
- gtk_window_set_icon_name(workflow_list_window,
- gtk_window_get_icon_name(parent));
- }
-
- GtkWidget *main_vbox = create_config_list_dialog(_("Workflow"), g_workflow_list, workflow_list_window, add_workflow_to_liststore, NULL, NULL);
-
- gtk_container_add(GTK_CONTAINER(workflow_list_window), main_vbox);
-
- gtk_widget_show_all(GTK_WIDGET(workflow_list_window));
-
+ g_hash_table_foreach(workflows, (GHFunc)load_events_foreach_workflow, NULL);
}
diff --git a/src/gui-wizard-gtk/main.c b/src/gui-wizard-gtk/main.c
index 03f8fd2..b47687b 100644
--- a/src/gui-wizard-gtk/main.c
+++ b/src/gui-wizard-gtk/main.c
@@ -140,7 +140,7 @@ int main(int argc, char **argv)
/* load /etc/abrt/events/foo.{conf,xml} stuff
and $XDG_CACHE_HOME/abrt/events/foo.conf */
- load_event_config_data();
+ g_event_config_list = load_event_config_data();
load_event_config_data_from_user_storage(g_event_config_list);
load_user_settings("report-gtk");
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index dae4e80..0abcbba 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -1522,9 +1522,6 @@ static bool is_processing_finished()
static void hide_next_step_button()
{
- if(gtk_widget_get_visible(GTK_WIDGET(g_btn_next)) == false)
- return
-
/* replace 'Forward' with 'Close' button */
/* 1. hide next button */
gtk_widget_hide(g_btn_next);
@@ -1534,9 +1531,6 @@ static void hide_next_step_button()
static void show_next_step_button()
{
- if(gtk_widget_get_visible(GTK_WIDGET(g_btn_next)) == true)
- return
-
gtk_box_reorder_child(g_box_buttons, g_btn_close, 0);
gtk_widget_show(g_btn_next);
}
@@ -2044,7 +2038,7 @@ static void on_no_comment_toggled(GtkToggleButton *togglebutton, gpointer user_d
static void on_show_event_list_cb(GtkWidget *button, gpointer user_data)
{
- show_events_list_dialog(GTK_WINDOW(g_wnd_assistant));
+ show_config_list_dialog(GTK_WINDOW(g_wnd_assistant));
}
#if 0
diff --git a/src/include/event_config.h b/src/include/event_config.h
index 68463d3..24e1eac 100644
--- a/src/include/event_config.h
+++ b/src/include/event_config.h
@@ -103,12 +103,14 @@ void free_event_config(event_config_t *p);
void load_event_description_from_file(event_config_t *event_config, const char* filename);
// (Re)loads data from /etc/abrt/events/*.{conf,xml}
-void load_event_config_data(void);
+GHashTable *load_event_config_data(void);
/* Frees all loaded data */
void free_event_config_data(void);
event_config_t *get_event_config(const char *event_name);
event_option_t *get_event_option_from_list(const char *option_name, GList *event_options);
+/* for debugging */
+void ec_print(event_config_t *ec);
extern GHashTable *g_event_config_list; // for iterating through entire list of all loaded configs
diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
index 4f85b2a..88a1f25 100644
--- a/src/include/internal_libreport.h
+++ b/src/include/internal_libreport.h
@@ -644,7 +644,7 @@ file_obj_t *new_file_obj(const char* fullpath, const char* filename);
#define free_file_obj libreport_free_file_obj
void free_file_obj(file_obj_t *f);
#define load_workflow_config_data libreport_load_workflow_config_data
-void load_workflow_config_data(const char* path);
+GHashTable *load_workflow_config_data(const char* path);
/* Connect to abrtd over unix domain socket, issue DELETE command */
int delete_dump_dir_possibly_using_abrtd(const char *dump_dir_name);
diff --git a/src/lib/event_config.c b/src/lib/event_config.c
index e6ae269..88041ff 100644
--- a/src/lib/event_config.c
+++ b/src/lib/event_config.c
@@ -79,6 +79,15 @@ bool ec_is_configurable(event_config_t* ec)
return g_list_length(ec->options) > 0;
}
+void ec_print(event_config_t *ec)
+{
+ printf("%s\n\t%s\n\t%s\n",
+ ec_get_name(ec),
+ ec_get_screen_name(ec),
+ ec_get_description(ec)
+ );
+}
+
void free_event_option(event_option_t *p)
{
if (!p)
@@ -183,7 +192,7 @@ static void load_config_files(const char *dir_path)
}
/* (Re)loads data from /etc/abrt/events/foo.{xml,conf} and $XDG_CACHE_HOME/abrt/events/foo.conf */
-void load_event_config_data(void)
+GHashTable *load_event_config_data(void)
{
free_event_config_data();
@@ -227,6 +236,8 @@ void load_event_config_data(void)
cachedir = concat_path_file(g_get_user_cache_dir(), "abrt/events");
load_config_files(cachedir);
free(cachedir);
+
+ return g_event_config_list;
}
/* Frees all loaded data */
diff --git a/src/lib/workflow.c b/src/lib/workflow.c
index 1b92283..6fa2634 100644
--- a/src/lib/workflow.c
+++ b/src/lib/workflow.c
@@ -53,10 +53,14 @@ static void free_workflow_cb(const char *name, workflow_t *w, gpointer user_data
free_workflow(w);
}
-void free_workflow_list(GHashTable *wl)
+void free_workflow_list(GHashTable **wl)
{
- g_hash_table_foreach(wl, (GHFunc)free_workflow_cb, NULL);
- g_hash_table_destroy(wl);
+ if(*wl != NULL)
+ {
+ g_hash_table_foreach(*wl, (GHFunc)free_workflow_cb, NULL);
+ g_hash_table_destroy(*wl);
+ *wl = NULL;
+ }
}
workflow_t *get_workflow(const char *name)
@@ -74,8 +78,11 @@ workflow_t *get_workflow(const char *name)
return g_hash_table_lookup(g_workflow_list, name);
}
-void load_workflow_config_data(const char* path)
+GHashTable *load_workflow_config_data(const char* path)
{
+ if (g_workflow_list)
+ return g_workflow_list;
+
if (g_workflow_list == NULL)
{
g_workflow_list = g_hash_table_new_full(
@@ -104,6 +111,8 @@ void load_workflow_config_data(const char* path)
workflow_files = g_list_next(workflow_files);
}
free_file_list(workflow_files);
+
+ return g_workflow_list;
}
config_item_info_t *workflow_get_config_info(workflow_t *w)
--
1.8.0.1
11 years, 6 months