diff options
author | Leandro A. F. Pereira <leandro@hardinfo.org> | 2006-01-26 19:39:15 +0000 |
---|---|---|
committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2006-01-26 19:39:15 +0000 |
commit | e9906f6d9335ae96cd6afac714646b97edc469a5 (patch) | |
tree | 956f3266766454f931e7d18e2fe78a6256d11039 /hardinfo2/report.c | |
parent | 53f455be1d85829551761dbcfcf6e5706606186b (diff) |
Sync with internal svn
Diffstat (limited to 'hardinfo2/report.c')
-rw-r--r-- | hardinfo2/report.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/hardinfo2/report.c b/hardinfo2/report.c new file mode 100644 index 00000000..f3621276 --- /dev/null +++ b/hardinfo2/report.c @@ -0,0 +1,467 @@ +/* + * HardInfo - Displays System Information + * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@linuxmag.com.br> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <report.h> +#include <stdio.h> +#include <string.h> +#include <shell.h> +#include <hardinfo.h> + +static ReportDialog *report_dialog_new(GtkTreeModel *model, GtkWidget *parent); +static void set_all_active(ReportDialog *rd, gboolean setting); + +static void +report_html_header(ReportContext *ctx) +{ + fprintf(ctx->stream, + "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Final//EN\">\n" \ + "<html><head>\n" \ + "<title>HardInfo System Report</title>\n" \ + "<style>\n" \ + ".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" \ + ".value { font: 80%% sans-serif; color: #505050 }\n" \ + "</style>\n" \ + "</head><body>\n" \ + "<table width=\"100%%\"><tbody>"); +} + +static void +report_html_footer(ReportContext *ctx) +{ + fprintf(ctx->stream, + "</tbody></table></body></html>"); +} + +static void +report_html_title(ReportContext *ctx, gchar *text) +{ + fprintf(ctx->stream, + "<tr><td colspan=\"2\" class=\"title\">%s</td></tr>\n", text); +} + +static void +report_html_subtitle(ReportContext *ctx, gchar *text) +{ + fprintf(ctx->stream, + "<tr><td colspan=\"2\" class=\"stitle\">%s</td></tr>\n", text); +} +static void +report_html_subsubtitle(ReportContext *ctx, gchar *text) +{ + fprintf(ctx->stream, + "<tr><td colspan=\"2\" class=\"sstitle\">%s</td></tr>\n", text); +} + +static void +report_html_key_value(ReportContext *ctx, gchar *key, gchar *value) +{ + fprintf(ctx->stream, + "<tr><td class=\"field\">%s</td>" \ + "<td class=\"value\">%s</td></tr>\n", key, value); +} + +static void +report_html_table(ReportContext *ctx, gchar *text) +{ + GKeyFile *key_file = g_key_file_new(); + gchar **groups; + gint i; + + g_key_file_load_from_data(key_file, text, strlen(text), 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]; + keys = g_key_file_get_keys(key_file, group, NULL, NULL); + + tmpgroup = g_strdup(group); + strend(group, '#'); + + report_html_subsubtitle(ctx, group); + + 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); + value = ctx->entry->fieldfunc(key); + } + + if (*key == '$') { + gchar **tmp; + + tmp = g_strsplit(++key, "$", 0); + report_html_key_value(ctx, tmp[1], value); + g_strfreev(tmp); + } else { + report_html_key_value(ctx, key, value); + } + + } + + g_free(value); + } + + g_free(tmpgroup); + g_strfreev(keys); + } + + g_strfreev(groups); + g_key_file_free(key_file); +} + +static void +report_generate_child(ReportContext *ctx, GtkTreeIter *iter) +{ + ShellModuleEntry *entry; + gboolean selected; + + gtk_tree_model_get(ctx->rd->model, iter, TREE_COL_SEL, &selected, -1); + if (!selected) + return; + + gtk_tree_model_get(ctx->rd->model, iter, TREE_COL_DATA, &entry, -1); + + ctx->entry = entry; + + report_html_subtitle(ctx, entry->name); + report_html_table(ctx, entry->func(entry->number)); +} + +static void +report_generate_children(ReportContext *ctx, GtkTreeIter *iter) +{ + GtkTreeModel *model = ctx->rd->model; + gchar *name; + + gtk_tree_model_get(model, iter, TREE_COL_NAME, &name, -1); + report_html_title(ctx, name); + + if (gtk_tree_model_iter_has_child(model, iter)) { + gint children = gtk_tree_model_iter_n_children(model, iter); + gint i; + + for (i = 0; i < children; i++) { + GtkTreeIter child; + + gtk_tree_model_iter_nth_child(model, &child, iter, i); + report_generate_child(ctx, &child); + } + } +} + +static gchar * +report_get_filename(void) +{ + GtkWidget *dialog; + gchar *filename = NULL; + + dialog = gtk_file_chooser_dialog_new("Save File", + NULL, + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), + TRUE); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), + "hardinfo report.html"); + + if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + } + + gtk_widget_destroy (dialog); + return filename; +} + +static gboolean +report_generate(ReportDialog *rd) +{ + GtkTreeIter iter; + GtkTreeModel *model; + ReportContext *ctx; + gchar *file; + FILE *stream; + + file = report_get_filename(); + if (!file) + return FALSE; + stream = fopen(file, "w+"); + if (!stream) { + /* FIXME complain */ + return FALSE; + } + + model = rd->model; + ctx = g_new0(ReportContext, 1); + ctx->rd = rd; + ctx->stream = stream; + + report_html_header(ctx); + + gtk_tree_model_get_iter_first(model, &iter); + + do { + report_generate_children(ctx, &iter); + } while (gtk_tree_model_iter_next(model, &iter)); + + report_html_footer(ctx); + + fclose(ctx->stream); + g_free(ctx); + + return TRUE; +} + +void +report_dialog_show(GtkTreeModel *model, GtkWidget *parent) +{ + gboolean success; + ReportDialog *rd = report_dialog_new(model, parent); + + if (gtk_dialog_run(GTK_DIALOG(rd->dialog)) == GTK_RESPONSE_ACCEPT) { + shell_status_update("Generating report..."); + gtk_widget_hide(rd->dialog); + shell_view_set_enabled(FALSE); + shell_status_set_enabled(TRUE); + + success = report_generate(rd); + + shell_status_set_enabled(FALSE); + + if (success) + shell_status_update("Report saved."); + else + shell_status_update("Error while creating the report."); + } + + set_all_active(rd, FALSE); + gtk_widget_destroy(rd->dialog); + g_free(rd); +} + +static void +set_children_active(GtkTreeModel *model, GtkTreeIter *iter, gboolean setting) +{ + if (gtk_tree_model_iter_has_child(model, iter)) { + gint children = gtk_tree_model_iter_n_children(model, iter); + + gtk_tree_store_set(GTK_TREE_STORE(model), iter, TREE_COL_SEL, setting, -1); + + for (children--; children >= 0; children--) { + GtkTreeIter child; + + gtk_tree_model_iter_nth_child(model, &child, iter, children); + gtk_tree_store_set(GTK_TREE_STORE(model), &child, TREE_COL_SEL, setting, -1); + } + } +} + +static void +set_all_active(ReportDialog *rd, gboolean setting) +{ + GtkTreeIter iter; + GtkTreeModel *model = rd->model; + + gtk_tree_model_get_iter_first(model, &iter); + + do { + set_children_active(model, &iter, setting); + } while (gtk_tree_model_iter_next(model, &iter)); +} + +static void +report_dialog_sel_none(GtkWidget *widget, ReportDialog *rd) +{ + set_all_active(rd, FALSE); +} + +static void +report_dialog_sel_all(GtkWidget *widget, ReportDialog *rd) +{ + set_all_active(rd, TRUE); +} + +static void +report_dialog_sel_toggle(GtkCellRendererToggle *cellrenderertoggle, + gchar *path_str, + ReportDialog *rd) +{ + GtkTreeModel *model = rd->model; + GtkTreeIter iter; + GtkTreePath *path = gtk_tree_path_new_from_string(path_str); + gboolean active; + + gtk_tree_model_get_iter(model, &iter, path); + gtk_tree_model_get(model, &iter, TREE_COL_SEL, &active, -1); + + active = !active; + gtk_tree_store_set(GTK_TREE_STORE(model), &iter, TREE_COL_SEL, active, -1); + set_children_active(model, &iter, active); + + gtk_tree_path_free(path); +} + +static ReportDialog +*report_dialog_new(GtkTreeModel *model, GtkWidget *parent) +{ + ReportDialog *rd; + GtkWidget *dlgReport; + GtkWidget *dialog1_vbox; + GtkWidget *scrolledwindow2; + GtkWidget *treeview2; + GtkWidget *hbuttonbox3; + GtkWidget *button3; + GtkWidget *button6; + GtkWidget *dialog1_action_area; + GtkWidget *button8; + GtkWidget *button7; + GtkWidget *label; + + GtkTreeViewColumn *column; + GtkCellRenderer *cr_text, *cr_pbuf, *cr_toggle; + + rd = g_new0(ReportDialog, 1); + + dlgReport = gtk_dialog_new(); + gtk_window_set_title(GTK_WINDOW(dlgReport), "Generate Report"); + gtk_window_set_default_size(GTK_WINDOW(dlgReport), 320, 260); + gtk_window_set_transient_for(GTK_WINDOW(dlgReport), GTK_WINDOW(parent)); + gtk_window_set_position(GTK_WINDOW(dlgReport), GTK_WIN_POS_CENTER_ON_PARENT); + gtk_window_set_type_hint(GTK_WINDOW(dlgReport), + GDK_WINDOW_TYPE_HINT_DIALOG); + + dialog1_vbox = GTK_DIALOG(dlgReport)->vbox; + gtk_box_set_spacing(GTK_BOX(dialog1_vbox), 5); + gtk_container_set_border_width(GTK_CONTAINER(dialog1_vbox), 4); + gtk_widget_show(dialog1_vbox); + + label = gtk_label_new("<big><b>Generate Report</b></big>\n" \ + "Please choose the information that you wish " \ + "to view in your report:"); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_label_set_use_markup(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); + gtk_widget_show(label); + gtk_box_pack_start(GTK_BOX(dialog1_vbox), label, FALSE, FALSE, 0); + + scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow2); + gtk_box_pack_start(GTK_BOX(dialog1_vbox), scrolledwindow2, TRUE, TRUE, 0); + gtk_widget_set_size_request(scrolledwindow2, -1, 200); + GTK_WIDGET_UNSET_FLAGS(scrolledwindow2, GTK_CAN_FOCUS); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow2), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_ALWAYS); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW + (scrolledwindow2), GTK_SHADOW_IN); + + treeview2 = gtk_tree_view_new_with_model(model); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview2), FALSE); + gtk_widget_show(treeview2); + gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview2); + GTK_WIDGET_UNSET_FLAGS(treeview2, GTK_CAN_FOCUS); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview2), column); + + cr_toggle = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(column, cr_toggle, FALSE); + g_signal_connect(cr_toggle, "toggled", G_CALLBACK(report_dialog_sel_toggle), rd); + gtk_tree_view_column_add_attribute(column, cr_toggle, "active", + TREE_COL_SEL); + + cr_pbuf = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(column, cr_pbuf, FALSE); + gtk_tree_view_column_add_attribute(column, cr_pbuf, "pixbuf", + TREE_COL_PBUF); + + cr_text = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, cr_text, TRUE); + gtk_tree_view_column_add_attribute(column, cr_text, "markup", + TREE_COL_NAME); + + hbuttonbox3 = gtk_hbutton_box_new(); + gtk_widget_show(hbuttonbox3); + gtk_box_pack_start(GTK_BOX(dialog1_vbox), hbuttonbox3, FALSE, TRUE, 0); + gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox3), + GTK_BUTTONBOX_SPREAD); + + button3 = gtk_button_new_with_mnemonic("Select _None"); + gtk_widget_show(button3); + gtk_container_add(GTK_CONTAINER(hbuttonbox3), button3); + GTK_WIDGET_UNSET_FLAGS(button3, GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS(button3, GTK_CAN_DEFAULT); + g_signal_connect(button3, "clicked", G_CALLBACK(report_dialog_sel_none), rd); + + button6 = gtk_button_new_with_mnemonic("Select _All"); + gtk_widget_show(button6); + gtk_container_add(GTK_CONTAINER(hbuttonbox3), button6); + GTK_WIDGET_UNSET_FLAGS(button6, GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS(button6, GTK_CAN_DEFAULT); + g_signal_connect(button6, "clicked", G_CALLBACK(report_dialog_sel_all), rd); + + dialog1_action_area = GTK_DIALOG(dlgReport)->action_area; + gtk_widget_show(dialog1_action_area); + gtk_button_box_set_layout(GTK_BUTTON_BOX(dialog1_action_area), + GTK_BUTTONBOX_END); + + button8 = gtk_button_new_from_stock("gtk-cancel"); + gtk_widget_show(button8); + gtk_dialog_add_action_widget(GTK_DIALOG(dlgReport), button8, + GTK_RESPONSE_CANCEL); + GTK_WIDGET_UNSET_FLAGS(button8, GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS(button8, GTK_CAN_DEFAULT); + + button7 = gtk_button_new_with_mnemonic("Generate _Report"); + gtk_widget_show(button7); + gtk_dialog_add_action_widget(GTK_DIALOG(dlgReport), button7, + GTK_RESPONSE_ACCEPT); + GTK_WIDGET_UNSET_FLAGS(button7, GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS(button7, GTK_CAN_DEFAULT); + + rd->dialog = dlgReport; + rd->btn_cancel = button8; + rd->btn_generate = button7; + rd->btn_sel_all = button6; + rd->btn_sel_none = button3; + rd->treeview = treeview2; + rd->model = model; + + gtk_tree_view_collapse_all(GTK_TREE_VIEW(treeview2)); + set_all_active(rd, TRUE); + + return rd; +} |