From d40146089b5957184af45de3cb91c4feed7ebd16 Mon Sep 17 00:00:00 2001 From: Jiri Moskovcak Date: Wed, 9 Feb 2011 15:05:54 +0100 Subject: abrt-gtk: beginning of C rewrite of GUI --- src/gui-gtk/Makefile.am | 48 ++++++++++++ src/gui-gtk/abrt-gtk.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++++ src/gui-gtk/abrt-gtk.h | 3 + src/gui-gtk/list_dir.c | 48 ++++++++++++ src/gui-gtk/list_dir.h | 3 + src/gui-gtk/main.c | 63 +++++++++++++++ 6 files changed, 369 insertions(+) create mode 100644 src/gui-gtk/Makefile.am create mode 100644 src/gui-gtk/abrt-gtk.c create mode 100644 src/gui-gtk/abrt-gtk.h create mode 100644 src/gui-gtk/list_dir.c create mode 100644 src/gui-gtk/list_dir.h create mode 100644 src/gui-gtk/main.c (limited to 'src/gui-gtk') diff --git a/src/gui-gtk/Makefile.am b/src/gui-gtk/Makefile.am new file mode 100644 index 00000000..d476866c --- /dev/null +++ b/src/gui-gtk/Makefile.am @@ -0,0 +1,48 @@ +bin_PROGRAMS = abrt-gtk + +abrt_gtk_SOURCES = \ + list_dir.c \ + list_dir.h \ + abrt-gtk.h \ + abrt-gtk.c \ + main.c +abrt_gtk_CFLAGS = \ + -I$(srcdir)/../include/report -I$(srcdir)/../include \ + -I$(srcdir)/../lib \ + -DBIN_DIR=\"$(bindir)\" \ + -DVAR_RUN=\"$(VAR_RUN)\" \ + -DCONF_DIR=\"$(CONF_DIR)\" \ + -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \ + -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \ + -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \ + -DICON_DIR=\"${datadir}/abrt/icons/hicolor/48x48/status\" \ + $(GTK_CFLAGS) \ + $(DBUS_CFLAGS) \ + -D_GNU_SOURCE \ + -Wall -Werror +# -I/usr/include/glib-2.0 +# -I/usr/lib/glib-2.0/include +# $(LIBNOTIFY_CFLAGS) +# $(DBUS_GLIB_CFLAGS) +abrt_gtk_LDADD = \ + ../lib/libreport.la \ + ../lib/libabrt_dbus.la \ + -lglib-2.0 \ + -lgthread-2.0 \ + $(DBUS_LIBS) \ + $(LIBNOTIFY_LIBS) \ + $(GTK_LIBS) + +#test_report_SOURCES = \ +# test_report.c +#test_report_CPPFLAGS = \ +# -I$(srcdir)/../include/report -I$(srcdir)/../include \ +# $(GLIB_CFLAGS) \ +# -D_GNU_SOURCE \ +# -Wall -Werror +#test_report_LDADD = \ +# ../lib/libreport.la + +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ + +@INTLTOOL_DESKTOP_RULE@ \ No newline at end of file diff --git a/src/gui-gtk/abrt-gtk.c b/src/gui-gtk/abrt-gtk.c new file mode 100644 index 00000000..d67c690b --- /dev/null +++ b/src/gui-gtk/abrt-gtk.c @@ -0,0 +1,204 @@ +#include +#include +#include +#include +#include "list_dir.h" +#include "abrtlib.h" + + + +GtkListStore *dumps_list_store; +GtkTreeIter iter; + +enum +{ + COLUMN_REPORTED, + COLUMN_APPLICATION, + COLUMN_HOSTNAME, + COLUMN_LATEST_CRASH_STR, + COLUMN_LATEST_CRASH, + COLUMN_DUMP_DIR, + NUM_COLUMNS +}; + +/* + +void gtk_tree_model_get_value (GtkTreeModel *tree_model, + GtkTreeIter *iter, + gint column, + GValue *value); +*/ + + +void on_row_activated_cb(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) +{ + GtkTreeIter iter; + GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view); + GtkTreeModel *dump_list_store = gtk_tree_view_get_model(tree_view); + gtk_tree_model_get_iter(dump_list_store, &iter, path); + GValue d_dir = {0}; + if(selection != NULL) + { + if(gtk_tree_selection_get_selected(selection, &dump_list_store, &iter) == TRUE) + { + gtk_tree_model_get_value(dump_list_store, &iter, COLUMN_DUMP_DIR, &d_dir); + g_print("CALL: run_event(%s)\n", g_value_get_string(&d_dir)); + } + } +} + +void view_store_add_item(gpointer item, gpointer data) +{ + char *dir = (char *)item; + struct dump_dir *dd; + + dd = dd_opendir(dir, DD_OPEN_READONLY); + + if(dd == NULL) + return; + + time_t time = atoi(dd_load_text(dd, FILENAME_TIME)); + struct tm * ptm = localtime(&time); + char time_buf[60]; + size_t time_len = strftime(time_buf, 59, "%c", ptm); + time_buf[time_len] = '\0'; + + gtk_list_store_append(dumps_list_store, &iter); + gtk_list_store_set(dumps_list_store, &iter, + COLUMN_REPORTED, "??", + COLUMN_APPLICATION, dd_load_text(dd, FILENAME_EXECUTABLE), + COLUMN_HOSTNAME, dd_load_text(dd, FILENAME_HOSTNAME), + //OPTION: time format + COLUMN_LATEST_CRASH_STR, time_buf, + COLUMN_LATEST_CRASH, (int)time, + COLUMN_DUMP_DIR, dir, + -1); + dd_close(dd); + VERB1 log("added: %s\n", dir); +} + +static void +add_columns (GtkTreeView *treeview) +{ + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + /* column reported */ + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Reported"), + renderer, + "text", + COLUMN_REPORTED, + NULL); + gtk_tree_view_column_set_sort_column_id(column, COLUMN_REPORTED); + gtk_tree_view_append_column(treeview, column); + + /* column for executable path */ + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Application"), + renderer, + "text", + COLUMN_APPLICATION, + NULL); + gtk_tree_view_column_set_resizable(column, TRUE); + gtk_tree_view_column_set_sort_column_id(column, COLUMN_APPLICATION); + gtk_tree_view_append_column(treeview, column); + + /* column for hostname */ + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Hostname"), + renderer, + "text", + COLUMN_HOSTNAME, + NULL); + gtk_tree_view_column_set_sort_column_id(column, COLUMN_HOSTNAME); + gtk_tree_view_append_column(treeview, column); + + /* column for the date of the last crash */ + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Last Crash"), + renderer, + "text", + COLUMN_LATEST_CRASH_STR, + NULL); + gtk_tree_view_column_set_sort_column_id(column, COLUMN_LATEST_CRASH); + gtk_tree_view_append_column(treeview, column); + +} + +int dump_list_hydrate(char *path) +{ + GList *dumps = get_dump_list(path); + g_list_foreach(dumps, view_store_add_item, NULL); + + return 0; +} + +GtkWidget *main_window_create() +{ + /* main window */ + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + if (!window) + die_out_of_memory(); + + gtk_window_set_default_size(GTK_WINDOW(window), 600, 700); + gtk_window_set_title(GTK_WINDOW(window), _("Automatic Bug Reporting Tool")); + gtk_window_set_icon_name(GTK_WINDOW(window), "abrt"); + //quit when user closes the main window + g_signal_connect(window, "destroy", gtk_main_quit, NULL); + + /* main pane + * holds the textview with dump list and a vbox with bug details + * and bug details (icon, comment, howto, cmdline, etc ...) + */ + GtkWidget *main_pane = gtk_vpaned_new(); + GtkWidget *dump_list_sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(dump_list_sw), + GTK_SHADOW_ETCHED_IN); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dump_list_sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + GtkWidget *dump_tv = gtk_tree_view_new(); + add_columns(GTK_TREE_VIEW(dump_tv)); + dumps_list_store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING, /* reported */ + G_TYPE_STRING, /* executable */ + G_TYPE_STRING, /* hostname */ + G_TYPE_STRING, /* time */ + G_TYPE_INT, /* unix time - used for sort */ + G_TYPE_STRING);/* dump dir path */ + //if(dumps_list_store == NULL) + // return NULL; + gtk_tree_view_set_model(GTK_TREE_VIEW(dump_tv), GTK_TREE_MODEL(dumps_list_store)); + g_signal_connect(dump_tv, "row-activated", G_CALLBACK(on_row_activated_cb), NULL); + gtk_container_add(GTK_CONTAINER(dump_list_sw), dump_tv); + + /* dump details */ + GtkWidget *dump_details_sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(dump_details_sw), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + + GtkWidget *details_vbox = gtk_vbox_new(false, 0); + GtkWidget *icon_name_hbox = gtk_hbox_new(false, 0); + GtkWidget *details_hbox = gtk_hbox_new(true, 0); + GtkWidget *package_icon = gtk_image_new_from_stock("gtk-missing-image", GTK_ICON_SIZE_DIALOG); + + + gtk_box_pack_start(GTK_BOX(icon_name_hbox), package_icon, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(details_vbox), icon_name_hbox, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(details_vbox), details_hbox, FALSE, TRUE, 0); + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(dump_details_sw), details_vbox); + + /* add dump list and dump details to pane */ + gtk_paned_pack1(GTK_PANED(main_pane), dump_list_sw, FALSE, FALSE); + gtk_paned_pack2(GTK_PANED(main_pane), dump_details_sw, FALSE, FALSE); + + + + + GtkWidget *main_vbox = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(main_vbox), main_pane, TRUE, TRUE, 0); + gtk_container_add(GTK_CONTAINER(window), main_vbox); + return window; +} diff --git a/src/gui-gtk/abrt-gtk.h b/src/gui-gtk/abrt-gtk.h new file mode 100644 index 00000000..c8c9e017 --- /dev/null +++ b/src/gui-gtk/abrt-gtk.h @@ -0,0 +1,3 @@ +int dump_list_hydrate(char *path); +GtkWidget *main_window_create(); + diff --git a/src/gui-gtk/list_dir.c b/src/gui-gtk/list_dir.c new file mode 100644 index 00000000..8a0d47bd --- /dev/null +++ b/src/gui-gtk/list_dir.c @@ -0,0 +1,48 @@ +#ifndef _GNU_SOURCE + #define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GList *get_dump_list(const char *path) +{ + GList *dumps = NULL; + DIR *dp; + struct dirent *ep; + //char *path = "./"; + char *current_dir_path; + + dp = opendir(path); + + if (dp != NULL) + { + while ((ep = readdir (dp))) + /* d_type is not supported on all systems, but should be ok for us + * can be implemented using stat if someone wants to do it... + */ + if(ep->d_name && ep->d_name[0] != '.' && ep->d_type == DT_DIR) + { + if(asprintf(¤t_dir_path, "%s/%s", path, ep->d_name) != -1) + { + //FIXME: should be int ret = access(current_dir_path, R_OK|W_OK); + int ret = access(current_dir_path, R_OK); + if(ret == 0) + { + dumps = g_list_prepend(dumps, current_dir_path); + } + } + } + (void) closedir (dp); + } + else + fprintf(stderr, "Couldn't open the directory %s: %s\n", path, strerror(errno)); + return dumps; +} diff --git a/src/gui-gtk/list_dir.h b/src/gui-gtk/list_dir.h new file mode 100644 index 00000000..1ee14e5d --- /dev/null +++ b/src/gui-gtk/list_dir.h @@ -0,0 +1,3 @@ + +GList *get_dump_list(const char *path); + diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c new file mode 100644 index 00000000..66fee821 --- /dev/null +++ b/src/gui-gtk/main.c @@ -0,0 +1,63 @@ +#include + +#include "abrtlib.h" +#include "abrt-gtk.h" + + + +int main(int argc, char **argv) +{ + /* I18n */ + setlocale(LC_ALL, ""); + char *path = "."; + + //int optflags = 0; + int opt; + while ((opt = getopt(argc, argv, "c:d:v")) != -1) + { + switch (opt) + { + case 'c': + VERB1 log("Loading settings from '%s'", optarg); + //load_conf_file(optarg, settings, /*skip key w/o values:*/ true); + VERB3 log("Loaded '%s'", optarg); + break; + case 'd': + path = optarg; + break; + case 'v': + g_verbose++; + break; + default: + /* Careful: the string below contains tabs, dont replace with spaces */ + error_msg_and_die( + "Usage: abrt-gtk -c CONFFILE -d DIR [-v]" + "\n" + "\nReport a crash to Bugzilla" + "\n" + "\nOptions:" + "\n -c FILE Configuration file (may be given many times)" + "\n -d DIR Crash dump directory" + "\n -v Verbose" + "\n -s Log to syslog" + ); + } + } + + if (argc > 1) + path = argv[1]; + + gtk_init(&argc, &argv); + + /* Prevent zombies when we spawn wizard */ + signal(SIGCHLD, SIG_IGN); + + GtkWidget *main_window = main_window_create(); + dump_list_hydrate(path); + gtk_widget_show_all(main_window); + + /* Enter main loop */ + gtk_main(); + + return 0; +} -- cgit