Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
src/applet/Applet.cpp | 2 +-
src/applet/CCApplet.cpp | 444 -----------------------------------------------
src/applet/CCApplet.h | 70 --------
src/applet/Makefile.am | 2 +-
src/applet/applet_gtk.c | 444 +++++++++++++++++++++++++++++++++++++++++++++++
src/applet/applet_gtk.h | 78 ++++++++
6 files changed, 524 insertions(+), 516 deletions(-)
delete mode 100644 src/applet/CCApplet.cpp
delete mode 100644 src/applet/CCApplet.h
create mode 100644 src/applet/applet_gtk.c
create mode 100644 src/applet/applet_gtk.h
diff --git a/src/applet/Applet.cpp b/src/applet/Applet.cpp
index f347592..15647d2 100644
--- a/src/applet/Applet.cpp
+++ b/src/applet/Applet.cpp
@@ -28,7 +28,7 @@
#include "abrtlib.h"
#include "abrt_dbus.h"
#include "dbus_common.h"
-#include "CCApplet.h"
+#include "applet_gtk.h"
static struct applet* applet = NULL;
diff --git a/src/applet/CCApplet.cpp b/src/applet/CCApplet.cpp
deleted file mode 100644
index aa9d12c..0000000
--- a/src/applet/CCApplet.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc(a)redhat.com)
- Copyright (C) 2009 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.
-*/
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include "abrtlib.h"
-#include "CCApplet.h"
-
-static bool load_icons(struct applet *applet)
-{
- //FIXME: just a tmp workaround
- return false;
- int stage;
- for (stage = ICON_DEFAULT; stage < ICON_STAGE_LAST; stage++)
- {
- char name[sizeof(ICON_DIR"/abrt%02d.png")];
- GError *error = NULL;
- if (snprintf(name, sizeof(ICON_DIR"/abrt%02d.png"),
ICON_DIR"/abrt%02d.png", stage) > 0)
- {
- applet->icon_stages_buff[stage] = gdk_pixbuf_new_from_file(name,
&error);
- if (error != NULL)
- {
- error_msg("Can't load pixbuf from %s, animation is
disabled", name);
- return false;
- }
- }
- }
- return true;
-}
-
-static void stop_animate_icon(struct applet *applet)
-{
- /* animator should be 0 if icons are not loaded, so this should be safe */
- if (applet->animator != 0)
- {
- g_source_remove(applet->animator);
- gtk_status_icon_set_from_pixbuf(applet->status_icon,
- applet->icon_stages_buff[ICON_DEFAULT]
- );
- applet->animator = 0;
- }
-}
-
-//this action should open the reporter dialog directly, without showing the main window
-static void action_report(NotifyNotification *notification, gchar *action, gpointer
user_data)
-{
- struct applet *applet = (struct applet *)user_data;
- if (applet->daemon_running)
- {
- pid_t pid = vfork();
- if (pid < 0)
- perror_msg("vfork");
- if (pid == 0)
- { /* child */
- char *buf = xasprintf("--report=%s", applet->last_crash_id);
- signal(SIGCHLD, SIG_DFL); /* undo SIG_IGN in abrt-applet */
- execl(BIN_DIR"/abrt-gui", "abrt-gui", buf, (char*)
NULL);
- /* Did not find abrt-gui in installation directory. Oh well */
- /* Trying to find it in PATH */
- execlp("abrt-gui", "abrt-gui", buf, (char*) NULL);
- perror_msg_and_die("Can't execute abrt-gui");
- }
- GError *err = NULL;
- notify_notification_close(notification, &err);
- if (err != NULL)
- {
- error_msg("%s", err->message);
- g_error_free(err);
- }
- gtk_status_icon_set_visible(applet->status_icon, false);
- stop_animate_icon(applet);
- }
-}
-
-//this action should open the main window
-static void action_open_gui(NotifyNotification *notification, gchar *action, gpointer
user_data)
-{
- struct applet *applet = (struct applet*)user_data;
- if (applet->daemon_running)
- {
- pid_t pid = vfork();
- if (pid < 0)
- perror_msg("vfork");
- if (pid == 0)
- { /* child */
- signal(SIGCHLD, SIG_DFL); /* undo SIG_IGN in abrt-applet */
- execl(BIN_DIR"/abrt-gui", "abrt-gui", (char*) NULL);
- /* Did not find abrt-gui in installation directory. Oh well */
- /* Trying to find it in PATH */
- execlp("abrt-gui", "abrt-gui", (char*) NULL);
- perror_msg_and_die("Can't execute abrt-gui");
- }
- GError *err = NULL;
- notify_notification_close(notification, &err);
- if (err != NULL)
- {
- error_msg("%s", err->message);
- g_error_free(err);
- }
- gtk_status_icon_set_visible(applet->status_icon, false);
- stop_animate_icon(applet);
- }
-}
-
-static void on_menu_popup_cb(GtkStatusIcon *status_icon,
- guint button,
- guint activate_time,
- gpointer user_data)
-{
- struct applet *applet = (struct applet*)user_data;
- /* stop the animation */
- stop_animate_icon(applet);
-
- if (applet->menu != NULL)
- {
- gtk_menu_popup(GTK_MENU(applet->menu),
- NULL, NULL,
- gtk_status_icon_position_menu,
- status_icon, button, activate_time);
- }
-}
-
-// why it is not named with suffix _cb when it is callback for g_timeout_add?
-static gboolean update_icon(void *user_data)
-{
- struct applet *applet = (struct applet*)user_data;
- if (applet->status_icon && applet->animation_stage <
ICON_STAGE_LAST)
- {
- gtk_status_icon_set_from_pixbuf(applet->status_icon,
-
applet->icon_stages_buff[applet->animation_stage++]);
- }
-
- if (applet->animation_stage == ICON_STAGE_LAST)
- applet->animation_stage = 0;
-
- if (--applet->anim_countdown == 0)
- stop_animate_icon(applet);
-
- return true;
-}
-
-static void animate_icon(struct applet* applet)
-{
- if (applet->animator == 0)
- {
- applet->animator = g_timeout_add(100, update_icon, applet);
- applet->anim_countdown = 10 * 3; /* 3 sec */
- }
-}
-
-static void on_notify_close(NotifyNotification *notification, gpointer user_data)
-{
- g_object_unref(notification);
-}
-
-static NotifyNotification *new_warn_notification()
-{
- NotifyNotification *notification;
- notification = notify_notification_new(_("Warning"), NULL, NULL, NULL);
- g_signal_connect(notification, "closed", G_CALLBACK(on_notify_close),
NULL);
-
- GdkPixbuf *pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
- GTK_STOCK_DIALOG_WARNING, 48, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-
- if (pixbuf)
- notify_notification_set_icon_from_pixbuf(notification, pixbuf);
- notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL);
- notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT);
-
- return notification;
-}
-
-
-static void on_hide_cb(GtkMenuItem *menuitem, gpointer applet)
-{
- if (applet)
- hide_icon((struct applet*)applet);
-}
-
-static void on_about_cb(GtkMenuItem *menuitem, gpointer dialog)
-{
- if (dialog)
- {
- gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_hide(GTK_WIDGET(dialog));
- }
-}
-
-static GtkWidget *create_about_dialog()
-{
- const char *copyright_str = "Copyright © 2009 Red Hat, Inc\nCopyright © 2010 Red
Hat, Inc";
- const char *license_str = "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."
- "\n\nThis 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."
- "\n\nYou should have received a copy of the GNU General
Public License along with this program. If not, see
<
http://www.gnu.org/licenses/>.";
-
- const char *website_url = "https://fedorahosted.org/abrt/";
- 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>",
- "Zdenek Prikryl <zprikryl(a)redhat.com>",
- "Denys Vlasenko <dvlasenk(a)redhat.com>",
- NULL};
-
- const char *artists[] = {"Patrick Connelly
<pcon(a)fedoraproject.org>",
- "Lapo Calamandrei",
- NULL};
-
- const char *comments = _("Notification area applet that notifies users about
"
- "issues detected by ABRT");
- GtkWidget *about_d = gtk_about_dialog_new();
- if (about_d)
- {
- gtk_window_set_default_icon_name("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_comments(GTK_ABOUT_DIALOG(about_d), comments);
- 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"));
- }
- return about_d;
-}
-
-static GtkWidget *create_menu(struct applet *applet)
-{
- GtkWidget *menu = gtk_menu_new();
- GtkWidget *b_quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
- g_signal_connect(b_quit, "activate", gtk_main_quit, NULL);
- GtkWidget *b_hide = gtk_menu_item_new_with_label(_("Hide"));
- g_signal_connect(b_hide, "activate", G_CALLBACK(on_hide_cb), applet);
- GtkWidget *b_about = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
- GtkWidget *about_dialog = create_about_dialog();
- g_signal_connect(b_about, "activate", G_CALLBACK(on_about_cb),
about_dialog);
- GtkWidget *separator = gtk_separator_menu_item_new();
- if (menu)
- {
- gtk_menu_shell_append(GTK_MENU_SHELL(menu),b_hide);
- gtk_widget_show(b_hide);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu),b_about);
- gtk_widget_show(b_about);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu),separator);
- gtk_widget_show(separator);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu),b_quit);
- gtk_widget_show(b_quit);
- }
- return menu;
-}
-
-static void on_applet_activate_cb(GtkStatusIcon *status_icon, gpointer user_data)
-{
- struct applet *applet = (struct applet*)user_data;
- if (applet->daemon_running)
- {
- pid_t pid = vfork();
- if (pid < 0)
- perror_msg("vfork");
- if (pid == 0)
- { /* child */
- signal(SIGCHLD, SIG_DFL); /* undo SIG_IGN in abrt-applet */
- execl(BIN_DIR"/abrt-gui", "abrt-gui", (char*) NULL);
- /* Did not find abrt-gui in installation directory. Oh well */
- /* Trying to find it in PATH */
- execlp("abrt-gui", "abrt-gui", (char*) NULL);
- perror_msg_and_die("Can't execute abrt-gui");
- }
- gtk_status_icon_set_visible(applet->status_icon, false);
- stop_animate_icon(applet);
- }
-}
-
-struct applet *applet_new(const char* app_name)
-{
- struct applet *applet = (struct applet*)xmalloc(sizeof(struct applet));
- applet->daemon_running = true;
- /* set-up icon buffers */
- applet->animator = 0;
- applet->animation_stage = ICON_DEFAULT;
- applet->icons_loaded = load_icons(applet);
- /* - animation - */
- if (applet->icons_loaded == true)
- {
- //FIXME: animation is disabled for now
- applet->status_icon =
gtk_status_icon_new_from_pixbuf(applet->icon_stages_buff[ICON_DEFAULT]);
- }
- else
- applet->status_icon = gtk_status_icon_new_from_icon_name("abrt");
-
- notify_init(app_name);
-
- gtk_status_icon_set_visible(applet->status_icon, FALSE);
-
- g_signal_connect(G_OBJECT(applet->status_icon), "activate",
GTK_SIGNAL_FUNC(on_applet_activate_cb), applet);
- g_signal_connect(G_OBJECT(applet->status_icon), "popup_menu",
GTK_SIGNAL_FUNC(on_menu_popup_cb), applet);
-
-// SetIconTooltip(_("Pending events: %i"), m_mapEvents.size());
-
- applet->menu = create_menu(applet);
- return applet;
-}
-
-void applet_destroy(struct applet *applet)
-{
- if (notify_is_initted())
- notify_uninit();
-
- free(applet);
-}
-
-void set_icon_tooltip(struct applet *applet, const char *format, ...)
-{
- va_list args;
- int n;
- char *buf;
-
- // xvasprintf?
- va_start(args, format);
- buf = NULL;
- n = vasprintf(&buf, format, args);
- va_end(args);
-
- gtk_status_icon_set_tooltip_text(applet->status_icon, (n >= 0 && buf) ?
buf : "");
- free(buf);
-}
-
-void crash_notify(struct applet *applet, const char* crash_id, const char *format, ...)
-{
- applet->last_crash_id = crash_id;
- va_list args;
- va_start(args, format);
- char *buf = xvasprintf(format, args);
- va_end(args);
-
- NotifyNotification *notification = new_warn_notification();
- notify_notification_add_action(notification, "REPORT",
_("Report"),
- NOTIFY_ACTION_CALLBACK(action_report),
- applet, NULL);
- notify_notification_add_action(notification, "OPEN_MAIN_WINDOW",
_("Open ABRT"),
- NOTIFY_ACTION_CALLBACK(action_open_gui),
- applet, NULL);
-
- notify_notification_update(notification, _("Warning"), buf, NULL);
- free(buf);
- GError *err = NULL;
- notify_notification_show(notification, &err);
- if (err != NULL)
- {
- error_msg("%s", err->message);
- g_error_free(err);
- }
-}
-
-void message_notify(struct applet *applet, const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- char *buf = xvasprintf(format, args);
- va_end(args);
-
- /* we don't want to show any buttons now,
- maybe later we can add action binded to message
- like >>Clear old dumps<< for quota exceeded
- */
- NotifyNotification *notification = new_warn_notification();
- notify_notification_add_action(notification, "OPEN_MAIN_WINDOW",
_("Open ABRT"),
- NOTIFY_ACTION_CALLBACK(action_open_gui),
- applet, NULL);
- notify_notification_update(notification, _("Warning"), buf, NULL);
- free(buf);
- GError *err = NULL;
- notify_notification_show(notification, &err);
- if (err != NULL)
- {
- error_msg("%s", err->message);
- g_error_free(err);
- }
-}
-
-void show_icon(struct applet *applet)
-{
- gtk_status_icon_set_visible(applet->status_icon, true);
- /* only animate if all icons are loaded, use the "gtk-warning" instead */
- if (applet->icons_loaded)
- animate_icon(applet);
-}
-
-void hide_icon(struct applet *applet)
-{
- gtk_status_icon_set_visible(applet->status_icon, false);
- stop_animate_icon(applet);
-}
-
-void disable(struct applet *applet, const char *reason)
-{
- /*
- FIXME: once we have our icon
- */
- applet->daemon_running = false;
- GdkPixbuf *gray_scaled;
- GdkPixbuf *pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
- GTK_STOCK_DIALOG_WARNING, 24, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
- if (pixbuf)
- {
- gray_scaled = gdk_pixbuf_copy(pixbuf);
- gdk_pixbuf_saturate_and_pixelate(pixbuf, gray_scaled, 0.0, false);
- gtk_status_icon_set_from_pixbuf(applet->status_icon, gray_scaled);
-//do we need to free pixbufs nere?
- }
- else
- error_msg("Can't load icon");
- set_icon_tooltip(applet, reason);
- show_icon(applet);
-}
-
-void enable(struct applet *applet, const char *reason)
-{
- /* restore the original icon */
- applet->daemon_running = true;
- set_icon_tooltip(applet, reason);
- gtk_status_icon_set_from_stock(applet->status_icon, GTK_STOCK_DIALOG_WARNING);
- show_icon(applet);
-}
diff --git a/src/applet/CCApplet.h b/src/applet/CCApplet.h
deleted file mode 100644
index c8f5da3..0000000
--- a/src/applet/CCApplet.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- Copyright (C) 2009 Jiri Moskovcak (jmoskovc(a)redhat.com)
- Copyright (C) 2009 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.
-*/
-#ifndef CC_APPLET_H_
-#define CC_APPLET_H_
-
-#include <gtk/gtk.h>
-#include <libnotify/notify.h>
-
-enum ICON_STAGES
-{
- ICON_DEFAULT,
- ICON_STAGE1,
- ICON_STAGE2,
- ICON_STAGE3,
- ICON_STAGE4,
- ICON_STAGE5,
- /* this must be always the last */
- ICON_STAGE_LAST
-};
-
-/*
- * What is better name for struct?
- *
- * typedef struct _applet {
- * ...
- * } applet_t;
- *
- * or
- */
-
-struct applet {
- GtkStatusIcon* status_icon;
- GtkWidget *menu;
- bool daemon_running;
- int animation_stage;
- guint animator;
- unsigned anim_countdown;
- bool icons_loaded;
- const char *last_crash_id;
- GdkPixbuf *icon_stages_buff[ICON_STAGE_LAST];
-};
-
-struct applet* applet_new(const char *app_name);
-void applet_destroy(struct applet *applet);
-
-void show_icon(struct applet *applet);
-void hide_icon(struct applet *applet);
-void set_icon_tooltip(struct applet *applet, const char *format, ...);
-void crash_notify(struct applet *applet, const char* crash_id, const char *format, ...);
-void message_notify(struct applet *applet, const char *format, ...);
-void disable(struct applet *applet, const char *reason);
-void enable(struct applet *applet, const char *reason);
-
-#endif
diff --git a/src/applet/Makefile.am b/src/applet/Makefile.am
index 743c18d..55e2873 100644
--- a/src/applet/Makefile.am
+++ b/src/applet/Makefile.am
@@ -2,7 +2,7 @@ bin_PROGRAMS = abrt-applet
abrt_applet_SOURCES = \
Applet.cpp \
- CCApplet.h CCApplet.cpp
+ applet_gtk.h applet_gtk.c
abrt_applet_CPPFLAGS = \
-Wall -Werror \
-I$(srcdir)/../../inc \
diff --git a/src/applet/applet_gtk.c b/src/applet/applet_gtk.c
new file mode 100644
index 0000000..cd8df4d
--- /dev/null
+++ b/src/applet/applet_gtk.c
@@ -0,0 +1,444 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc(a)redhat.com)
+ Copyright (C) 2009 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.
+*/
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "abrtlib.h"
+#include "applet_gtk.h"
+
+static bool load_icons(struct applet *applet)
+{
+ //FIXME: just a tmp workaround
+ return false;
+ int stage;
+ for (stage = ICON_DEFAULT; stage < ICON_STAGE_LAST; stage++)
+ {
+ char name[sizeof(ICON_DIR"/abrt%02d.png")];
+ GError *error = NULL;
+ if (snprintf(name, sizeof(ICON_DIR"/abrt%02d.png"),
ICON_DIR"/abrt%02d.png", stage) > 0)
+ {
+ applet->icon_stages_buff[stage] = gdk_pixbuf_new_from_file(name,
&error);
+ if (error != NULL)
+ {
+ error_msg("Can't load pixbuf from %s, animation is
disabled", name);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static void stop_animate_icon(struct applet *applet)
+{
+ /* animator should be 0 if icons are not loaded, so this should be safe */
+ if (applet->animator != 0)
+ {
+ g_source_remove(applet->animator);
+ gtk_status_icon_set_from_pixbuf(applet->status_icon,
+ applet->icon_stages_buff[ICON_DEFAULT]
+ );
+ applet->animator = 0;
+ }
+}
+
+//this action should open the reporter dialog directly, without showing the main window
+static void action_report(NotifyNotification *notification, gchar *action, gpointer
user_data)
+{
+ struct applet *applet = (struct applet *)user_data;
+ if (applet->daemon_running)
+ {
+ pid_t pid = vfork();
+ if (pid < 0)
+ perror_msg("vfork");
+ if (pid == 0)
+ { /* child */
+ char *buf = xasprintf("--report=%s", applet->last_crash_id);
+ signal(SIGCHLD, SIG_DFL); /* undo SIG_IGN in abrt-applet */
+ execl(BIN_DIR"/abrt-gui", "abrt-gui", buf, (char*)
NULL);
+ /* Did not find abrt-gui in installation directory. Oh well */
+ /* Trying to find it in PATH */
+ execlp("abrt-gui", "abrt-gui", buf, (char*) NULL);
+ perror_msg_and_die("Can't execute abrt-gui");
+ }
+ GError *err = NULL;
+ notify_notification_close(notification, &err);
+ if (err != NULL)
+ {
+ error_msg("%s", err->message);
+ g_error_free(err);
+ }
+ gtk_status_icon_set_visible(applet->status_icon, false);
+ stop_animate_icon(applet);
+ }
+}
+
+//this action should open the main window
+static void action_open_gui(NotifyNotification *notification, gchar *action, gpointer
user_data)
+{
+ struct applet *applet = (struct applet*)user_data;
+ if (applet->daemon_running)
+ {
+ pid_t pid = vfork();
+ if (pid < 0)
+ perror_msg("vfork");
+ if (pid == 0)
+ { /* child */
+ signal(SIGCHLD, SIG_DFL); /* undo SIG_IGN in abrt-applet */
+ execl(BIN_DIR"/abrt-gui", "abrt-gui", (char*) NULL);
+ /* Did not find abrt-gui in installation directory. Oh well */
+ /* Trying to find it in PATH */
+ execlp("abrt-gui", "abrt-gui", (char*) NULL);
+ perror_msg_and_die("Can't execute abrt-gui");
+ }
+ GError *err = NULL;
+ notify_notification_close(notification, &err);
+ if (err != NULL)
+ {
+ error_msg("%s", err->message);
+ g_error_free(err);
+ }
+ gtk_status_icon_set_visible(applet->status_icon, false);
+ stop_animate_icon(applet);
+ }
+}
+
+static void on_menu_popup_cb(GtkStatusIcon *status_icon,
+ guint button,
+ guint activate_time,
+ gpointer user_data)
+{
+ struct applet *applet = (struct applet*)user_data;
+ /* stop the animation */
+ stop_animate_icon(applet);
+
+ if (applet->menu != NULL)
+ {
+ gtk_menu_popup(GTK_MENU(applet->menu),
+ NULL, NULL,
+ gtk_status_icon_position_menu,
+ status_icon, button, activate_time);
+ }
+}
+
+// why it is not named with suffix _cb when it is callback for g_timeout_add?
+static gboolean update_icon(void *user_data)
+{
+ struct applet *applet = (struct applet*)user_data;
+ if (applet->status_icon && applet->animation_stage <
ICON_STAGE_LAST)
+ {
+ gtk_status_icon_set_from_pixbuf(applet->status_icon,
+
applet->icon_stages_buff[applet->animation_stage++]);
+ }
+
+ if (applet->animation_stage == ICON_STAGE_LAST)
+ applet->animation_stage = 0;
+
+ if (--applet->anim_countdown == 0)
+ stop_animate_icon(applet);
+
+ return true;
+}
+
+static void animate_icon(struct applet* applet)
+{
+ if (applet->animator == 0)
+ {
+ applet->animator = g_timeout_add(100, update_icon, applet);
+ applet->anim_countdown = 10 * 3; /* 3 sec */
+ }
+}
+
+static void on_notify_close(NotifyNotification *notification, gpointer user_data)
+{
+ g_object_unref(notification);
+}
+
+static NotifyNotification *new_warn_notification()
+{
+ NotifyNotification *notification;
+ notification = notify_notification_new(_("Warning"), NULL, NULL, NULL);
+ g_signal_connect(notification, "closed", G_CALLBACK(on_notify_close),
NULL);
+
+ GdkPixbuf *pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
+ GTK_STOCK_DIALOG_WARNING, 48, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+
+ if (pixbuf)
+ notify_notification_set_icon_from_pixbuf(notification, pixbuf);
+ notify_notification_set_urgency(notification, NOTIFY_URGENCY_NORMAL);
+ notify_notification_set_timeout(notification, NOTIFY_EXPIRES_DEFAULT);
+
+ return notification;
+}
+
+
+static void on_hide_cb(GtkMenuItem *menuitem, gpointer applet)
+{
+ if (applet)
+ hide_icon((struct applet*)applet);
+}
+
+static void on_about_cb(GtkMenuItem *menuitem, gpointer dialog)
+{
+ if (dialog)
+ {
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_hide(GTK_WIDGET(dialog));
+ }
+}
+
+static GtkWidget *create_about_dialog()
+{
+ const char *copyright_str = "Copyright © 2009 Red Hat, Inc\nCopyright © 2010 Red
Hat, Inc";
+ const char *license_str = "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."
+ "\n\nThis 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."
+ "\n\nYou should have received a copy of the GNU General
Public License along with this program. If not, see
<
http://www.gnu.org/licenses/>.";
+
+ const char *website_url = "https://fedorahosted.org/abrt/";
+ 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>",
+ "Zdenek Prikryl <zprikryl(a)redhat.com>",
+ "Denys Vlasenko <dvlasenk(a)redhat.com>",
+ NULL};
+
+ const char *artists[] = {"Patrick Connelly
<pcon(a)fedoraproject.org>",
+ "Lapo Calamandrei",
+ NULL};
+
+ const char *comments = _("Notification area applet that notifies users about
"
+ "issues detected by ABRT");
+ GtkWidget *about_d = gtk_about_dialog_new();
+ if (about_d)
+ {
+ gtk_window_set_default_icon_name("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_comments(GTK_ABOUT_DIALOG(about_d), comments);
+ 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"));
+ }
+ return about_d;
+}
+
+static GtkWidget *create_menu(struct applet *applet)
+{
+ GtkWidget *menu = gtk_menu_new();
+ GtkWidget *b_quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
+ g_signal_connect(b_quit, "activate", gtk_main_quit, NULL);
+ GtkWidget *b_hide = gtk_menu_item_new_with_label(_("Hide"));
+ g_signal_connect(b_hide, "activate", G_CALLBACK(on_hide_cb), applet);
+ GtkWidget *b_about = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, NULL);
+ GtkWidget *about_dialog = create_about_dialog();
+ g_signal_connect(b_about, "activate", G_CALLBACK(on_about_cb),
about_dialog);
+ GtkWidget *separator = gtk_separator_menu_item_new();
+ if (menu)
+ {
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),b_hide);
+ gtk_widget_show(b_hide);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),b_about);
+ gtk_widget_show(b_about);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),separator);
+ gtk_widget_show(separator);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),b_quit);
+ gtk_widget_show(b_quit);
+ }
+ return menu;
+}
+
+static void on_applet_activate_cb(GtkStatusIcon *status_icon, gpointer user_data)
+{
+ struct applet *applet = (struct applet*)user_data;
+ if (applet->daemon_running)
+ {
+ pid_t pid = vfork();
+ if (pid < 0)
+ perror_msg("vfork");
+ if (pid == 0)
+ { /* child */
+ signal(SIGCHLD, SIG_DFL); /* undo SIG_IGN in abrt-applet */
+ execl(BIN_DIR"/abrt-gui", "abrt-gui", (char*) NULL);
+ /* Did not find abrt-gui in installation directory. Oh well */
+ /* Trying to find it in PATH */
+ execlp("abrt-gui", "abrt-gui", (char*) NULL);
+ perror_msg_and_die("Can't execute abrt-gui");
+ }
+ gtk_status_icon_set_visible(applet->status_icon, false);
+ stop_animate_icon(applet);
+ }
+}
+
+struct applet *applet_new(const char* app_name)
+{
+ struct applet *applet = (struct applet*)xmalloc(sizeof(struct applet));
+ applet->daemon_running = true;
+ /* set-up icon buffers */
+ applet->animator = 0;
+ applet->animation_stage = ICON_DEFAULT;
+ applet->icons_loaded = load_icons(applet);
+ /* - animation - */
+ if (applet->icons_loaded == true)
+ {
+ //FIXME: animation is disabled for now
+ applet->status_icon =
gtk_status_icon_new_from_pixbuf(applet->icon_stages_buff[ICON_DEFAULT]);
+ }
+ else
+ applet->status_icon = gtk_status_icon_new_from_icon_name("abrt");
+
+ notify_init(app_name);
+
+ gtk_status_icon_set_visible(applet->status_icon, FALSE);
+
+ g_signal_connect(G_OBJECT(applet->status_icon), "activate",
GTK_SIGNAL_FUNC(on_applet_activate_cb), applet);
+ g_signal_connect(G_OBJECT(applet->status_icon), "popup_menu",
GTK_SIGNAL_FUNC(on_menu_popup_cb), applet);
+
+// SetIconTooltip(_("Pending events: %i"), m_mapEvents.size());
+
+ applet->menu = create_menu(applet);
+ return applet;
+}
+
+void applet_destroy(struct applet *applet)
+{
+ if (notify_is_initted())
+ notify_uninit();
+
+ free(applet);
+}
+
+void set_icon_tooltip(struct applet *applet, const char *format, ...)
+{
+ va_list args;
+ int n;
+ char *buf;
+
+ // xvasprintf?
+ va_start(args, format);
+ buf = NULL;
+ n = vasprintf(&buf, format, args);
+ va_end(args);
+
+ gtk_status_icon_set_tooltip_text(applet->status_icon, (n >= 0 && buf) ?
buf : "");
+ free(buf);
+}
+
+void crash_notify(struct applet *applet, const char* crash_id, const char *format, ...)
+{
+ applet->last_crash_id = crash_id;
+ va_list args;
+ va_start(args, format);
+ char *buf = xvasprintf(format, args);
+ va_end(args);
+
+ NotifyNotification *notification = new_warn_notification();
+ notify_notification_add_action(notification, "REPORT",
_("Report"),
+ NOTIFY_ACTION_CALLBACK(action_report),
+ applet, NULL);
+ notify_notification_add_action(notification, "OPEN_MAIN_WINDOW",
_("Open ABRT"),
+ NOTIFY_ACTION_CALLBACK(action_open_gui),
+ applet, NULL);
+
+ notify_notification_update(notification, _("Warning"), buf, NULL);
+ free(buf);
+ GError *err = NULL;
+ notify_notification_show(notification, &err);
+ if (err != NULL)
+ {
+ error_msg("%s", err->message);
+ g_error_free(err);
+ }
+}
+
+void message_notify(struct applet *applet, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ char *buf = xvasprintf(format, args);
+ va_end(args);
+
+ /* we don't want to show any buttons now,
+ maybe later we can add action binded to message
+ like >>Clear old dumps<< for quota exceeded
+ */
+ NotifyNotification *notification = new_warn_notification();
+ notify_notification_add_action(notification, "OPEN_MAIN_WINDOW",
_("Open ABRT"),
+ NOTIFY_ACTION_CALLBACK(action_open_gui),
+ applet, NULL);
+ notify_notification_update(notification, _("Warning"), buf, NULL);
+ free(buf);
+ GError *err = NULL;
+ notify_notification_show(notification, &err);
+ if (err != NULL)
+ {
+ error_msg("%s", err->message);
+ g_error_free(err);
+ }
+}
+
+void show_icon(struct applet *applet)
+{
+ gtk_status_icon_set_visible(applet->status_icon, true);
+ /* only animate if all icons are loaded, use the "gtk-warning" instead */
+ if (applet->icons_loaded)
+ animate_icon(applet);
+}
+
+void hide_icon(struct applet *applet)
+{
+ gtk_status_icon_set_visible(applet->status_icon, false);
+ stop_animate_icon(applet);
+}
+
+void disable(struct applet *applet, const char *reason)
+{
+ /*
+ FIXME: once we have our icon
+ */
+ applet->daemon_running = false;
+ GdkPixbuf *gray_scaled;
+ GdkPixbuf *pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(),
+ GTK_STOCK_DIALOG_WARNING, 24, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+ if (pixbuf)
+ {
+ gray_scaled = gdk_pixbuf_copy(pixbuf);
+ gdk_pixbuf_saturate_and_pixelate(pixbuf, gray_scaled, 0.0, false);
+ gtk_status_icon_set_from_pixbuf(applet->status_icon, gray_scaled);
+//do we need to free pixbufs nere?
+ }
+ else
+ error_msg("Can't load icon");
+ set_icon_tooltip(applet, reason);
+ show_icon(applet);
+}
+
+void enable(struct applet *applet, const char *reason)
+{
+ /* restore the original icon */
+ applet->daemon_running = true;
+ set_icon_tooltip(applet, reason);
+ gtk_status_icon_set_from_stock(applet->status_icon, GTK_STOCK_DIALOG_WARNING);
+ show_icon(applet);
+}
diff --git a/src/applet/applet_gtk.h b/src/applet/applet_gtk.h
new file mode 100644
index 0000000..22e9c2a
--- /dev/null
+++ b/src/applet/applet_gtk.h
@@ -0,0 +1,78 @@
+/*
+ Copyright (C) 2009 Jiri Moskovcak (jmoskovc(a)redhat.com)
+ Copyright (C) 2009 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.
+*/
+#ifndef CC_APPLET_H_
+#define CC_APPLET_H_
+
+#include <gtk/gtk.h>
+#include <libnotify/notify.h>
+
+enum ICON_STAGES
+{
+ ICON_DEFAULT,
+ ICON_STAGE1,
+ ICON_STAGE2,
+ ICON_STAGE3,
+ ICON_STAGE4,
+ ICON_STAGE5,
+ /* this must be always the last */
+ ICON_STAGE_LAST
+};
+
+/*
+ * What is better name for struct?
+ *
+ * typedef struct _applet {
+ * ...
+ * } applet_t;
+ *
+ * or
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct applet {
+ GtkStatusIcon* status_icon;
+ GtkWidget *menu;
+ bool daemon_running;
+ int animation_stage;
+ guint animator;
+ unsigned anim_countdown;
+ bool icons_loaded;
+ const char *last_crash_id;
+ GdkPixbuf *icon_stages_buff[ICON_STAGE_LAST];
+};
+
+struct applet* applet_new(const char *app_name);
+void applet_destroy(struct applet *applet);
+
+void show_icon(struct applet *applet);
+void hide_icon(struct applet *applet);
+void set_icon_tooltip(struct applet *applet, const char *format, ...);
+void crash_notify(struct applet *applet, const char* crash_id, const char *format, ...);
+void message_notify(struct applet *applet, const char *format, ...);
+void disable(struct applet *applet, const char *reason);
+void enable(struct applet *applet, const char *reason);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--
1.7.1