/* Notification plugin for Claws-Mail
* Copyright (C) 2005-2007 Holger Berndt and the Claws Mail Team.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
/* This module is of course inspired by the trayicon plugin which is
* shipped with Claws-Mail, copyrighted by the Claws-Mail Team. */
#include "pluginconfig.h"
#ifdef NOTIFICATION_TRAYICON
#include "notification_trayicon.h"
#include "notification_prefs.h"
#include "notification_core.h"
#include "notification_pixbuf.h"
#include "notification_foldercheck.h"
#include "gettext.h"
#include "main.h"
#include "mainwindow.h"
#include "prefs_common.h"
#include "alertpanel.h"
#include "menu.h"
#include "gtk/manage_window.h"
static GdkPixbuf* notification_trayicon_create(void);
static void notification_trayicon_on_activate(GtkStatusIcon*, gpointer);
static void notification_trayicon_on_popup_menu(GtkStatusIcon*,guint,
guint,gpointer);
static gboolean notification_trayicon_on_size_changed(GtkStatusIcon*,
gint, gpointer);
static void trayicon_get_all_cb(gpointer, guint, GtkWidget*);
static void trayicon_compose_cb(gpointer, guint, GtkWidget*);
static void trayicon_compose_acc_cb(GtkMenuItem*, gpointer);
static void trayicon_addressbook_cb(gpointer, guint, GtkWidget*);
static void trayicon_exit_cb(gpointer, guint, GtkWidget*);
static void trayicon_toggle_offline_cb(gpointer, guint, GtkWidget*);
#ifdef HAVE_LIBNOTIFY
static void trayicon_toggle_notify_cb(gpointer, guint, GtkWidget*);
#endif
#ifdef HAVE_LIBNOTIFY
#include <libnotify/notify.h>
typedef struct {
gint count;
gint num_mail;
gint num_news;
gint num_calendar;
gint num_rss;
gchar *msg_path;
guint timeout_id;
NotifyNotification *notification;
GError *error;
} NotificationTrayiconPopup;
static NotificationTrayiconPopup popup;
static gboolean notification_trayicon_popup_add_msg(MsgInfo*,
NotificationFolderType);
static gboolean notification_trayicon_popup_create(MsgInfo*,
NotificationFolderType);
static gboolean popup_timeout_fun(gpointer);
static void notification_trayicon_popup_free_func(gpointer);
static void notification_trayicon_popup_default_action_cb(NotifyNotification*,
const char*,void*);
static gchar* notification_trayicon_popup_assemble_summary(void);
static gchar* notification_trayicon_popup_assemble_body(MsgInfo*);
static void notification_trayicon_popup_count_msgs(NotificationFolderType);
G_LOCK_DEFINE_STATIC(trayicon_popup);
#endif
static GtkStatusIcon *trayicon;
static gboolean updating_menu = FALSE;
static GtkWidget *traymenu_popup;
static GtkItemFactory *traymenu_factory;
static GtkItemFactoryEntry trayicon_popup_menu_entries[] = {
{N_("/_Get Mail"), NULL,trayicon_get_all_cb, 0, NULL},
{"/---", NULL,NULL, 0, "<Separator>"},
{N_("/_Email"), NULL,trayicon_compose_cb, 0, NULL},
{N_("/_Email from account"),NULL,NULL, 0, "<Branch>"},
{"/---", NULL,NULL, 0, "<Separator>"},
{N_("/Open A_ddressbook"), NULL,trayicon_addressbook_cb, 0, NULL},
{"/---", NULL,NULL, 0, "<Separator>"},
#ifdef HAVE_LIBNOTIFY
{N_("/Show Trayicon Notifications"), NULL,trayicon_toggle_notify_cb, 0, "<CheckItem>"},
#endif
{N_("/_Work Offline"), NULL,trayicon_toggle_offline_cb,0, "<CheckItem>"},
{"/---", NULL,NULL, 0, "<Separator>"},
{N_("/E_xit Claws Mail"), NULL,trayicon_exit_cb, 0, NULL}
};
void notification_trayicon_msg(MsgInfo *msginfo)
{
#ifndef HAVE_LIBNOTIFY
return;
#else
FolderType ftype;
NotificationFolderType nftype;
gchar *uistr;
nftype = F_TYPE_MAIL;
if(!msginfo || !notify_config.trayicon_enabled ||
!notify_config.trayicon_popup_enabled ||
!MSG_IS_NEW(msginfo->flags))
return;
if(notify_config.trayicon_popup_folder_specific) {
guint id;
GSList *list;
gchar *identifier;
gboolean found = FALSE;
if(!(msginfo->folder))
return;
identifier = folder_item_get_identifier(msginfo->folder);
id =
notification_register_folder_specific_list
(TRAYICON_POPUP_SPECIFIC_FOLDER_ID_STR);
list = notification_foldercheck_get_list(id);
for(; (list != NULL) && !found; list = g_slist_next(list)) {
gchar *list_identifier;
FolderItem *list_item = (FolderItem*) list->data;
list_identifier = folder_item_get_identifier(list_item);
if(!strcmp2(list_identifier, identifier))
found = TRUE;
g_free(list_identifier);
}
g_free(identifier);
if(!found)
return;
} /* folder specific */
ftype = msginfo->folder->folder->klass->type;
G_LOCK(trayicon_popup);
/* Check out which type to notify about */
switch(ftype) {
case F_MH:
case F_MBOX:
case F_MAILDIR:
case F_IMAP:
nftype = F_TYPE_MAIL;
break;
case F_NEWS:
nftype = F_TYPE_NEWS;
break;
case F_UNKNOWN:
if((uistr = msginfo->folder->folder->klass->uistr) == NULL) {
G_UNLOCK(trayicon_popup);
return;
}
else if(!strcmp(uistr, "vCalendar"))
nftype = F_TYPE_CALENDAR;
else if(!strcmp(uistr, "RSSyl"))
nftype = F_TYPE_RSS;
else {
debug_print("Notification Plugin: Unknown folder type %d\n",ftype);
G_UNLOCK(trayicon_popup);
return;
}
break;
default:
debug_print("Notification Plugin: Unknown folder type %d\n",ftype);
G_UNLOCK(trayicon_popup);
return;
}
if(notification_trayicon_popup_add_msg(msginfo, nftype)) {
if(popup.timeout_id)
g_source_remove(popup.timeout_id);
popup.timeout_id = g_timeout_add(notify_config.trayicon_popup_timeout,
popup_timeout_fun, NULL);
}
G_UNLOCK(trayicon_popup);
#endif /* HAVE_LIBNOTIFY */
}
void notification_trayicon_destroy(void)
{
if(trayicon) {
g_object_unref(trayicon);
trayicon = NULL;
}
}
void notification_update_trayicon(guint new_msgs, guint unread_msgs,
guint unreadmarked_msgs, guint marked_msgs,
guint total_msgs)
{
gchar *buf;
static GdkPixbuf *old_icon = NULL;
GdkPixbuf *new_icon;
gint offset;
if(!notify_config.trayicon_enabled)
return;
if(!trayicon) {
old_icon = notification_trayicon_create();
if(!trayicon) {
debug_print("Notification plugin: Could not create trayicon\n");
return;
}
}
/* Tooltip */
buf = g_strdup_printf(_("New %d, Unread: %d, Total: %d"),
new_msgs, unread_msgs, total_msgs);
gtk_status_icon_set_tooltip(trayicon, buf);
g_free(buf);
/* Pixmap */
(prefs_common.work_offline) ? (offset = 1) : (offset = 0);
if((new_msgs > 0) && (unreadmarked_msgs > 0))
new_icon =
notification_pixbuf_get(NOTIFICATION_TRAYICON_NEWMARKEDMAIL+offset);
else if(new_msgs > 0)
new_icon =
notification_pixbuf_get(NOTIFICATION_TRAYICON_NEWMAIL+offset);
else if(unreadmarked_msgs > 0)
new_icon =
notification_pixbuf_get(NOTIFICATION_TRAYICON_UNREADMARKEDMAIL+offset);
else if(unread_msgs > 0)
new_icon =
notification_pixbuf_get(NOTIFICATION_TRAYICON_UNREADMAIL+offset);
else
new_icon =
notification_pixbuf_get(NOTIFICATION_TRAYICON_NOMAIL+offset);
if(new_icon != old_icon) {
gtk_status_icon_set_from_pixbuf(trayicon, new_icon);
old_icon = new_icon;
}
}
gboolean notification_trayicon_main_window_close(gpointer source, gpointer data)
{
if(!notify_config.trayicon_enabled)
return FALSE;
if(source) {
gboolean *close_allowed = (gboolean*)source;
if(notify_config.trayicon_close_to_tray) {
MainWindow *mainwin = mainwindow_get_mainwindow();
*close_allowed = FALSE;
if(mainwin && GTK_WIDGET_VISIBLE(GTK_WIDGET(mainwin->window)))
main_window_hide(mainwin);
}
}
return FALSE;
}
gboolean notification_trayicon_main_window_got_iconified(gpointer source,
gpointer data)
{
MainWindow *mainwin = mainwindow_get_mainwindow();
if(!notify_config.trayicon_enabled)
return FALSE;
if(notify_config.trayicon_hide_when_iconified &&
mainwin && GTK_WIDGET_VISIBLE(GTK_WIDGET(mainwin->window))
&& !gtk_window_get_skip_taskbar_hint(GTK_WINDOW(mainwin->window))) {
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwin->window), TRUE);
}
return FALSE;
}
gboolean notification_trayicon_account_list_changed(gpointer source,
gpointer data)
{
GList *cur_ac, *cur_item = NULL;
GtkWidget *menu;
GtkWidget *menuitem;
PrefsAccount *ac_prefs;
GList *account_list = account_get_list();
if(!notify_config.trayicon_enabled)
return FALSE;
menu = gtk_item_factory_get_widget(traymenu_factory,
"/Email from account");
/* destroy all previous menu item */
cur_item = GTK_MENU_SHELL(menu)->children;
while(cur_item != NULL) {
GList *next = cur_item->next;
gtk_widget_destroy(GTK_WIDGET(cur_item->data));
cur_item = next;
}
for(cur_ac = account_list; cur_ac != NULL; cur_ac = cur_ac->next) {
ac_prefs = (PrefsAccount *)cur_ac->data;
menuitem = gtk_menu_item_new_with_label
(ac_prefs->account_name ? ac_prefs->account_name
: _("Untitled"));
gtk_widget_show(menuitem);
gtk_menu_append(GTK_MENU(menu), menuitem);
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(trayicon_compose_acc_cb),
ac_prefs);
}
return FALSE;
}
static GdkPixbuf* notification_trayicon_create(void)
{
GdkPixbuf *trayicon_nomail;
gint n_entries = 0;
trayicon_nomail = notification_pixbuf_get(NOTIFICATION_TRAYICON_NOMAIL);
notification_trayicon_destroy();
trayicon = gtk_status_icon_new_from_pixbuf(trayicon_nomail);
g_signal_connect(G_OBJECT(trayicon), "activate",
G_CALLBACK(notification_trayicon_on_activate), NULL);
g_signal_connect(G_OBJECT(trayicon), "popup-menu",
G_CALLBACK(notification_trayicon_on_popup_menu), NULL);
g_signal_connect(G_OBJECT(trayicon), "size-changed",
G_CALLBACK(notification_trayicon_on_size_changed), NULL);
/* Popup-Menu */
n_entries = sizeof(trayicon_popup_menu_entries) /
sizeof(trayicon_popup_menu_entries[0]);
traymenu_popup = menu_create_items(trayicon_popup_menu_entries,
n_entries, "<TrayiconMenu>", &traymenu_factory,
NULL);
return trayicon_nomail;
}
/* Hide/show main window */
static void notification_trayicon_on_activate(GtkStatusIcon *status_icon,
gpointer user_data)
{
MainWindow *mainwin;
if((mainwin = mainwindow_get_mainwindow()) == NULL)
return;
if(GTK_WIDGET_VISIBLE(GTK_WIDGET(mainwin->window))) {
if((gdk_window_get_state(GTK_WIDGET(mainwin->window)->window)&GDK_WINDOW_STATE_ICONIFIED)
|| mainwindow_is_obscured()) {
gtk_window_deiconify(GTK_WINDOW(mainwin->window));
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwin->window), FALSE);
main_window_show(mainwin);
gtk_window_present(GTK_WINDOW(mainwin->window));
}
else {
main_window_hide(mainwin);
}
}
else {
gtk_window_deiconify(GTK_WINDOW(mainwin->window));
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwin->window), FALSE);
main_window_show(mainwin);
gtk_window_present(GTK_WINDOW(mainwin->window));
}
}
static void notification_trayicon_on_popup_menu(GtkStatusIcon *status_icon,
guint button, guint activate_time,
gpointer user_data)
{
MainWindow *mainwin = mainwindow_get_mainwindow();
if(!mainwin)
return;
/* tell callbacks to skip any event */
updating_menu = TRUE;
/* initialize checkitems according to current states */
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item
(traymenu_factory, "/Work Offline")),
prefs_common.work_offline);
#ifdef HAVE_LIBNOTIFY
gtk_check_menu_item_set_active
(GTK_CHECK_MENU_ITEM(gtk_item_factory_get_item
(traymenu_factory, "/Show Trayicon Notifications")),
notify_config.trayicon_popup_enabled);
#endif
gtk_widget_set_sensitive(GTK_WIDGET(gtk_item_factory_get_item(traymenu_factory,
"/Get Mail")),
mainwin->lock_count == 0);
updating_menu = FALSE;
gtk_menu_popup(GTK_MENU(traymenu_popup), NULL, NULL, NULL, NULL,
button, activate_time);
}
static gboolean notification_trayicon_on_size_changed(GtkStatusIcon *icon,
gint size,
gpointer user_data)
{
notification_update_msg_counts(NULL);
return FALSE;
}
/* popup menu callbacks */
static void trayicon_get_all_cb( gpointer data, guint action, GtkWidget *widget )
{
MainWindow *mainwin = mainwindow_get_mainwindow();
inc_all_account_mail_cb(mainwin, 0, NULL);
}
static void trayicon_compose_cb( gpointer data, guint action, GtkWidget *widget )
{
MainWindow *mainwin = mainwindow_get_mainwindow();
compose_mail_cb(mainwin, 0, NULL);
}
static void trayicon_compose_acc_cb( GtkMenuItem *menuitem, gpointer data )
{
compose_new((PrefsAccount *)data, NULL, NULL);
}
static void trayicon_addressbook_cb(gpointer data, guint action,
GtkWidget *widget)
{
addressbook_open(NULL);
}
static void trayicon_toggle_offline_cb(gpointer data, guint action,
GtkWidget *widget)
{
/* toggle offline mode if menu checkitem has been clicked */
if(!updating_menu) {
MainWindow *mainwin = mainwindow_get_mainwindow();
main_window_toggle_work_offline(mainwin, !prefs_common.work_offline, TRUE);
}
}
#ifdef HAVE_LIBNOTIFY
static void trayicon_toggle_notify_cb(gpointer data, guint action,
GtkWidget *widget)
{
if(!updating_menu) {
notify_config.trayicon_popup_enabled = !notify_config.trayicon_popup_enabled;
}
}
#endif
static void app_exit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
{
if(prefs_common.confirm_on_exit) {
if(alertpanel(_("Exit"), _("Exit Claws Mail?"),
GTK_STOCK_CANCEL, GTK_STOCK_OK,
NULL) != G_ALERTALTERNATE) {
return;
}
manage_window_focus_in(mainwin->window, NULL, NULL);
}
app_will_exit(NULL, mainwin);
}
static void trayicon_exit_cb( gpointer data, guint action, GtkWidget *widget )
{
MainWindow *mainwin = mainwindow_get_mainwindow();
if(mainwin->lock_count == 0) {
app_exit_cb(mainwin, 0, NULL);
}
}
#ifdef HAVE_LIBNOTIFY
static gboolean notification_trayicon_popup_add_msg(MsgInfo *msginfo,
NotificationFolderType nftype)
{
gchar *summary;
gchar *utf8_str;
gboolean retval;
g_return_val_if_fail(msginfo, FALSE);
if(!popup.notification)
return notification_trayicon_popup_create(msginfo,nftype);
/* Count messages */
notification_trayicon_popup_count_msgs(nftype);
if(popup.msg_path) {
g_free(popup.msg_path);
popup.msg_path = NULL;
}
summary = notification_trayicon_popup_assemble_summary();
utf8_str = notification_trayicon_popup_assemble_body(msginfo);
retval = notify_notification_update(popup.notification, summary,
utf8_str, NULL);
g_free(summary);
g_free(utf8_str);
if(!retval) {
debug_print("Notification Plugin: Failed to update notification.\n");
return FALSE;
}
/* Show the popup */
if(!notify_notification_show(popup.notification, &(popup.error))) {
debug_print("Notification Plugin: Failed to send updated notification: "
"%s\n", popup.error->message);
g_clear_error(&(popup.error));
return FALSE;
}
debug_print("Notification Plugin: Popup successfully modified "
"with libnotify.\n");
return TRUE;
}
static gboolean notification_trayicon_popup_create(MsgInfo *msginfo,
NotificationFolderType nftype)
{
gchar *summary = NULL;
gchar *utf8_str = NULL;
GdkPixbuf *pixbuf;
/* init libnotify if necessary */
if(!notify_is_initted()) {
if(!notify_init("claws-mail")) {
debug_print("Notification Plugin: Failed to initialize libnotify. "
"No popups will be shown.\n");
return FALSE;
}
}
/* Count messages */
notification_trayicon_popup_count_msgs(nftype);
summary = notification_trayicon_popup_assemble_summary();
utf8_str = notification_trayicon_popup_assemble_body(msginfo);
popup.notification = notify_notification_new(summary, utf8_str, NULL, NULL);
notify_notification_attach_to_status_icon(popup.notification, trayicon);
g_free(summary);
g_free(utf8_str);
/* Default action */
notify_notification_add_action(popup.notification,
"default", "Present main window",
(NotifyActionCallback)
notification_trayicon_popup_default_action_cb,
GINT_TO_POINTER(nftype),
notification_trayicon_popup_free_func);
if(popup.notification == NULL) {
debug_print("Notification Plugin: Failed to create a new notification.\n");
return FALSE;
}
/* Icon */
pixbuf = notification_pixbuf_get(NOTIFICATION_CM_LOGO_64x64);
if(pixbuf)
notify_notification_set_icon_from_pixbuf(popup.notification, pixbuf);
else /* This is not fatal */
debug_print("Notification plugin: Icon could not be loaded.\n");
/* Never time out, close is handled manually. */
notify_notification_set_timeout(popup.notification, NOTIFY_EXPIRES_NEVER);
/* Category */
notify_notification_set_category(popup.notification, "email.arrived");
/* Show the popup */
if(!notify_notification_show(popup.notification, &(popup.error))) {
debug_print("Notification Plugin: Failed to send notification: %s\n",
popup.error->message);
g_clear_error(&(popup.error));
g_object_unref(G_OBJECT(popup.notification));
popup.notification = NULL;
return FALSE;
}
/* Store path to message */
if(nftype == F_TYPE_MAIL) {
if(msginfo->folder && msginfo->folder) {
gchar *ident;
ident = folder_item_get_identifier(msginfo->folder);
popup.msg_path = g_strdup_printf("%s%s%u", ident,G_DIR_SEPARATOR_S,
msginfo->msgnum);
g_free(ident);
}
else
popup.msg_path = NULL;
}
debug_print("Notification Plugin: Popup created with libnotify.\n");
return TRUE;
}
static gboolean popup_timeout_fun(gpointer data)
{
G_LOCK(trayicon_popup);
if(!notify_notification_close(popup.notification, &(popup.error))) {
debug_print("Notification Plugin: Failed to close notification: %s.\n",
popup.error->message);
/* do I need to g_object_unref()? */
}
else {
g_object_unref(G_OBJECT(popup.notification));
debug_print("Notification Plugin: Popup closed due to timeout.\n");
}
popup.notification = NULL;
g_clear_error(&(popup.error));
popup.timeout_id = 0;
popup.count = 0;
popup.num_mail = 0;
popup.num_news = 0;
popup.num_calendar = 0;
popup.num_rss = 0;
if(popup.msg_path) {
g_free(popup.msg_path);
popup.msg_path = NULL;
}
G_UNLOCK(trayicon_popup);
return FALSE;
}
static void notification_trayicon_popup_free_func(gpointer data)
{
if(popup.msg_path) {
g_free(popup.msg_path);
popup.msg_path = NULL;
}
debug_print("Freed notification data\n");
}
static void notification_trayicon_popup_default_action_cb(NotifyNotification
*notification,
const char *action,
void *user_data)
{
if(strcmp("default", action))
return;
MainWindow *mainwin;
mainwin = mainwindow_get_mainwindow();
if(mainwin) {
NotificationFolderType nftype;
/* Let mainwindow pop up */
gtk_window_deiconify(GTK_WINDOW(mainwin->window));
gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwin->window), FALSE);
main_window_show(mainwin);
gtk_window_present(GTK_WINDOW(mainwin->window));
/* If there is only one new mail message, jump to this message */
nftype = (NotificationFolderType)GPOINTER_TO_INT(user_data);
if((popup.count == 1) && (nftype == F_TYPE_MAIL)) {
gchar *select_str;
G_LOCK(trayicon_popup);
select_str = g_strdup(popup.msg_path);
G_UNLOCK(trayicon_popup);
debug_print("Notification plugin: Select message %s\n", select_str);
mainwindow_jump_to(select_str, FALSE);
g_free(select_str);
}
}
}
static void notification_trayicon_popup_count_msgs(NotificationFolderType nftype)
{
switch(nftype) {
case F_TYPE_MAIL:
popup.num_mail++;
break;
case F_TYPE_NEWS:
popup.num_news++;
break;
case F_TYPE_CALENDAR:
popup.num_calendar++;
break;
case F_TYPE_RSS:
popup.num_rss++;
break;
default:
debug_print("Notification plugin: Unknown folder type\n");
return;
}
popup.count++;
}
/* The returned value has to be freed by the caller */
static gchar* notification_trayicon_popup_assemble_summary(void)
{
gchar *summary = NULL;
if(popup.count == 1) {
if(popup.num_mail)
summary = g_strdup(_("New mail message"));
else if(popup.num_news)
summary = g_strdup(_("New news post"));
else if(popup.num_calendar)
summary = g_strdup(_("New calendar message"));
else
summary = g_strdup(_("New article in RSS feed"));
} /* One new message */
else {
summary = g_strdup(_("New messages arrived"));
} /* Many new messages */
return summary;
}
/* The returned value has to be freed by the caller */
static gchar* notification_trayicon_popup_assemble_body(MsgInfo *msginfo)
{
gchar *utf8_str;
if(popup.count == 1) {
if(popup.num_mail || popup.num_news) {
gchar *from;
gchar *subj;
gchar *text;
from = notification_libnotify_sanitize_str(msginfo->from ?
msginfo->from :
_("(No From)"));
subj = notification_libnotify_sanitize_str(msginfo->subject ?
msginfo->subject :
_("(No Subject)"));
text = g_strconcat(from,"\n\n",subj,NULL);
/* Make sure text is valid UTF8 */
utf8_str = notification_validate_utf8_str(text);
g_free(text);
if(from) g_free(from);
if(subj) g_free(subj);
}
else if(popup.num_calendar) {
utf8_str = g_strdup(_("A new calendar message arrived"));
}
else {
utf8_str = g_strdup(_("A new article in a RSS feed arrived"));
}
} /* One message */
else {
gchar *msg;
gchar *tmp;
gboolean str_empty = TRUE;
utf8_str = g_strdup("");
if(popup.num_mail) {
msg = g_strdup_printf(_("%d new mail message arrived"),
popup.num_mail);
tmp = g_strdup_printf("%s%s%s",utf8_str,str_empty?"":"\n",msg);
g_free(msg);
g_free(utf8_str);
utf8_str = tmp;
str_empty = FALSE;
}
if(popup.num_news) {
msg = g_strdup_printf(_("%d new news posts arrived"),
popup.num_news);
tmp = g_strdup_printf("%s%s%s",utf8_str,str_empty?"":"\n",msg);
g_free(msg);
g_free(utf8_str);
utf8_str = tmp;
str_empty = FALSE;
}
if(popup.num_calendar) {
msg = g_strdup_printf(_("%d new calendar messages arrived"),
popup.num_calendar);
tmp = g_strdup_printf("%s%s%s",utf8_str,str_empty?"":"\n",msg);
g_free(msg);
g_free(utf8_str);
utf8_str = tmp;
str_empty = FALSE;
}
if(popup.num_rss) {
msg = g_strdup_printf(_("%d new articles in RSS feeds arrived"),
popup.num_rss);
tmp = g_strdup_printf("%s%s%s",utf8_str,str_empty?"":"\n",msg);
g_free(msg);
g_free(utf8_str);
utf8_str = tmp;
str_empty = FALSE;
}
} /* Many messages */
return utf8_str;
}
#endif /* HAVE_LIBNOTIFY */
#endif /* NOTIFICATION_TRAYICON */
syntax highlighted by Code2HTML, v. 0.9.1