libreport/0003-Worklflow-order-workflows-according-to-their-priorit.patch
2014-04-30 16:39:05 +02:00

263 lines
9.0 KiB
Diff

From 27a2c75409c7abae68c4ad3af99d8e90927af803 Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Mon, 28 Apr 2014 13:57:05 +0200
Subject: [LIBREPORT PATCH 03/10] Worklflow: order workflows according to their
priority
Higher number -> higher priority -> more visible place in UI
Introduce 'priority' element in XML workflow definition:
- child of 'workflow' element
- the type is signed integer
- optional value, if not present, 0 is used
Related to #259
Signed-off-by: Jakub Filak <jfilak@redhat.com>
mmilata: fix DTD in manual page
---
doc/report-gtk.txt | 8 +++++++-
src/cli/cli-report.c | 32 ++++++++++++++++++--------------
src/gui-wizard-gtk/wizard.c | 10 ++++++----
src/include/workflow.h | 10 ++++++++++
src/lib/workflow.c | 21 +++++++++++++++++++++
src/lib/workflow_xml_parser.c | 20 +++++++++++++++++++-
6 files changed, 81 insertions(+), 20 deletions(-)
diff --git a/doc/report-gtk.txt b/doc/report-gtk.txt
index e7611de..f39c77c 100644
--- a/doc/report-gtk.txt
+++ b/doc/report-gtk.txt
@@ -64,11 +64,12 @@ These configuration files are placed in /usr/share/libreport/workflows.
Each file has XML formatting with the following DTD:
------------
-<!ELEMENT workflow (name+,description+,events*)>
+<!ELEMENT workflow (name+,description+,priority?,events*)>
<!ELEMENT name (#PCDATA)>
<!ATTLIST name xml:lang CDATA #IMPLIED>
<!ELEMENT description (#PCDATA)>
<!ATTLIST description xml:lang CDATA #IMPLIED>
+<!ELEMENT priority = (#PCDATA)>
<!ELEMENT events = (event)+>
<!ELEMENT event = (#PCDATA)>
------------
@@ -79,6 +80,10 @@ name::
description::
User visible description
+priority::
+ Priority of the workflow. Higher number means a more visible place in UI.
+ If not provided, 0 is used. The value is signed integer.
+
events::
List of executed events
@@ -98,6 +103,7 @@ Simple reporting work flow
<name xml:lang="cs">Příklad</name>
<description xml:lang="en">Example description</description>
<description xml:lang="cs">Příklad popisu</description>
+ <priority>10</priority>
<evetns>
<event>analyze_example</event>
<event>collect_example</event>
diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c
index 68baa8b..9cc7613 100644
--- a/src/cli/cli-report.c
+++ b/src/cli/cli-report.c
@@ -824,32 +824,36 @@ int run_event_chain(const char *dump_dir_name, GList *chain, int interactive)
static workflow_t *select_workflow(GHashTable *workflows)
{
- GHashTableIter iter;
- gpointer key = NULL;
- workflow_t *value = NULL;
+ GList *wf_list = g_hash_table_get_values(workflows);
- g_hash_table_iter_init(&iter, workflows);
-
- if (!g_hash_table_iter_next(&iter, &key, (gpointer *)&value))
+ if (wf_list == NULL)
{
error_msg("No workflow suitable for this problem was found!");
return NULL;
}
- if (g_hash_table_size(workflows) == 1)
+ const guint wf_cnt = g_list_length(wf_list);
+ if (wf_cnt == 1)
{
- log_notice("autoselected workflow: '%s'", (char *)key);
- return value;
+ workflow_t *wf_selected = (workflow_t *)wf_list->data;
+ log_notice("autoselected workflow: '%s'", (char *)wf_get_name(wf_selected));
+ g_list_free(wf_list);
+ return wf_selected;
}
- workflow_t *help_wf_array[g_hash_table_size(workflows)];
+ wf_list = g_list_sort(wf_list, (GCompareFunc)wf_priority_compare);
+
+ workflow_t *help_wf_array[wf_cnt];
unsigned count = 0;
- do
+
+ for(GList *wf_iter = wf_list; wf_iter; wf_iter = g_list_next(wf_iter))
{
- help_wf_array[count] = value;
- printf("%d %s\n %s\n\n", ++count, wf_get_screen_name(value), wf_get_description(value));
+ workflow_t *wf = (workflow_t *)wf_iter->data;
+ help_wf_array[count] = wf;
+ printf("%d %s\n %s\n\n", ++count, wf_get_screen_name(wf), wf_get_description(wf));
}
- while (g_hash_table_iter_next(&iter, &key, (gpointer *)&value));
+
+ g_list_free(wf_list);
const unsigned picked = choose_number_from_range(1, count, _("Select a workflow to run: "));
return help_wf_array[picked - 1];
diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
index 82bdf3e..e6f6ee7 100644
--- a/src/gui-wizard-gtk/wizard.c
+++ b/src/gui-wizard-gtk/wizard.c
@@ -2736,10 +2736,12 @@ static void add_workflow_buttons(GtkBox *box, GHashTable *workflows, GCallback f
list_possible_events_glist(g_dump_dir_name, "workflow"),
WORKFLOWS_DIR);
- GList *keys = g_hash_table_get_keys(workflow_table);
- while(keys)
+ GList *wf_list = g_hash_table_get_values(workflow_table);
+ wf_list = g_list_sort(wf_list, (GCompareFunc)wf_priority_compare);
+
+ for (GList *wf_iter = wf_list; wf_iter; wf_iter = g_list_next(wf_iter))
{
- workflow_t *w = g_hash_table_lookup(workflow_table, keys->data);
+ workflow_t *w = (workflow_t *)wf_iter->data;
char *btn_label = xasprintf("<b>%s</b>\n%s", wf_get_screen_name(w), wf_get_description(w));
GtkWidget *button = gtk_button_new_with_label(btn_label);
GList *children = gtk_container_get_children(GTK_CONTAINER(button));
@@ -2756,9 +2758,9 @@ static void add_workflow_buttons(GtkBox *box, GHashTable *workflows, GCallback f
free(btn_label);
g_signal_connect(button, "clicked", func, w);
gtk_box_pack_start(box, button, true, false, 2);
- keys = g_list_next(keys);
}
+ g_list_free(wf_list);
}
static char *setup_next_processed_event(GList **events_list)
diff --git a/src/include/workflow.h b/src/include/workflow.h
index 66bbdaf..d79708e 100644
--- a/src/include/workflow.h
+++ b/src/include/workflow.h
@@ -39,11 +39,21 @@ GList *wf_get_event_names(workflow_t *w);
const char *wf_get_screen_name(workflow_t *w);
const char *wf_get_description(workflow_t *w);
const char *wf_get_long_desc(workflow_t *w);
+int wf_get_priority(workflow_t *w);
void wf_set_screen_name(workflow_t *w, const char* screen_name);
void wf_set_description(workflow_t *w, const char* description);
void wf_set_long_desc(workflow_t *w, const char* long_desc);
void wf_add_event(workflow_t *w, event_config_t *ec);
+void wf_set_priority(workflow_t *w, int priority);
+
+/*
+ * Returns a negative integer if the first value comes before the second, 0 if
+ * they are equal, or a positive integer if the first value comes after the
+ * second.
+ */
+int wf_priority_compare(const workflow_t *first, const workflow_t *second);
+
GHashTable *load_workflow_config_data_from_list(GList *wf_names, const char *path);
#endif
diff --git a/src/lib/workflow.c b/src/lib/workflow.c
index 52ad924..c6eedf4 100644
--- a/src/lib/workflow.c
+++ b/src/lib/workflow.c
@@ -24,6 +24,7 @@
struct workflow
{
config_item_info_t *info;
+ int priority; // direct correlation: higher number -> higher priority
GList *events; //list of event_option_t
};
@@ -193,6 +194,11 @@ const char *wf_get_long_desc(workflow_t *w)
return ci_get_long_desc(workflow_get_config_info(w));
}
+int wf_get_priority(workflow_t *w)
+{
+ return w->priority;
+}
+
void wf_set_screen_name(workflow_t *w, const char* screen_name)
{
ci_set_screen_name(workflow_get_config_info(w), screen_name);
@@ -213,3 +219,18 @@ void wf_add_event(workflow_t *w, event_config_t *ec)
w->events = g_list_append(w->events, ec);
log_info("added to ev list: '%s'", ec_get_screen_name(ec));
}
+
+void wf_set_priority(workflow_t *w, int priority)
+{
+ w->priority = priority;
+}
+
+/*
+ * Returns a negative integer if the first value comes before the second, 0 if
+ * they are equal, or a positive integer if the first value comes after the
+ * second.
+ */
+int wf_priority_compare(const workflow_t *first, const workflow_t *second)
+{
+ return second->priority - first->priority;
+}
diff --git a/src/lib/workflow_xml_parser.c b/src/lib/workflow_xml_parser.c
index 0efc733..f216c18 100644
--- a/src/lib/workflow_xml_parser.c
+++ b/src/lib/workflow_xml_parser.c
@@ -26,6 +26,7 @@
#define EVENT_ELEMENT "event"
#define DESCRIPTION_ELEMENT "description"
#define NAME_ELEMENT "name"
+#define PRIORITY_ELEMENT "priority"
static void start_element(GMarkupParseContext *context,
const gchar *element_name,
@@ -134,9 +135,26 @@ static void text(GMarkupParseContext *context,
}
}
}
-
}
+ else if(strcmp(inner_element, PRIORITY_ELEMENT) == 0)
+ {
+ log_debug("workflow priority:'%s'", text);
+
+ char *end = NULL;
+ long long val = strtoll(text, &end, 10);
+
+ if (text == end || end[0] != '\0'
+ || (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN))
+ || (val > INT_MAX || val < INT_MIN)
+ || (errno != 0 && val == 0))
+ {
+ error_msg("Workflow's priority is not a number in range <%d,%d>", INT_MIN, INT_MAX);
+ return;
+ }
+
+ wf_set_priority(workflow, (int)val);
+ }
}
// Called for strings that should be re-saved verbatim in this same
--
1.8.3.1