- configuration is shared with the events, so changes in events
are reflected in workflow and vice versa
---
src/gtk-helpers/config_dialog.c | 252 +++++++++++++++++++++++--------
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, 357 insertions(+), 221 deletions(-)
diff --git a/src/gtk-helpers/config_dialog.c b/src/gtk-helpers/config_dialog.c
index 88d01ae..7d60301 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;
+ ConfigSaveFun 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,
+ ConfigSaveFun 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)
-{
- VERB1 log("activated row: '%s'", (const
char*)get_column_value_from_row(treeview, COLUMN_NAME, TYPE_STR));
-
- 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)
+static void save_value_from_widget(gpointer data, gpointer user_data)
{
- GtkTreeView *tv = (GtkTreeView *)user_data;
- const void * dialog = get_column_value_from_row(tv, CONFIG_DIALOG, TYPE_POINTER);
+ option_widget_t *ow = (option_widget_t *)data;
- 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,138 @@ 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);
+
+ g_hash_table_foreach(configs, (GHFunc)add_config_tabs, 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);
+
+ GtkListStore *events_store = add_events_to_liststore(events);
+ g_hash_table_insert(confs, _("Events"), events_store);
+
+
+ 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);
+
+ 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..6bc85cd 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,
+ (ConfigSaveFun)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..516f98e 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 (* ConfigSaveFun)(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, ConfigSaveFun
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..90f2d49 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,
+ (ConfigSaveFun)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