diff options
-rw-r--r-- | includes/report.h | 9 | ||||
-rw-r--r-- | includes/shell.h | 19 | ||||
-rw-r--r-- | shell/report.c | 260 | ||||
-rw-r--r-- | shell/shell.c | 84 |
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; +} |