Signed-off-by: Jiri Moskovcak <jmoskovc(a)redhat.com>
---
configure.ac | 1 -
po/POTFILES.in | 1 -
src/Makefile.am | 2 +-
src/gui-gtk/Makefile.am | 38 --
src/gui-gtk/main.c | 1422 -----------------------------------------------
5 files changed, 1 insertion(+), 1463 deletions(-)
delete mode 100644 src/gui-gtk/Makefile.am
delete mode 100644 src/gui-gtk/main.c
diff --git a/configure.ac b/configure.ac
index 07d2f02..b04a5aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -187,7 +187,6 @@ AC_CONFIG_FILES([
src/daemon/Makefile
src/hooks/Makefile
src/applet/Makefile
- src/gui-gtk/Makefile
src/cli/Makefile
src/dbus/Makefile
src/plugins/abrt-action-install-debuginfo
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4f070a6..c54004b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,7 +8,6 @@ src/daemon/abrt-server.c
src/dbus/abrt-dbus.c
src/daemon/abrtd.c
src/daemon/abrt-handle-event.c
-src/gui-gtk/main.c
src/lib/abrt_conf.c
src/lib/hooklib.c
src/lib/problem_api.c
diff --git a/src/Makefile.am b/src/Makefile.am
index ebf2a6f..b7da68f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1 +1 @@
-SUBDIRS = include lib hooks daemon applet gui-gtk plugins cli dbus python-problem
+SUBDIRS = include lib hooks daemon applet plugins cli dbus python-problem
diff --git a/src/gui-gtk/Makefile.am b/src/gui-gtk/Makefile.am
deleted file mode 100644
index 2274a41..0000000
--- a/src/gui-gtk/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-bin_PROGRAMS = abrt-gui
-
-abrt_gui_SOURCES = \
- main.c
-abrt_gui_CFLAGS = \
- -I$(srcdir)/../include \
- -I$(srcdir)/../lib \
- -I$(srcdir)/../gtk-helpers \
- -DBIN_DIR=\"$(bindir)\" \
- -DLIBEXEC_DIR=\"$(libexecdir)\" \
- -DICON_DIR=\"${datadir}/abrt/icons/hicolor/48x48/status\" \
- $(GTK_CFLAGS) \
- $(LIBREPORT_GTK_CFLAGS) \
- -D_GNU_SOURCE \
- $(GIO_CFLAGS)
-# -I/usr/include/glib-2.0
-# -I/usr/lib/glib-2.0/include
-# $(LIBNOTIFY_CFLAGS)
-# $(DBUS_GLIB_CFLAGS)
-abrt_gui_LDADD = \
- -lglib-2.0 \
- -lgthread-2.0 \
- $(GIO_LIBS) \
- $(LIBREPORT_GTK_LIBS) \
- ../lib/libabrt.la \
- $(GTK_LIBS)
-# $(LIBNOTIFY_LIBS)
-
-#test_report_SOURCES = \
-# test_report.c
-#test_report_CPPFLAGS = \
-# -I$(srcdir)/../include/report -I$(srcdir)/../include \
-# $(GLIB_CFLAGS) \
-# -D_GNU_SOURCE
-#test_report_LDADD = \
-# ../lib/libreport.la
-
-DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
diff --git a/src/gui-gtk/main.c b/src/gui-gtk/main.c
deleted file mode 100644
index ea0c2fa..0000000
--- a/src/gui-gtk/main.c
+++ /dev/null
@@ -1,1422 +0,0 @@
-/*
- Copyright (C) 2011 ABRT Team
- Copyright (C) 2011 RedHat inc.
-
- 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; either version 2 of the License, or
- (at your option) any later version.
-
- 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <sys/inotify.h>
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-#include <libreport/internal_libreport_gtk.h>
-#include "libabrt.h"
-#include "abrt-dbus.h"
-
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 22
-# define GDK_KEY_Delete GDK_Delete
-# define GDK_KEY_KP_Delete GDK_KP_Delete
-#endif
-
-/* We used to work with problem dirs directly.
- * Access via dbus was added in order to be able to see
- * (after authorization) problem dirs which are readable
- * only by root. These "root only" problems can also be deleted,
- * or chown'ed and then events can be run on them.
- * (IMO this feature added too much PITA for a rather limited gain.
- * Oh well...)
- */
-
-static void rescan_and_refresh(void);
-
-
-static const char help_uri[] =
-// For released versions, should be similar to:
-//
"http://docs.fedoraproject.org/en-US/Fedora/14/html/Deployment_Guide/ch-abrt.html";
-//
-// This doc (hopefully) matches the most recent code.
-// It is supposed to be kept updated (see doc/deployment/*)
-// and uploaded to
fedorahosted.org:
-"https://fedorahosted.org/releases/a/b/abrt/Deployment_Guide.html";
-
-enum {
- OPT_v = 1 << 0,
- OPT_p = 1 << 1,
- OPT_D = 1 << 2,
-};
-
-static unsigned g_opts;
-
-static int inotify_fd = -1;
-static GIOChannel *channel_inotify;
-static int channel_inotify_event_id = -1;
-static char **s_dirs;
-static int s_signal_pipe[2];
-
-static GtkListStore *s_dumps_list_store;
-static GtkListStore *s_reported_dumps_list_store;
-
-static GtkWidget *s_treeview;
-static GtkWidget *s_reported_treeview;
-static GtkWidget *s_active_treeview;
-static GtkTreePath *s_path_treeview;
-static GtkTreePath *s_path_reported_treeview;
-
-static GtkWidget *g_main_window;
-
-enum
-{
- COLUMN_SOURCE,
- COLUMN_REASON,
- COLUMN_LATEST_CRASH_STR,
- COLUMN_LATEST_CRASH,
- COLUMN_DUMP_DIR,
- COLUMN_DIR_OVER_DBUS,
- COLUMN_REPORTED_TO,
- NUM_COLUMNS
-};
-/* Must match the above enum! Used in gtk_list_store_new() call */
-# define COLUMN_TYPES \
- G_TYPE_STRING, \
- G_TYPE_STRING, \
- G_TYPE_STRING, \
- G_TYPE_INT, \
- G_TYPE_STRING, \
- G_TYPE_INT, \
- G_TYPE_STRING \
-
-/* Whether to try to authorize when getting list of problems */
-static gint g_authorize;
-
-/* Returns malloced copy */
-static char *get_last_line(const char *msg)
-{
- const char *last_eol = strrchr(msg, '\n');
-
- if (!last_eol) /* entire msg is one line? */
- return xstrdup(msg);
-
- if (last_eol[1] != '\0') /* last line is not \n terminated? */
- return xstrdup(last_eol + 1);
-
- /* It's "... \n line \n" and we point to last "\n" */
- const char *end = last_eol;
- /* Walk back */
- while (last_eol > msg)
- {
- if (last_eol[-1] == '\n') /* We found prev "\n" */
- return xstrndup(last_eol, end - last_eol);
- last_eol--;
- }
- /* There is no prev "\n" */
- return xstrndup(last_eol, end - last_eol);
-}
-
-static void show_warning_dialog(const char *message)
-{
- GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(g_main_window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK, /* wizard uses GTK_BUTTONS_CLOSE
instead */
- "%s", message
- );
- gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
-}
-
-static void watch_this_dir(const char *dir_name)
-{
-//TODO: we probably need to remove old watches too...
- if (inotify_fd >= 0 && inotify_add_watch(inotify_fd, dir_name, 0
- // | IN_ATTRIB // Metadata changed
- // | IN_CLOSE_WRITE // File opened for writing was closed
- | IN_CREATE // File/directory created in watched directory
- | IN_DELETE // File/directory deleted from watched directory
- | IN_DELETE_SELF // Watched file/directory was itself deleted
- | IN_MODIFY // File was modified
- | IN_MOVE_SELF // Watched file/directory was itself moved
- | IN_MOVED_FROM // File moved out of watched directory
- | IN_MOVED_TO // File moved into watched directory
- ) < 0)
- {
- /* Missing .abrt/spool is ok, else complain */
- if (errno != ENOENT)
- perror_msg("inotify_add_watch failed on '%s'", dir_name);
- }
-}
-
-/* Returns non 0 if str is NULL or if str consists from white spaces */
-inline static int is_null_or_empty_string(const char *str)
-{
- return !str || skip_whitespace(str)[0] == '\0';
-}
-
-static void add_directory_to_dirlist(const char *problem_dir_path, gpointer data)
-{
- bool use_dbus = (bool)data;
- problem_data_t *pd;
- if (!use_dbus)
- {
- /* Silently ignore *any* errors, not only EACCES.
- * We saw "lock file is locked by process PID" error
- * when we raced with wizard.
- */
- int sv_logmode = logmode;
- logmode = 0;
- struct dump_dir *dd = dd_opendir(problem_dir_path, DD_OPEN_READONLY |
DD_FAIL_QUIETLY_EACCES);
- logmode = sv_logmode;
- if (!dd)
- return;
-//FIXME: this is inefficient. We can instead read only selected elements, not all:
- pd = create_problem_data_from_dump_dir(dd);
- dd_close(dd);
- }
- else
- {
- pd = get_problem_data_dbus(problem_dir_path);
- if (!pd)
- return;
- }
-
- char time_buf[sizeof("YYYY-MM-DD hh:mm:ss")];
- time_buf[0] = '\0';
- const char *time_str = problem_data_get_content_or_NULL(pd, FILENAME_TIME);
- time_t t = 0;
- if (time_str && time_str[0])
- {
- t = strtol(time_str, NULL, 10); /* atoi won't work past 2038! */
- struct tm *ptm = localtime(&t);
- size_t time_len = strftime(time_buf, sizeof(time_buf)-1, "%Y-%m-%d
%H:%M", ptm);
- time_buf[time_len] = '\0';
- }
-
- const char *reason = problem_data_get_content_or_NULL(pd, FILENAME_NOT_REPORTABLE);
- if (is_null_or_empty_string(reason)) /* if problem is NOT not reportable we use
reason */
- {
- reason = problem_data_get_content_or_NULL(pd, FILENAME_REASON);
- if (is_null_or_empty_string(reason)) /* if we don't have reason we use
'N/A' */
- reason = "N/A";
- }
-
- /* the source of the problem:
- * - first we try to load component, as we use it on Fedora
- */
- const char *source = problem_data_get_content_or_NULL(pd, FILENAME_COMPONENT);
- if (is_null_or_empty_string(source)) /* if we don't have component, we fallback
to executable */
- {
- source = problem_data_get_content_or_NULL(pd, FILENAME_EXECUTABLE);
- if (is_null_or_empty_string(source)) /* even if we don't have executable, we
use 'N/A' */
- source = "N/A";
- }
-
- const char *msg = problem_data_get_content_or_NULL(pd, FILENAME_REPORTED_TO);
-
- GtkListStore *list_store = s_dumps_list_store;
- char *subm_status = NULL;
- if (msg)
- {
- list_store = s_reported_dumps_list_store;
- subm_status = get_last_line(msg);
- if (is_null_or_empty_string(subm_status))
- { /* the problem is reported but the submission status is not available */
- /* we have to use 'N/A' string instead of empty string */
- free(subm_status);
- subm_status = xstrdup("N/A");
- }
- }
-
- GtkTreeIter iter;
- gtk_list_store_append(list_store, &iter);
- gtk_list_store_set(list_store, &iter,
- COLUMN_SOURCE, source,
- COLUMN_REASON, reason,
- //OPTION: time format
- COLUMN_LATEST_CRASH_STR, time_buf,
- COLUMN_LATEST_CRASH, t,
- COLUMN_DUMP_DIR, problem_dir_path,
- COLUMN_DIR_OVER_DBUS, (int)use_dbus,
- COLUMN_REPORTED_TO, subm_status,
- -1);
-
- free(subm_status);
- problem_data_free(pd);
-
- VERB1 log("added: %s", problem_dir_path);
-}
-
-static void scan_directory_and_add_to_dirlist(const char *path)
-{
- DIR *dp = opendir(path);
- if (!dp)
- {
- /* We don't want to yell if, say, $HOME/.abrt/spool doesn't exist */
- //perror_msg("Can't open directory '%s'", path);
- return;
- }
-
- struct dirent *dent;
- while ((dent = readdir(dp)) != NULL)
- {
- if (dot_or_dotdot(dent->d_name))
- continue; /* skip "." and ".." */
-
- char *full_name = concat_path_file(path, dent->d_name);
- struct stat statbuf;
- if (stat(full_name, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
- add_directory_to_dirlist(full_name, /*use_dbus:*/ (void*)false);
- free(full_name);
- }
- closedir(dp);
-
- watch_this_dir(path);
-}
-
-static void query_dbus_and_add_to_dirlist(void)
-{
- GList *problem_dirs = get_problems_over_dbus(g_authorize);
-
- if (problem_dirs == ERR_PTR)
- {
- /* One way to trigger this is to temporarily rename
- * dbus socket (/var/run/dbus/system_bus_socket)
- */
- error_msg("Error in DBus communication, falling back to direct access to
'%s'", g_settings_dump_location);
- scan_directory_and_add_to_dirlist(g_settings_dump_location);
- return;
- }
-
- if (problem_dirs)
- {
- g_list_foreach(problem_dirs, (GFunc)add_directory_to_dirlist, /*use_dbus:*/
(void*)true);
- list_free_with_free(problem_dirs);
- }
-
- /* HACK ALERT! We "magically know" that dbus-reported problem dirs
- * live in g_settings_dump_location.
- * Notifications on changes should be implemented to go over dbus too.
- */
- watch_this_dir(g_settings_dump_location);
-}
-
-static void scan_dirs_and_add_to_dirlist(void)
-{
- if (!(g_opts & OPT_D))
- query_dbus_and_add_to_dirlist();
-
- char **argv = s_dirs;
- while (*argv)
- scan_directory_and_add_to_dirlist(*argv++);
-}
-
-static void rescan_dirs_and_add_to_dirlist(void)
-{
- gtk_list_store_clear(s_dumps_list_store);
- gtk_list_store_clear(s_reported_dumps_list_store);
- scan_dirs_and_add_to_dirlist();
-}
-
-
-static GtkTreePath *get_cursor(void)
-{
- GtkTreeView *treeview = GTK_TREE_VIEW(s_treeview);
- GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
- if (selection)
- {
- GtkTreeIter iter;
- GtkTreeModel *store = gtk_tree_view_get_model(treeview);
- if (gtk_tree_selection_get_selected(selection, &store, &iter) == TRUE)
- {
- return gtk_tree_model_get_path(store, &iter);
- }
- }
- return NULL;
-}
-
-static void sanitize_cursor(GtkTreePath *preferred_path)
-{
- GtkTreePath *path;
-
- gtk_tree_view_get_cursor(GTK_TREE_VIEW(s_treeview), &path, /* GtkTreeViewColumn**
*/ NULL);
- if (path)
- {
- /* Cursor exists already */
- goto ret;
- }
-
- if (preferred_path)
- {
- /* Try to position cursor on preferred_path */
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(s_treeview), preferred_path,
- /* GtkTreeViewColumn *focus_column */ NULL, /* start_editing */ false);
-
- /* Did it work? */
- gtk_tree_view_get_cursor(GTK_TREE_VIEW(s_treeview), &path, /*
GtkTreeViewColumn** */ NULL);
- if (path) /* yes */
- goto ret;
- }
-
- /* Try to position cursor on 1st element */
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(s_dumps_list_store), &iter))
- {
- /* We have at least one element, put cursor on it */
-
- /* Get path from iter pointing to 1st element */
- path = gtk_tree_model_get_path(GTK_TREE_MODEL(s_dumps_list_store), &iter);
-
- /* Use it to set cursor */
- gtk_tree_view_set_cursor(GTK_TREE_VIEW(s_treeview), path,
- /* GtkTreeViewColumn *focus_column */ NULL, /* start_editing */ false);
- }
- /* else we have no elements */
-
- ret:
- gtk_tree_path_free(path);
-
- /* Without this, the *header* of the list gets the focus. Ugly. */
- gtk_widget_grab_focus(s_treeview);
-}
-
-
-/* create_main_window and helpers */
-
-static void deactivate_selection(GtkTreeView *tv)
-{
- if (!GTK_IS_TREE_VIEW(tv))
- return;
-
- GtkTreeSelection *selection = gtk_tree_view_get_selection(tv);
- if (selection)
- {
- /* Remember the selection */
- GList *list = gtk_tree_selection_get_selected_rows(selection, /*GtkTreeModel
**model:*/ NULL);
- /* Note: returned list is a copy! We take ownership (IOW: must free it) */
- GtkTreePath **pp_path = NULL;
- if ((void*)tv == (void*)s_treeview)
- pp_path = &s_path_treeview;
- if ((void*)tv == (void*)s_reported_treeview)
- pp_path = &s_path_reported_treeview;
- if (pp_path && list)
- {
- if (*pp_path)
- gtk_tree_path_free(*pp_path);
- *pp_path = list->data;
- list = g_list_delete_link(list, list);
- }
- g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL);
- g_list_free(list);
- /* Deactivate */
- gtk_tree_selection_unselect_all(selection);
- }
-}
-
-/* Contrary to what I expected, this callback is NOT called
- * when I select a row with a mouse.
- * Maybe this callback can be removed.
- */
-static gboolean on_select_cursor_row_cb(
- GtkTreeView *treeview,
- gboolean arg1,
- gpointer user_data)
-{
- //log("SELECT_ROW:%p/%p", treeview, user_data);
- if (GTK_IS_TREE_VIEW(user_data))
- deactivate_selection(GTK_TREE_VIEW(user_data));
-
- return false; /* propagate the event further */
-}
-
-/* Called when I select a row with a mouse (among other cases).
- * Make sure other tv loses its selection.
- */
-static gboolean on_cursor_changed_cb(
- GtkTreeView *treeview,
- gpointer user_data)
-{
- //log("cursor-changed:%p/%p", treeview, user_data);
- if (GTK_IS_TREE_VIEW(user_data))
- deactivate_selection(GTK_TREE_VIEW(user_data));
-
- /* Without this, only <tab>ing to treeview sets s_active_treeview.
- * Thus, selecting a row with mouse and clicking [Open] with mouse
- * wouldn't work!
- */
- s_active_treeview = GTK_WIDGET(treeview);
-
- return false; /* propagate the event further */
-}
-
-/* Called when I <tab> to the treeview
- * Make sure other tv loses its selection.
- * Also, restore selection in current tv if it was desecleted
- * (for example, if we <tab>ed to the other seletion a few sec ago...).
- */
-static gboolean on_focus_cb(
- GtkWidget *widget,
- GtkDirectionType direction,
- gpointer user_data)
-{
- //log("FOCUS:%p/%p", widget, user_data);
- s_active_treeview = widget;
-
- /* Deactivate the other one */
- deactivate_selection(GTK_TREE_VIEW(user_data));
-
- /* Re-activate row in this one if it was deactivated */
- GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
- if (selection && gtk_tree_selection_count_selected_rows(selection) < 1)
- {
- GtkTreePath **pp_path = NULL;
- if (widget == s_treeview)
- pp_path = &s_path_treeview;
- if (widget == s_reported_treeview)
- pp_path = &s_path_reported_treeview;
- if (pp_path && *pp_path)
- {
- gtk_tree_selection_select_path(selection, *pp_path);
- gtk_tree_path_free(*pp_path);
- *pp_path = NULL;
- }
- }
-
- return false; /* propagate the event further */
-}
-
-static const char *current_dirname(int *is_dbus, GtkTreePath **path_p, GtkTreeView
*treeview)
-{
- GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
- if (selection)
- {
- GtkTreeIter iter;
- GtkTreeModel *store = gtk_tree_view_get_model(treeview);
- if (gtk_tree_selection_get_selected(selection, &store, &iter) == TRUE)
- {
- if (path_p)
- *path_p = gtk_tree_model_get_path(store, &iter);
-
- GValue d_dir = { 0 };
- gtk_tree_model_get_value(store, &iter, COLUMN_DUMP_DIR, &d_dir);
- const char *dirname = g_value_get_string(&d_dir);
- if (is_dbus)
- {
- GValue d_int = { 0 };
- gtk_tree_model_get_value(store, &iter, COLUMN_DIR_OVER_DBUS,
&d_int);
- *is_dbus = g_value_get_int(&d_int);
- }
- return dirname;
- }
- }
- return NULL;
-}
-
-static void on_row_activated_cb(GtkTreeView *treeview, GtkTreePath *path,
GtkTreeViewColumn *column, gpointer user_data)
-{
- int is_dbus;
- const char *dirname = current_dirname(&is_dbus, NULL, treeview);
- if (dirname)
- {
- if (!is_dbus || chown_dir_over_dbus(dirname) == 0)
- {
- fflush(NULL); /* paranoia */
- pid_t pid = fork();
- if (pid < 0) /* error */
- perror_msg_and_die("fork");
- if (pid == 0) /* child */
- {
- execl(LIBEXEC_DIR"/abrt-handle-event",
"abrt-handle-event", "-e", "report-gui", "--",
(char *)dirname, NULL);
- /* Child can't use GUI error reporting, we need to clear
g_custom_logger */
- g_custom_logger = NULL;
- perror_msg_and_die("Can't execute '%s'",
LIBEXEC_DIR"/abrt-handle-event");
- }
- }
- /* else: chown_dir_over_dbus already complained */
- }
-}
-
-static void open_problem_data_cb(GtkMenuItem *menuitem, gpointer user_data)
-{
- int is_dbus;
- const char *dirname = current_dirname(&is_dbus, NULL,
GTK_TREE_VIEW(s_active_treeview));
- if (dirname)
- {
- if (is_dbus && chown_dir_over_dbus(dirname) != 0)
- {
- error_msg("Can't chown '%s'", dirname);
- return;
- }
-
- fflush(NULL); /* paranoia */
- pid_t pid = fork();
- if (pid < 0) /* error */
- perror_msg_and_die("fork");
- if (pid == 0) /* child */
- {
- execl(LIBEXEC_DIR"/abrt-handle-event",
"abrt-handle-event", "-e", "open-gui", "--", (char
*)dirname, NULL);
- /* Child can't use GUI error reporting, we need to clear g_custom_logger
*/
- g_custom_logger = NULL;
- perror_msg_and_die("Can't execute '%s'",
LIBEXEC_DIR"/abrt-handle-event");
- }
- }
-}
-
-static void on_btn_report_cb(GtkButton *button, gpointer user_data)
-{
- if (s_active_treeview)
- on_row_activated_cb(GTK_TREE_VIEW(s_active_treeview), NULL, NULL, NULL);
-}
-
-static void on_column_change_cb(GtkTreeSortable *sortable, gpointer user_data)
-{
- const char *name;
- char *value;
- GtkSortType sort_type;
- int col_id;
-
- if (sortable == GTK_TREE_SORTABLE(s_dumps_list_store))
- name = "sort_column";
- else if (sortable == GTK_TREE_SORTABLE(s_reported_dumps_list_store))
- name = "sort_reported_column";
- else
- assert(0);
-
- gtk_tree_sortable_get_sort_column_id(sortable, &col_id, &sort_type);
- if (sort_type == GTK_SORT_ASCENDING)
- col_id = -col_id - 1; /* store ascending sort as negative id */
- value = xasprintf("%d", col_id);
- set_user_setting(name, value);
- free(value);
-}
-
-static void on_show_all_cb(GtkToggleButton *togglebutton, gpointer data)
-{
- g_authorize = gtk_toggle_button_get_active(togglebutton);
- rescan_and_refresh();
-}
-
-static void load_sort_setting(GtkTreeSortable *sortable)
-{
- const char *name, *value;
- GtkSortType sort_type;
- int col_id;
-
- if (sortable == GTK_TREE_SORTABLE(s_dumps_list_store))
- name = "sort_column";
- else if (sortable == GTK_TREE_SORTABLE(s_reported_dumps_list_store))
- name = "sort_reported_column";
- else
- return;
-
- /* defaults */
- col_id = COLUMN_LATEST_CRASH;
- sort_type = GTK_SORT_DESCENDING;
-
- value = get_user_setting(name);
- if (value)
- {
- col_id = xatoi(value);
- if (col_id < 0)
- {
- /* negative id means ascending order */
- col_id = -col_id - 1;
- sort_type = GTK_SORT_ASCENDING;
- }
- }
-
- if (col_id >= NUM_COLUMNS)
- col_id = COLUMN_LATEST_CRASH;
-
- gtk_tree_sortable_set_sort_column_id(sortable, col_id, sort_type);
-}
-
-static void delete_problem(GtkTreeView *treeview)
-{
- GtkTreePath *old_path = NULL;
- int is_dbus;
- const char *dirname = current_dirname(&is_dbus, &old_path,
GTK_TREE_VIEW(s_active_treeview));
- if (dirname)
- {
- VERB1 log("Deleting '%s'", dirname);
-
- //TODO: I plan to implement deleting multiple items at once rhbz#541928
- GList *problem_dir_paths = NULL;
- problem_dir_paths = g_list_append(problem_dir_paths, xstrdup(dirname));
-
- int result;
- if (is_dbus)
- {
- result = delete_problem_dirs_over_dbus(problem_dir_paths);
- }
- else
- {
- result = delete_dump_dir_possibly_using_abrtd(dirname);
- }
- list_free_with_free(problem_dir_paths);
-
- if (result != 0)
- {
- /* Strange. Deletion did not succeed. Someone else deleted it?
- * Rescan the whole list */
- rescan_dirs_and_add_to_dirlist();
- }
-
- /* Try to retain the same cursor position */
- if (old_path)
- {
- sanitize_cursor(old_path);
- gtk_tree_path_free(old_path);
- }
- }
-}
-
-static gint on_key_press_event_cb(GtkTreeView *treeview, GdkEventKey *key, gpointer
unused)
-{
- int k = key->keyval;
-
- if (k == GDK_KEY_Delete || k == GDK_KEY_KP_Delete)
- {
- delete_problem(treeview);
- return TRUE;
- }
- return FALSE;
-}
-
-static void on_btn_delete_cb(GtkButton *button, gpointer unused)
-{
- if (s_active_treeview)
- delete_problem(GTK_TREE_VIEW(s_active_treeview));
-}
-
-static void on_menu_help_cb(GtkMenuItem *menuitem, gpointer unused)
-{
- gtk_show_uri(NULL, help_uri, GDK_CURRENT_TIME, NULL);
-}
-
-static void show_error_dialog(GtkWindow *wnd, const char *summary, const char
*description)
-{
- GtkWidget *dialog = gtk_message_dialog_new(wnd,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- summary);
-
- gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), description);
-
- gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy (dialog);
-}
-
-static void on_button_send_cb(GtkWidget *button, gpointer data)
-{
- GtkWidget *wnd_report = GTK_WIDGET(data);
-
- /* Excpecting that the first child is Vertical Box with all the widgets */
- GList *children = gtk_container_get_children(GTK_CONTAINER(wnd_report));
- GtkContainer *vbox = GTK_CONTAINER(children->data);
- g_list_free(children);
-
- /* Expected content of the children list:
- * Lable Summary
- * Entry Summary
- * TextView Description
- * Button Send
- */
- children = gtk_container_get_children(vbox);
-
- children = g_list_delete_link(children, children);
- GtkEntry *txe_summary = GTK_ENTRY(children->data);
-
- children = g_list_delete_link(children, children);
- GtkTextView *tev = GTK_TEXT_VIEW(children->data);
-
- g_list_free(children);
-
- GtkTextBuffer *buf = gtk_text_view_get_buffer(tev);
- GtkTextIter it_start;
- GtkTextIter it_end;
- gtk_text_buffer_get_start_iter(buf, &it_start);
- gtk_text_buffer_get_end_iter(buf, &it_end);
- gchar *description = gtk_text_buffer_get_text(buf,
- &it_start,
- &it_end,
- false);
-
- if (strlen(description) < 10)
- {
- show_error_dialog(GTK_WINDOW(wnd_report),
- _("The description of problem is too short"),
- _("In order to get more useful reports we "
- "do not accept reports with the description "
- "shorter than 10 letters."));
-
- gtk_widget_grab_focus(GTK_WIDGET(tev));
-
- free(description);
- return;
- }
-
- char *summary = xstrdup(gtk_entry_get_text(txe_summary));
- if (strlen(summary) < 10)
- {
- show_error_dialog(GTK_WINDOW(wnd_report),
- _("The summary of problem is too short"),
- _("In order to get more useful reports we "
- "do not accept reports with the summary "
- "shorter than 10 letters."));
-
- gtk_widget_grab_focus(GTK_WIDGET(txe_summary));
- gtk_editable_set_position(GTK_EDITABLE(txe_summary), strlen(summary));
-
- free(description);
- free(summary);
- return;
- }
-
-
- problem_data_t *pd = problem_data_new();
- problem_data_add_text_noteditable(pd, FILENAME_COMMENT, description);
- problem_data_add_text_noteditable(pd, FILENAME_REASON, summary);
- problem_data_add_text_noteditable(pd, FILENAME_COMPONENT, "abrt");
- char *version = xasprintf("abrt-%s", VERSION);
- problem_data_add_text_noteditable(pd, FILENAME_PACKAGE, version);
-
- /* Must be here because it computes FILENAME_DUPHASH from the content. */
- problem_data_add_basics(pd);
-
- /* why it doesn't want to hide before report ends? */
- gtk_widget_destroy(wnd_report);
-
- report_problem_in_memory(pd, LIBREPORT_NOWAIT | LIBREPORT_GETPID);
-
- free(version);
- free(summary);
- free(description);
- problem_data_free(pd);
-}
-
-static void on_menu_report_cb(GtkMenuItem *menuitem, gpointer unused)
-{
- GtkWidget *wnd_report = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(wnd_report), _("Problem description"));
- gtk_window_set_default_size(GTK_WINDOW(wnd_report), 400, 400);
-
- GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_widget_set_margin_top(vbox, 5);
- gtk_widget_set_margin_left(vbox, 5);
- gtk_widget_set_margin_right(vbox, 5);
-
- GtkWidget *lbl_summary = GTK_WIDGET(gtk_label_new(_("Summary:")));
- gtk_widget_set_halign(lbl_summary, GTK_ALIGN_START);
- gtk_widget_set_margin_left(lbl_summary, 3);
- gtk_widget_set_margin_right(lbl_summary, 3);
-
- GtkWidget *txe_reason = GTK_WIDGET(gtk_entry_new());
-
- GtkWidget *tev = gtk_text_view_new();
- gtk_widget_set_margin_left(tev, 3);
- gtk_widget_set_margin_right(tev, 3);
- gtk_widget_set_can_focus(tev, TRUE);
-
- GtkWidget *btn_send = gtk_button_new_with_label(_("_Send"));
- gtk_button_set_use_underline(GTK_BUTTON(btn_send), TRUE);
- g_signal_connect(btn_send, "clicked", G_CALLBACK(on_button_send_cb),
wnd_report);
-
- /* gtk_box_pack_start(box, widget, expand, fill, padding) */
- gtk_box_pack_start(GTK_BOX(vbox), lbl_summary, FALSE, TRUE, 3);
- gtk_box_pack_start(GTK_BOX(vbox), txe_reason, FALSE, TRUE, 3);
- gtk_box_pack_start(GTK_BOX(vbox), tev, TRUE, TRUE, 5);
- gtk_box_pack_start(GTK_BOX(vbox), btn_send, FALSE, TRUE, 3);
-
- gtk_container_add(GTK_CONTAINER(wnd_report), vbox);
-
- gtk_widget_show_all(wnd_report);
-
- /* Sets text but text is selected :) */
- gtk_entry_set_text(GTK_ENTRY(txe_reason), _("A problem with ABRT"));
- /* Unselect text in txe_entry */
- gtk_editable_set_position(GTK_EDITABLE(txe_reason), 0);
-
- /* Move focus to text view with description of problem */
- gtk_widget_grab_focus(tev);
-}
-
-static void on_menu_about_cb(GtkMenuItem *menuitem, gpointer unused)
-{
- static const char copyright_str[] = "Copyright © 2009, 2010, 2011 Red Hat,
Inc";
-
- static const char license_str[] = "This program is free software; you can
redistribut"
- "e it and/or modify it under the terms of the GNU General Public License
"
- "as published by the Free Software Foundation; either version 2 of the
Li"
- "cense, or (at your option) any later version.\n\nThis program is
distrib"
- "uted in the hope that it will be useful, but WITHOUT ANY WARRANTY;
witho"
- "ut even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICU"
- "LAR PURPOSE. See the GNU General Public License for more
details.\n\nYo"
- "u should have received a copy of the GNU General Public License along
wi"
- "th this program. If not, see <
http://www.gnu.org/licenses/>.";
-
- static const char website_url[] = "https://fedorahosted.org/abrt/";
-
- static const char *authors[] = {
- "Anton Arapov <aarapov(a)redhat.com>",
- "Karel Klic <kklic(a)redhat.com>",
- "Jiri Moskovcak <jmoskovc(a)redhat.com>",
- "Nikola Pajkovsky <npajkovs(a)redhat.com>",
- "Denys Vlasenko <dvlasenk(a)redhat.com>",
- "Michal Toman <mtoman(a)redhat.com>",
- "Zdenek Prikryl",
- NULL
- };
-
- static const char *artists[] = {
- "Patrick Connelly <pcon(a)fedoraproject.org>",
- "Máirín Duffy <duffy(a)fedoraproject.org>",
- "Lapo Calamandrei",
- "Jakub Steinar <jsteiner(a)redhat.com>",
- NULL
- };
-
- GtkWidget *about_d = gtk_about_dialog_new();
-
- gtk_window_set_icon_name(GTK_WINDOW(about_d), "abrt");
- gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_d), VERSION);
- gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(about_d), "abrt");
- gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about_d), "ABRT");
- gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about_d), copyright_str);
- gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about_d), license_str);
- gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(about_d),true);
- gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about_d), website_url);
- gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about_d), authors);
- gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(about_d), artists);
- gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(about_d),
_("translator-credits"));
-
- gtk_window_set_transient_for(GTK_WINDOW(about_d), GTK_WINDOW(g_main_window));
-
- gtk_dialog_run(GTK_DIALOG(about_d));
- gtk_widget_hide(GTK_WIDGET(about_d));
-}
-
-static void show_events_list_dialog_cb(GtkMenuItem *menuitem, gpointer user_data)
-{
- show_config_list_dialog(GTK_WINDOW(g_main_window));
-}
-
-static void add_columns(GtkTreeView *treeview)
-{
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Source"),
- renderer,
- "text",
- COLUMN_SOURCE,
- NULL);
- gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_column_set_sort_column_id(column, COLUMN_SOURCE);
- gtk_tree_view_append_column(treeview, column);
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Problem"),
- renderer,
- "text",
- COLUMN_REASON,
- NULL);
- gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_column_set_sort_column_id(column, COLUMN_REASON);
- gtk_tree_view_append_column(treeview, column);
-
- /*
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Stored in"),
- renderer,
- "text",
- COLUMN_DIRNAME,
- NULL);
- gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_column_set_sort_column_id(column, COLUMN_DIRNAME);
- gtk_tree_view_append_column(treeview, column);
- */
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Last Occurrence"),
- 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);
-}
-
-static void add_columns_reported(GtkTreeView *treeview)
-{
- GtkCellRenderer *renderer;
- GtkTreeViewColumn *column;
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Source"),
- renderer,
- "text",
- COLUMN_SOURCE,
- NULL);
- gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_column_set_sort_column_id(column, COLUMN_SOURCE);
- gtk_tree_view_append_column(treeview, column);
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Problem"),
- renderer,
- "text",
- COLUMN_REASON,
- NULL);
- gtk_tree_view_column_set_resizable(column, TRUE);
- gtk_tree_view_column_set_sort_column_id(column, COLUMN_REASON);
- gtk_tree_view_append_column(treeview, column);
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Date Submitted"),
- 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);
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(_("Submission Result"),
- renderer,
- "text",
- COLUMN_REPORTED_TO,
- NULL);
- //gtk_tree_view_column_set_sort_column_id(column, COLUMN_LATEST_CRASH);
- gtk_tree_view_append_column(treeview, column);
-}
-
-void on_quit_cb(GtkWidget *widget, gpointer user_data)
-{
- GApplication *app = user_data;
-
- g_application_quit(app);
-}
-
-static GtkWidget *create_menu(GtkApplication *app)
-{
- /* main bar */
- GtkWidget *menu = gtk_menu_bar_new();
- GtkWidget *file_item = gtk_menu_item_new_with_mnemonic(_("_Problem"));
- GtkWidget *edit_item = gtk_menu_item_new_with_mnemonic(_("_Edit"));
- GtkWidget *help_item = gtk_menu_item_new_with_mnemonic(_("_Help"));
-
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), file_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), edit_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), help_item);
-
- /* file submenu */
- GtkWidget *file_submenu = gtk_menu_new();
- GtkWidget *quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
- GtkWidget *report_item = gtk_image_menu_item_new_with_label(_("Report"));
- g_signal_connect(report_item, "activate", G_CALLBACK(on_btn_report_cb),
NULL);
- GtkWidget *open_problem_item = gtk_menu_item_new_with_label(_("Open problem
data"));
- g_signal_connect(open_problem_item, "activate",
G_CALLBACK(open_problem_data_cb), NULL);
-
- gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), report_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), open_problem_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(file_submenu), quit_item);
-
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_submenu);
-
- g_signal_connect(quit_item, "activate", (GCallback)on_quit_cb, app);
-
- /* edit submenu */
- GtkWidget *edit_submenu = gtk_menu_new();
-
- GtkWidget *preferences_item =
gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, NULL);
- gtk_menu_shell_append(GTK_MENU_SHELL(edit_submenu), preferences_item);
- //gtk_menu_shell_append(GTK_MENU_SHELL(edit_submenu), preferences_item);
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit_item), edit_submenu);
-
- g_signal_connect(preferences_item, "activate",
G_CALLBACK(show_events_list_dialog_cb), NULL);
-
- /* help submenu */
- GtkWidget *help_submenu = gtk_menu_new();
- GtkWidget *online_help_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_HELP,
NULL);
- GtkWidget *report_problem_item = gtk_menu_item_new_with_label(_("Report problem
with ABRT"));
- GtkWidget *about_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
- gtk_menu_shell_append(GTK_MENU_SHELL(help_submenu), online_help_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(help_submenu), report_problem_item);
- gtk_menu_shell_append(GTK_MENU_SHELL(help_submenu), about_item);
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_item), help_submenu);
-
- g_signal_connect(online_help_item, "activate", G_CALLBACK(on_menu_help_cb),
NULL);
- g_signal_connect(report_problem_item, "activate",
G_CALLBACK(on_menu_report_cb), NULL);
- g_signal_connect(about_item, "activate", G_CALLBACK(on_menu_about_cb),
NULL);
-
- return menu;
-}
-
-static GtkWidget *create_main_window(GtkApplication *app)
-{
- /* Main window */
- g_main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_default_size(GTK_WINDOW(g_main_window), 700, 700);
- gtk_window_set_title(GTK_WINDOW(g_main_window), _("Automatic Bug Reporting
Tool"));
- gtk_window_set_default_icon_name("abrt");
-
- GtkWidget *main_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- /* add menu */
- gtk_box_pack_start(GTK_BOX(main_vbox), create_menu(app), false, false, 0);
-
- GtkWidget *not_subm_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_set_border_width(GTK_CONTAINER(not_subm_vbox), 10);
- GtkWidget *subm_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- gtk_container_set_border_width(GTK_CONTAINER(subm_vbox), 10);
-
- /* Scrolled region for not reported problems inside main window*/
- GtkWidget *new_problems_scroll_win = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(new_problems_scroll_win),
- GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(new_problems_scroll_win),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- GtkWidget *not_subm_lbl = gtk_label_new(_("Not submitted reports"));
- gtk_misc_set_alignment(GTK_MISC(not_subm_lbl), 0, 0);
- gtk_label_set_markup(GTK_LABEL(not_subm_lbl), _("<b>Not submitted
reports</b>"));
-
- GtkWidget *show_all_btn = gtk_check_button_new_with_label(_("Show all
problems"));
- g_signal_connect(show_all_btn, "toggled", G_CALLBACK(on_show_all_cb),
NULL);
-
- /* add label for not submitted tree view */
- gtk_box_pack_start(GTK_BOX(not_subm_vbox), not_subm_lbl, false, false, 0);
- gtk_box_pack_start(GTK_BOX(not_subm_vbox), new_problems_scroll_win, true, true, 0);
- gtk_box_pack_start(GTK_BOX(main_vbox), not_subm_vbox, true, true, 0);
- gtk_box_pack_start(GTK_BOX(main_vbox), show_all_btn, false, false, 0);
-
- /* Two tree views */
- s_treeview = gtk_tree_view_new();
- s_reported_treeview = gtk_tree_view_new();
-
- /* Tree view inside scrolled region */
- g_object_set(s_treeview, "rules-hint", 1, NULL); /* use alternating colors
*/
- add_columns(GTK_TREE_VIEW(s_treeview));
- gtk_container_add(GTK_CONTAINER(new_problems_scroll_win), s_treeview);
-
- /* Create data store for the list and attach it */
- s_dumps_list_store = gtk_list_store_new(NUM_COLUMNS, COLUMN_TYPES);
-
- load_sort_setting(GTK_TREE_SORTABLE(s_dumps_list_store));
-
- g_signal_connect(GTK_TREE_SORTABLE(s_dumps_list_store),
"sort-column-changed", G_CALLBACK(on_column_change_cb), NULL);
-
- gtk_tree_view_set_model(GTK_TREE_VIEW(s_treeview),
GTK_TREE_MODEL(s_dumps_list_store));
-
- /* Double click/Enter handler */
- g_signal_connect(s_treeview, "row-activated",
G_CALLBACK(on_row_activated_cb), NULL);
- g_signal_connect(s_treeview, "focus", G_CALLBACK(on_focus_cb),
s_reported_treeview);
- g_signal_connect(s_treeview, "select-cursor-row",
G_CALLBACK(on_select_cursor_row_cb), s_reported_treeview);
- g_signal_connect(s_treeview, "cursor-changed",
G_CALLBACK(on_cursor_changed_cb), s_reported_treeview);
- /* Delete handler */
- g_signal_connect(s_treeview, "key-press-event",
G_CALLBACK(on_key_press_event_cb), NULL);
-
- /* scrolled region for reported problems */
- GtkWidget *reported_problems_scroll_win = gtk_scrolled_window_new(NULL, NULL);
-
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(reported_problems_scroll_win),
- GTK_SHADOW_ETCHED_IN);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(reported_problems_scroll_win),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
- GtkWidget *subm_lbl = gtk_label_new(_("Submitted reports"));
- /* align to left */
- gtk_misc_set_alignment(GTK_MISC(subm_lbl), 0, 0);
- gtk_label_set_markup(GTK_LABEL(subm_lbl), _("<b>Submitted
reports</b>"));
-
- /* add label for submitted tree view */
- gtk_box_pack_start(GTK_BOX(subm_vbox), subm_lbl, false, false, 0);
- gtk_box_pack_start(GTK_BOX(subm_vbox), reported_problems_scroll_win, true, true, 0);
- gtk_box_pack_start(GTK_BOX(main_vbox), subm_vbox, true, true, 0);
-
- /* Tree view inside scrolled region */
- g_object_set(s_reported_treeview, "rules-hint", 1, NULL); /* use
alternating colors */
- add_columns_reported(GTK_TREE_VIEW(s_reported_treeview));
- gtk_container_add(GTK_CONTAINER(reported_problems_scroll_win), s_reported_treeview);
-
- /* Create data store for the list and attach it */
- s_reported_dumps_list_store = gtk_list_store_new(NUM_COLUMNS, COLUMN_TYPES);
-
- load_sort_setting(GTK_TREE_SORTABLE(s_reported_dumps_list_store));
-
- g_signal_connect(GTK_TREE_SORTABLE(s_reported_dumps_list_store),
"sort-column-changed", G_CALLBACK(on_column_change_cb), NULL);
-
- gtk_tree_view_set_model(GTK_TREE_VIEW(s_reported_treeview),
GTK_TREE_MODEL(s_reported_dumps_list_store));
-
- /* buttons are homogenous so set size only for one button and it will
- * work for the rest buttons in same gtk_hbox_new() */
- GtkWidget *btn_report = gtk_button_new_with_label(_("Report"));
- gtk_widget_set_size_request(btn_report, 200, 30);
-
- GtkWidget *btn_delete = gtk_button_new_from_stock(GTK_STOCK_DELETE);
-
- GtkWidget *hbox_report_delete = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_box_set_homogeneous(GTK_BOX(hbox_report_delete), true);
- gtk_box_pack_start(GTK_BOX(hbox_report_delete), btn_delete, true, true, 0);
- gtk_box_pack_start(GTK_BOX(hbox_report_delete), btn_report, true, true, 10);
-
- GtkWidget *halign = gtk_alignment_new(1, 0, 0, 0);
- gtk_container_add(GTK_CONTAINER(halign), hbox_report_delete);
-
- gtk_box_pack_start(GTK_BOX(main_vbox), halign, false, false, 10);
-
- /* put the main_vbox to main window */
- gtk_container_add(GTK_CONTAINER(g_main_window), main_vbox);
-
- /* Double click/Enter handler */
- g_signal_connect(s_reported_treeview, "row-activated",
G_CALLBACK(on_row_activated_cb), NULL);
- g_signal_connect(s_reported_treeview, "focus", G_CALLBACK(on_focus_cb),
s_treeview);
- g_signal_connect(s_reported_treeview, "select-cursor-row",
G_CALLBACK(on_select_cursor_row_cb), s_treeview);
- g_signal_connect(s_reported_treeview, "cursor-changed",
G_CALLBACK(on_cursor_changed_cb), s_treeview);
- /* Delete handler */
- g_signal_connect(s_reported_treeview, "key-press-event",
G_CALLBACK(on_key_press_event_cb), NULL);
-
- /* Open and delete button handlers */
- g_signal_connect(btn_report, "clicked", G_CALLBACK(on_btn_report_cb),
NULL);
- g_signal_connect(btn_delete, "clicked", G_CALLBACK(on_btn_delete_cb),
NULL);
-
- /* Quit when user closes the main window */
- g_signal_connect(g_main_window, "destroy", (GCallback)on_quit_cb, app);
-
- return g_main_window;
-}
-
-
-static void rescan_and_refresh(void)
-{
- GtkTreePath *old_path = get_cursor();
- //log("old_path1:'%s'", gtk_tree_path_to_string(old_path)); //leak
-
- rescan_dirs_and_add_to_dirlist();
-
- /* Try to restore cursor position */
- //log("old_path2:'%s'", gtk_tree_path_to_string(old_path)); //leak
- sanitize_cursor(old_path);
- if (old_path)
- gtk_tree_path_free(old_path);
-}
-
-
-static void handle_signal(int signo)
-{
- int save_errno = errno;
-
- // Enable for debugging only, malloc/printf are unsafe in signal handlers
- //VERB3 log("Got signal %d", signo);
-
- uint8_t sig_caught = signo;
- if (write(s_signal_pipe[1], &sig_caught, 1))
- /* we ignore result, if () shuts up stupid compiler */;
-
- errno = save_errno;
-}
-
-static gboolean handle_signal_pipe(GIOChannel *gio, GIOCondition condition, gpointer
ptr_unused)
-{
- /* It can only be SIGCHLD. Therefore we do not check the result,
- * and eat more than one byte at once: why refresh twice?
- */
- gchar buf[16];
- gsize bytes_read;
- g_io_channel_read_chars(gio, buf, sizeof(buf), &bytes_read, NULL);
-
- /* Destroy zombies */
- while (safe_waitpid(-1, NULL, WNOHANG) > 0)
- continue;
-
- rescan_and_refresh();
-
- return TRUE; /* "please don't remove this event" */
-}
-
-
-static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer
ptr_unused);
-
-static void init_notify(void)
-{
- VERB1 log("Initializing inotify");
- errno = 0;
- inotify_fd = inotify_init();
- if (inotify_fd < 0)
- perror_msg("inotify_init failed");
- else
- {
- close_on_exec_on(inotify_fd);
- ndelay_on(inotify_fd);
- VERB1 log("Adding inotify watch to glib main loop");
- channel_inotify = g_io_channel_unix_new(inotify_fd);
- channel_inotify_event_id = g_io_add_watch(channel_inotify,
- G_IO_IN,
- handle_inotify_cb,
- NULL);
- }
-}
-
-#if 0 // UNUSED
-static void close_notify(void)
-{
- if (inotify_fd >= 0)
- {
- //VERB1 log("g_source_remove:");
- g_source_remove(channel_inotify_event_id);
- //VERB1 log("g_io_channel_unref:");
- g_io_channel_unref(channel_inotify);
- //VERB1 log("close(inotify_fd):");
- close(inotify_fd);
- inotify_fd = -1;
- //VERB1 log("Done");
- }
-}
-#endif
-
-/* Inotify handler */
-static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition condition, gpointer
ptr_unused)
-{
- /* Since dump dir creation usually involves directory rename as a last step,
- * we end up rescanning twice. A small wait after first inotify event
- * usually allows to avoid this.
- */
- usleep(10*1000);
-
- /* We read inotify events, but don't analyze them */
- gchar buf[sizeof(struct inotify_event) + PATH_MAX + 64];
- gsize bytes_read;
- while (g_io_channel_read_chars(gio, buf, sizeof(buf), &bytes_read, NULL) ==
G_IO_STATUS_NORMAL
- && bytes_read > 0
- ) {
- continue;
- }
-
- rescan_and_refresh();
-
- return TRUE; /* "please don't remove this event" */
-}
-
-static void activate(GtkApplication *app)
-{
-
- GList *windows = NULL;
-
- windows = gtk_application_get_windows(app);
-
- if (windows)
- {
- gtk_window_present(GTK_WINDOW(windows->data));
- return;
- }
-
- GtkWidget *main_window = create_main_window(app);
- load_abrt_conf();
- load_user_settings("abrt-gui");
-
- init_notify();
-
- scan_dirs_and_add_to_dirlist();
-
- gtk_window_set_application(GTK_WINDOW(main_window), app);
-
- gtk_widget_show_all(main_window);
-
- sanitize_cursor(NULL);
-
- /* Set up signal pipe */
- xpipe(s_signal_pipe);
- close_on_exec_on(s_signal_pipe[0]);
- close_on_exec_on(s_signal_pipe[1]);
- ndelay_on(s_signal_pipe[0]);
- ndelay_on(s_signal_pipe[1]);
- signal(SIGCHLD, handle_signal);
- g_io_add_watch(g_io_channel_unix_new(s_signal_pipe[0]),
- G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- handle_signal_pipe,
- NULL);
-
- g_custom_logger = &show_warning_dialog;
-
- return;
-}
-
-int main(int argc, char **argv)
-{
- /* I18n */
- setlocale(LC_ALL, "");
-#if ENABLE_NLS
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-#endif
-
- abrt_init(argv);
-
- /* without this the name is set to argv[0] which confuses
- * desktops which use the name to find the corresponding .desktop file
- * trac#180
- */
- g_set_prgname("abrt");
-
- gtk_init(&argc, &argv);
-
- /* Can't keep these strings/structs static: _() doesn't support that */
- const char *program_usage_string = _(
- "& [-vpD] [DIR]...\n"
- "\n"
- "Shows list of problem directories in specified DIR(s)\n"
- "and ones saved in system-wide problem directory spool."
- /* don't end last line with "\n"! */
- );
- /* Keep OPT_x enums and order of options below in sync! */
- struct options program_options[] = {
- OPT__VERBOSE(&g_verbose),
- OPT_BOOL( 'p', NULL, NULL , _("Add program names to
log")),
- OPT_BOOL( 'D', NULL, NULL , _("Do not query problems over
dbus (use only DIRs)")),
- OPT_END()
- };
- g_opts = parse_opts(argc, argv, program_options, program_usage_string);
-
- migrate_to_xdg_dirs();
-
- export_abrt_envvars(g_opts & OPT_p);
-
- const char *default_dirs[] = {
- NULL,
- NULL,
- };
- argv += optind;
- if (!argv[0])
- {
- default_dirs[0] = concat_path_file(g_get_user_cache_dir(),
"abrt/spool");
- argv = (char**)default_dirs;
- }
- s_dirs = argv;
-
- GtkApplication *app = NULL;
-
-
- app = gtk_application_new("org.freedesktop.AbrtGui", 0);
- g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);
- gint status;
- status = g_application_run(G_APPLICATION(app), argc, argv);
-
- g_object_unref(app);
-
- save_user_settings();
- free_abrt_conf_data();
-
- return status;
-}
--
1.8.1.4