aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/report.h9
-rw-r--r--includes/shell.h19
-rw-r--r--shell/report.c260
-rw-r--r--shell/shell.c84
4 files changed, 268 insertions, 104 deletions
diff --git a/includes/report.h b/includes/report.h
index c04d2073..931a536e 100644
--- a/includes/report.h
+++ b/includes/report.h
@@ -49,13 +49,19 @@ struct _ReportContext {
void (*subsubtitle) (ReportContext *ctx, gchar *text);
void (*keyvalue) (ReportContext *ctx, gchar *key, gchar *value, gboolean highlight);
+ void (*details_start) (ReportContext *ctx, gchar *key, gchar *value, gboolean highlight);
+ void (*details_section) (ReportContext *ctx, gchar *name);
+ void (*details_keyvalue) (ReportContext *ctx, gchar *key, gchar *value, gboolean highlight);
+ void (*details_end) (ReportContext *ctx);
+
ReportFormat format;
gboolean is_image_enabled;
gboolean first_table;
+ gboolean in_details;
gboolean show_column_headers;
- guint columns;
+ guint columns, parent_columns;
GHashTable *column_titles;
};
@@ -83,6 +89,7 @@ void report_subtitle (ReportContext *ctx, gchar *text);
void report_subsubtitle (ReportContext *ctx, gchar *text);
void report_key_value (ReportContext *ctx, gchar *key, gchar *value, gboolean highlight);
void report_table (ReportContext *ctx, gchar *text);
+void report_details (ReportContext *ctx, gchar *key, gchar *value, gboolean highlight, gchar *details);
void report_create_from_module_list(ReportContext *ctx, GSList *modules);
gchar *report_create_from_module_list_format(GSList *modules, ReportFormat format);
diff --git a/includes/shell.h b/includes/shell.h
index 2eb9e6d2..d03355f3 100644
--- a/includes/shell.h
+++ b/includes/shell.h
@@ -97,10 +97,10 @@ struct _Shell {
ShellViewType view_type;
gboolean normalize_percentage;
-
+
gint _pulses;
ShellOrderType _order_type;
-
+
GKeyFile *hosts;
HelpViewer *help_viewer;
};
@@ -109,7 +109,7 @@ struct _ShellSummary {
GtkWidget *header;
GtkWidget *scroll;
GtkWidget *view;
-
+
GSList *items;
};
@@ -127,7 +127,7 @@ struct _ShellInfoTree {
GtkWidget *view;
GtkTreeModel *model;
GtkTreeSelection *selection;
-
+
GtkTreeViewColumn *col_progress, *col_value, *col_extra1, *col_extra2, *col_textvalue;
};
@@ -144,7 +144,7 @@ struct _ShellModule {
gpointer (*aboutfunc) ();
gchar *(*summaryfunc) ();
void (*deinit) ();
-
+
guchar weight;
GSList *entries;
@@ -162,7 +162,7 @@ struct _ShellModuleEntry {
gboolean selected;
gint number;
guint32 flags;
-
+
gchar *(*func) ();
void (*scan_func) ();
@@ -220,6 +220,13 @@ void shell_update_remote_menu(void);
void shell_set_remote_label(Shell *shell, gchar *label);
+/* decode special information in keys */
+gboolean key_is_flagged(gchar *key); /* has $[<flags>][<tag>]$ at the start of the key */
+gboolean key_is_highlighted(gchar *key); /* flag '*' = select/highlight */
+gboolean key_wants_details(gchar *key); /* flag '!' = report should include the "moreinfo" */
+gchar *key_mi_tag(gchar *key); /* moreinfo lookup tag */
+const gchar *key_get_name(gchar *key); /* get the key's name, flagged or not */
+
#endif /* __SHELL_H__ */
diff --git a/shell/report.c b/shell/report.c
index 4485faf5..8177822a 100644
--- a/shell/report.c
+++ b/shell/report.c
@@ -34,35 +34,37 @@ static FileTypes file_types[] = {
{NULL, NULL, NULL, NULL}
};
+/* virtual functions */
void report_header(ReportContext * ctx)
-{
- ctx->header(ctx);
-}
+{ ctx->header(ctx); }
void report_footer(ReportContext * ctx)
-{
- ctx->footer(ctx);
-}
+{ ctx->footer(ctx); }
void report_title(ReportContext * ctx, gchar * text)
-{
- ctx->title(ctx, text);
-}
+{ ctx->title(ctx, text); }
void report_subtitle(ReportContext * ctx, gchar * text)
-{
- ctx->subtitle(ctx, text);
-}
+{ ctx->subtitle(ctx, text); }
void report_subsubtitle(ReportContext * ctx, gchar * text)
-{
- ctx->subsubtitle(ctx, text);
-}
+{ ctx->subsubtitle(ctx, text); }
void report_key_value(ReportContext * ctx, gchar * key, gchar * value, gboolean highlight)
-{
- ctx->keyvalue(ctx, key, value, highlight);
-}
+{ ctx->keyvalue(ctx, key, value, highlight); }
+
+void report_details_start(ReportContext *ctx, gchar *key, gchar *value, gboolean highlight)
+{ ctx->details_start(ctx, key, value, highlight); }
+
+void report_details_section(ReportContext *ctx, gchar *label)
+{ ctx->details_section(ctx, label); }
+
+void report_details_keyvalue(ReportContext *ctx, gchar *key, gchar *value, gboolean highlight)
+{ ctx->details_keyvalue(ctx, key, value, highlight); }
+
+void report_details_end(ReportContext *ctx)
+{ ctx->details_end(ctx); }
+/* end virtual functions */
gint report_get_visible_columns(ReportContext *ctx)
{
@@ -151,6 +153,90 @@ void report_context_configure(ReportContext * ctx, GKeyFile * keyfile)
}
+static void report_html_details_start(ReportContext *ctx, gchar *key, gchar *value, gboolean highlight) {
+ guint cols = report_get_visible_columns(ctx);
+ report_key_value(ctx, key, value, highlight);
+ ctx->parent_columns = ctx->columns;
+ ctx->columns = REPORT_COL_VALUE;
+ ctx->output = h_strdup_cprintf("<tr><td colspan=\"%d\"><table class=\"details\">\n", ctx->output, cols);
+}
+
+static void report_html_details_end(ReportContext *ctx) {
+ ctx->output = h_strdup_cprintf("</table></td></tr>\n", ctx->output);
+ ctx->columns = ctx->parent_columns;
+ ctx->parent_columns = 0;
+}
+
+void report_details(ReportContext *ctx, gchar *key, gchar *value, gboolean highlight, gchar *details)
+{
+ GKeyFile *key_file = g_key_file_new();
+ gchar **groups;
+ gint i;
+
+ report_details_start(ctx, key, value, highlight);
+ ctx->in_details = TRUE;
+
+ g_key_file_load_from_data(key_file, details, strlen(details), 0, NULL);
+ groups = g_key_file_get_groups(key_file, NULL);
+
+ for (i = 0; groups[i]; i++) {
+ gchar *group, *tmpgroup;
+ gchar **keys;
+ gint j;
+
+ if (groups[i][0] == '$') {
+ continue;
+ }
+
+ group = groups[i];
+
+ tmpgroup = g_strdup(group);
+ strend(group, '#');
+
+ report_subsubtitle(ctx, group);
+
+ keys = g_key_file_get_keys(key_file, tmpgroup, NULL, NULL);
+ for (j = 0; keys[j]; j++) {
+ gchar *key = keys[j];
+ gchar *value;
+
+ value = g_key_file_get_value(key_file, tmpgroup, key, NULL);
+
+ if (g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
+ strend(key, '#');
+
+ if (g_str_equal(value, "...")) {
+ g_free(value);
+ if (!(value = ctx->entry->fieldfunc(key))) {
+ value = g_strdup("...");
+ }
+ }
+
+ if ( key_is_flagged(key) ) {
+ if (key_wants_details(key)) {
+ /* huh? */
+ }
+ report_key_value(ctx, strchr(key + 1, '$') + 1, value, key_is_highlighted(key) );
+ } else {
+ report_key_value(ctx, key, value, FALSE);
+ }
+
+ }
+
+ g_free(value);
+ }
+
+ g_strfreev(keys);
+ g_free(tmpgroup);
+ }
+
+ g_strfreev(groups);
+ g_key_file_free(key_file);
+
+ ctx->in_details = FALSE;
+ report_details_end(ctx);
+}
+
void report_table(ReportContext * ctx, gchar * text)
{
GKeyFile *key_file = g_key_file_new();
@@ -166,69 +252,74 @@ void report_table(ReportContext * ctx, gchar * text)
groups = g_key_file_get_groups(key_file, NULL);
for (i = 0; groups[i]; i++) {
- if (groups[i][0] == '$') {
- report_context_configure(ctx, key_file);
- break;
- }
+ if (groups[i][0] == '$') {
+ report_context_configure(ctx, key_file);
+ break;
+ }
}
for (i = 0; groups[i]; i++) {
- gchar *group, *tmpgroup;
- gchar **keys;
- gint j;
+ gchar *group, *tmpgroup;
+ gchar **keys;
+ gint j;
- if (groups[i][0] == '$') {
- continue;
- }
+ if (groups[i][0] == '$') {
+ continue;
+ }
- group = groups[i];
+ group = groups[i];
- tmpgroup = g_strdup(group);
- strend(group, '#');
+ tmpgroup = g_strdup(group);
+ strend(group, '#');
- report_subsubtitle(ctx, group);
+ report_subsubtitle(ctx, group);
#if 0
- if (ctx->is_image_enabled) {
- report_embed_image(ctx, key_file, group);
- } else {
+ if (ctx->is_image_enabled) {
+ report_embed_image(ctx, key_file, group);
+ } else {
#endif
- keys = g_key_file_get_keys(key_file, tmpgroup, NULL, NULL);
- for (j = 0; keys[j]; j++) {
- gchar *key = keys[j];
- gchar *value;
-
- value = g_key_file_get_value(key_file, tmpgroup, key, NULL);
-
- if (g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
- strend(key, '#');
-
- if (g_str_equal(value, "...")) {
- g_free(value);
- if (!(value = ctx->entry->fieldfunc(key))) {
- value = g_strdup("...");
- }
- }
-
- if (*key == '$') {
- if (*(key+1) == '*') /* check for selected/highlighted */
- report_key_value(ctx, strchr(key + 1, '$') + 1, value, TRUE);
- else
- report_key_value(ctx, strchr(key + 1, '$') + 1, value, FALSE);
- } else {
- report_key_value(ctx, key, value, FALSE);
- }
-
- }
-
- g_free(value);
- }
-
- g_strfreev(keys);
+ keys = g_key_file_get_keys(key_file, tmpgroup, NULL, NULL);
+ for (j = 0; keys[j]; j++) {
+ gchar *key = keys[j];
+ gchar *value;
+
+ value = g_key_file_get_value(key_file, tmpgroup, key, NULL);
+
+ if (g_utf8_validate(key, -1, NULL) && g_utf8_validate(value, -1, NULL)) {
+ strend(key, '#');
+
+ if (g_str_equal(value, "...")) {
+ g_free(value);
+ if (!(value = ctx->entry->fieldfunc(key))) {
+ value = g_strdup("...");
+ }
+ }
+
+ if ( key_is_flagged(key) ) {
+ gchar *mi_tag = key_mi_tag(key);
+ gchar *mi_data = NULL; /*const*/
+ if (key_wants_details(key)) {
+ mi_data = ctx->entry->morefunc(mi_tag);
+ report_details(ctx, (gchar*)key_get_name(key), value, key_is_highlighted(key), mi_data);
+ } else {
+ report_key_value(ctx, (gchar*)key_get_name(key), value, key_is_highlighted(key) );
+ }
+ g_free(mi_tag);
+ } else {
+ report_key_value(ctx, key, value, FALSE);
+ }
+
+ }
+
+ g_free(value);
+ }
+
+ g_strfreev(keys);
#if 0
- }
+ }
#endif
- g_free(tmpgroup);
+ g_free(tmpgroup);
}
g_strfreev(groups);
@@ -248,9 +339,10 @@ static void report_html_header(ReportContext * ctx)
" .title { font: bold 130%% serif; color: #0066FF; padding: 30px 0 10px 0 }\n"
" .stitle { font: bold 100%% sans-serif; color: #0044DD; padding: 30px 0 10px 0 }\n"
" .sstitle{ font: bold 80%% serif; color: #000000; background: #efefef }\n"
- " .field { font: 80%% sans-serif; color: #000000; padding: 2px; padding-left: 50px }\n"
+ " .field { font: 80%% sans-serif; color: #000000; padding: 2px; padding-left: 30px }\n"
" .value { font: 80%% sans-serif; color: #505050 }\n"
" .hilight { font: bold 110%% sans-serif; color: #000000; background: #ffff66 }\n"
+ " table.details { margin-left: 50px; }\n"
"</style>\n" "</head><body>\n",
VERSION);
}
@@ -368,7 +460,10 @@ static void report_text_subtitle(ReportContext * ctx, gchar * text)
static void report_text_subsubtitle(ReportContext * ctx, gchar * text)
{
- ctx->output = h_strdup_cprintf("-%s-\n", ctx->output, text);
+ gchar indent[10] = " ";
+ if (!ctx->in_details)
+ indent[0] = 0;
+ ctx->output = h_strdup_cprintf("%s-%s-\n", ctx->output, indent, text);
}
static void
@@ -377,20 +472,23 @@ report_text_key_value(ReportContext * ctx, gchar * key, gchar * value, gboolean
gint columns = report_get_visible_columns(ctx);
gchar **values;
gint i, mc;
+ gchar indent[10] = " ";
+ if (!ctx->in_details)
+ indent[0] = 0;
- if (columns == 2) {
+ if (columns == 2 || ctx->in_details) {
if (strlen(value))
- ctx->output = h_strdup_cprintf("%s%s\t\t: %s\n", ctx->output, highlight ? "* " : "", key, value);
+ ctx->output = h_strdup_cprintf("%s%s%s\t\t: %s\n", ctx->output, indent, highlight ? "* " : "", key, value);
else
- ctx->output = h_strdup_cprintf("%s%s\n", ctx->output, highlight ? "* " : "", key);
+ ctx->output = h_strdup_cprintf("%s%s%s\n", ctx->output, indent, highlight ? "* " : "", key);
} else {
values = g_strsplit(value, "|", columns);
mc = g_strv_length(values) - 1;
- ctx->output = h_strdup_cprintf("%s%s\t", ctx->output, highlight ? "* " : "", key);
+ ctx->output = h_strdup_cprintf("%s%s%s", ctx->output, indent, highlight ? "* " : "", key);
for (i = mc; i >= 0; i--) {
- ctx->output = h_strdup_cprintf("%s\t",
+ ctx->output = h_strdup_cprintf("\t%s",
ctx->output,
values[i]);
}
@@ -540,6 +638,11 @@ ReportContext *report_context_html_new()
ctx->subsubtitle = report_html_subsubtitle;
ctx->keyvalue = report_html_key_value;
+ ctx->details_start = report_html_details_start;
+ ctx->details_section = report_html_subsubtitle;
+ ctx->details_keyvalue = report_html_key_value;
+ ctx->details_end = report_html_details_end;
+
ctx->output = g_strdup("");
ctx->format = REPORT_FORMAT_HTML;
@@ -562,6 +665,11 @@ ReportContext *report_context_text_new()
ctx->subsubtitle = report_text_subsubtitle;
ctx->keyvalue = report_text_key_value;
+ ctx->details_start = report_text_key_value;
+ ctx->details_section = report_text_subsubtitle;
+ ctx->details_keyvalue = report_text_key_value;
+ ctx->details_end = report_text_footer; /* nothing */
+
ctx->output = g_strdup("");
ctx->format = REPORT_FORMAT_TEXT;
diff --git a/shell/shell.c b/shell/shell.c
index 9918db34..83677ea1 100644
--- a/shell/shell.c
+++ b/shell/shell.c
@@ -45,7 +45,7 @@ static void module_selected(gpointer data);
static void module_selected_show_info(ShellModuleEntry * entry,
gboolean reload);
static void info_selected(GtkTreeSelection * ts, gpointer data);
-static void info_selected_show_extra(gchar * data);
+static void info_selected_show_extra(const gchar *tag);
static gboolean reload_section(gpointer data);
static gboolean rescan_section(gpointer data);
static gboolean update_field(gpointer data);
@@ -1236,19 +1236,19 @@ group_handle_normal(GKeyFile * key_file, ShellModuleEntry * entry,
strend(key, '#');
- if (*key == '$') {
- gchar **tmp;
+ if (key_is_flagged(key)) {
+ const gchar *name = key_get_name(key);
+ gchar *flags = g_strdup(key);
+ *(strchr(flags+1, '$')+1) = 0;
- tmp = g_strsplit(++key, "$", 0);
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME,
+ _(name), INFO_TREE_COL_DATA, flags, -1);
- gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME,
- tmp[1], INFO_TREE_COL_DATA, tmp[0], -1);
-
- g_strfreev(tmp);
- } else {
- gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, _(key),
- INFO_TREE_COL_DATA, NULL, -1);
- }
+ g_free(flags);
+ } else {
+ gtk_tree_store_set(store, &child, INFO_TREE_COL_NAME, _(key),
+ INFO_TREE_COL_DATA, NULL, -1);
+ }
g_hash_table_insert(update_tbl, g_strdup(key),
gtk_tree_iter_copy(&child));
@@ -1421,7 +1421,7 @@ select_marked_or_first_item(gpointer data)
it = first;
while ( gtk_tree_model_iter_next(shell->info->model, &it) ) {
gtk_tree_model_get(shell->info->model, &it, INFO_TREE_COL_DATA, &datacol, -1);
- if (datacol != NULL && *datacol == '*') {
+ if (key_is_highlighted(datacol)) {
gtk_tree_selection_select_iter(shell->info->selection, &it);
found_selection = TRUE;
}
@@ -1541,7 +1541,7 @@ module_selected_show_info(ShellModuleEntry * entry, gboolean reload)
}
}
-static void info_selected_show_extra(gchar * data)
+static void info_selected_show_extra(const gchar *tag)
{
GtkTreeStore *store;
@@ -1551,12 +1551,9 @@ static void info_selected_show_extra(gchar * data)
if (!shell->selected->morefunc)
return;
- if (data) {
- /* skip the select marker */
- if (*data == '*')
- data++;
+ if (tag) {
GKeyFile *key_file = g_key_file_new();
- gchar *key_data = shell->selected->morefunc(data);
+ gchar *key_data = shell->selected->morefunc((gchar *)tag);
gchar **groups;
gint i;
@@ -1871,7 +1868,7 @@ static void info_selected(GtkTreeSelection * ts, gpointer data)
ShellInfoTree *info = (ShellInfoTree *) data;
GtkTreeModel *model = GTK_TREE_MODEL(info->model);
GtkTreeIter parent;
- gchar *datacol;
+ gchar *datacol, *mi_tag;
if (!gtk_tree_selection_get_selected(ts, &model, &parent))
return;
@@ -1883,8 +1880,10 @@ static void info_selected(GtkTreeSelection * ts, gpointer data)
}
gtk_tree_model_get(model, &parent, INFO_TREE_COL_DATA, &datacol, -1);
- info_selected_show_extra(datacol);
+ mi_tag = key_mi_tag(datacol);
+ info_selected_show_extra(mi_tag);
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(shell->moreinfo->view));
+ g_free(mi_tag);
}
static ShellInfoTree *info_tree_new(gboolean extra)
@@ -2049,3 +2048,46 @@ static ShellTree *tree_new()
return shelltree;
}
+
+gboolean key_is_flagged(gchar *key) {
+ return (key && *key == '$' && strchr(key+1, '$')) ? TRUE : FALSE;
+}
+
+gboolean key_is_highlighted(gchar *key) {
+ if (key_is_flagged(key)) {
+ if (strchr(key, '*'))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean key_wants_details(gchar *key) {
+ if (key_is_flagged(key)) {
+ if (strchr(key, '!'))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gchar *key_mi_tag(gchar *key) {
+ gchar *p = key, *l, *t;
+
+ if (key_is_flagged(key)) {
+ l = strchr(key+1, '$');
+ while(p < l && (*p == '$' || *p == '*' || *p == '!') ) {
+ p++;
+ }
+ if (strlen(p)) {
+ t = g_strdup(p);
+ *(strchr(t, '$')) = 0;
+ return t;
+ }
+ }
+ return NULL;
+}
+
+const gchar *key_get_name(gchar *key) {
+ if (key_is_flagged(key))
+ return strchr(key+1, '$')+1;
+ return key;
+}