/* Notification plugin for Claws-Mail * Copyright (C) 2005-2007 Holger Berndt * * 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 . */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "pluginconfig.h" #include "common/claws.h" #include "common/version.h" #include "common/utils.h" #include "common/defs.h" #include "folder.h" #include "hooks.h" #include "procmsg.h" #include "mainwindow.h" #include "main.h" #include "gettext.h" #include "notification_plugin.h" #include "notification_core.h" #include "notification_prefs.h" #include "notification_banner.h" #include "notification_lcdproc.h" #include "notification_trayicon.h" #include "notification_foldercheck.h" #include "notification_pixbuf.h" #include "plugin.h" #if HAVE_LIBNOTIFY # include #endif static gboolean my_folder_item_update_hook(gpointer, gpointer); static gboolean my_folder_update_hook(gpointer, gpointer); static gboolean my_msginfo_update_hook(gpointer, gpointer); static gboolean my_offline_switch_hook(gpointer, gpointer); static gboolean my_main_window_close_hook(gpointer, gpointer); static gboolean my_main_window_got_iconified_hook(gpointer, gpointer); static gboolean my_account_list_changed_hook(gpointer, gpointer); static guint hook_f_item; static guint hook_f; static guint hook_m_info; static guint hook_offline; static guint hook_mw_close; static guint hook_got_iconified; static guint hook_account; #ifdef NOTIFICATION_BANNER static GSList* banner_collected_msgs; #endif static gboolean my_account_list_changed_hook(gpointer source, gpointer data) { gboolean retVal = FALSE; #ifdef NOTIFICATION_TRAYICON notification_update_msg_counts(NULL); retVal = notification_trayicon_account_list_changed(source, data); #endif return retVal; } static gboolean my_main_window_got_iconified_hook(gpointer source, gpointer data) { gboolean retVal = FALSE; #ifdef NOTIFICATION_TRAYICON notification_update_msg_counts(NULL); retVal = notification_trayicon_main_window_got_iconified(source, data); #endif return retVal; } static gboolean my_main_window_close_hook(gpointer source, gpointer data) { gboolean retVal = FALSE; #ifdef NOTIFICATION_TRAYICON notification_update_msg_counts(NULL); retVal = notification_trayicon_main_window_close(source, data); #endif return retVal; } static gboolean my_offline_switch_hook(gpointer source, gpointer data) { #ifdef NOTIFICATION_TRAYICON notification_update_msg_counts(NULL); #endif return FALSE; } static gboolean my_folder_item_update_hook(gpointer source, gpointer data) { FolderItemUpdateData *update_data = source; FolderType ftype; gchar *uistr; g_return_val_if_fail(source != NULL, FALSE); #if defined(NOTIFICATION_LCDPROC) || defined(NOTIFICATION_TRAYICON) notification_update_msg_counts(NULL); #endif /* Check if the folder types is to be notified about */ ftype = update_data->item->folder->klass->type; uistr = update_data->item->folder->klass->uistr; if(!notify_include_folder_type(ftype, uistr)) return FALSE; if(update_data->update_flags & F_ITEM_UPDATE_MSGCNT) { #ifdef NOTIFICATION_BANNER notification_update_banner(); #endif #if defined(NOTIFICATION_POPUP) || defined(NOTIFICATION_COMMAND) notification_new_unnotified_msgs(update_data); #endif } return FALSE; } static gboolean my_folder_update_hook(gpointer source, gpointer data) { FolderUpdateData *hookdata; g_return_val_if_fail(source != NULL, FALSE); hookdata = source; #if defined(NOTIFICATION_LCDPROC) || defined(NOTIFICATION_TRAYICON) if(hookdata->update_flags & FOLDER_REMOVE_FOLDERITEM) notification_update_msg_counts(hookdata->item); else notification_update_msg_counts(NULL); #endif return FALSE; } static gboolean my_msginfo_update_hook(gpointer source, gpointer data) { return notification_notified_hash_msginfo_update((MsgInfoUpdate*)source); } gint plugin_init(gchar **error) { gchar *rcpath; bindtextdomain(TEXTDOMAIN, LOCALEDIR); bind_textdomain_codeset(TEXTDOMAIN, "UTF-8"); /* Version check */ if(!check_plugin_version(MAKE_NUMERIC_VERSION(2,9,2,72), VERSION_NUMERIC, _("Notification"), error)) return -1; /* Check if threading is enabled */ if(!g_thread_supported()) { *error = g_strdup(_("The Notification plugin needs threading support.")); return -1; } hook_f_item = hooks_register_hook(FOLDER_ITEM_UPDATE_HOOKLIST, my_folder_item_update_hook, NULL); if(hook_f_item == (guint) -1) { *error = g_strdup(_("Failed to register folder item update hook in the " "Notification plugin")); return -1; } hook_f = hooks_register_hook(FOLDER_UPDATE_HOOKLIST, my_folder_update_hook, NULL); if(hook_f == (guint) -1) { *error = g_strdup(_("Failed to register folder update hook in the " "Notification plugin")); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); return -1; } hook_m_info = hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, my_msginfo_update_hook, NULL); if(hook_m_info == (guint) -1) { *error = g_strdup(_("Failed to register msginfo update hook in the " "Notification plugin")); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, hook_f); return -1; } hook_offline = hooks_register_hook(OFFLINE_SWITCH_HOOKLIST, my_offline_switch_hook, NULL); if(hook_offline == (guint) -1) { *error = g_strdup(_("Failed to register offline switch hook in the " "Notification plugin")); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, hook_f); hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, hook_m_info); return -1; } hook_mw_close = hooks_register_hook(MAIN_WINDOW_CLOSE, my_main_window_close_hook, NULL); if(hook_mw_close == (guint) -1) { *error = g_strdup(_("Failed to register main window close hook in the " "Notification plugin")); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, hook_f); hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, hook_m_info); hooks_unregister_hook(OFFLINE_SWITCH_HOOKLIST, hook_offline); return -1; } hook_got_iconified = hooks_register_hook(MAIN_WINDOW_GOT_ICONIFIED, my_main_window_got_iconified_hook, NULL); if(hook_got_iconified == (guint) -1) { *error = g_strdup(_("Failed to register got iconified hook in the " "Notification plugin")); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, hook_f); hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, hook_m_info); hooks_unregister_hook(OFFLINE_SWITCH_HOOKLIST, hook_offline); hooks_unregister_hook(MAIN_WINDOW_CLOSE, hook_mw_close); return -1; } hook_account = hooks_register_hook(ACCOUNT_LIST_CHANGED_HOOKLIST, my_account_list_changed_hook, NULL); if (hook_account == (guint) -1) { *error = g_strdup(_("Failed to register account list changed hook in the " "Notification plugin")); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, hook_f); hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, hook_m_info); hooks_unregister_hook(OFFLINE_SWITCH_HOOKLIST, hook_offline); hooks_unregister_hook(MAIN_WINDOW_CLOSE, hook_mw_close); hooks_unregister_hook(MAIN_WINDOW_GOT_ICONIFIED, hook_got_iconified); return -1; } /* Configuration */ prefs_set_default(notify_param); rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL); prefs_read_config(notify_param, "NotificationPlugin", rcpath, NULL); g_free(rcpath); /* Folder specific stuff */ notification_foldercheck_read_array(); notification_notified_hash_startup_init(); notify_gtk_init(); #ifdef NOTIFICATION_BANNER notification_update_banner(); #endif #ifdef NOTIFICATION_LCDPROC notification_lcdproc_connect(); #endif #ifdef NOTIFICATION_TRAYICON if(notify_config.trayicon_hide_at_startup && claws_is_starting()) { MainWindow *mainwin = mainwindow_get_mainwindow(); if(mainwin && GTK_WIDGET_VISIBLE(GTK_WIDGET(mainwin->window))) main_window_hide(mainwin); main_set_show_at_startup(FALSE); } #endif my_account_list_changed_hook(NULL,NULL); debug_print("Notification plugin loaded\n"); return 0; } gboolean plugin_done(void) { notify_save_config(); #ifdef NOTIFICATION_BANNER notification_collected_msgs_free(banner_collected_msgs); banner_collected_msgs = NULL; notification_banner_destroy(); #endif #ifdef NOTIFICATION_LCDPROC notification_lcdproc_disconnect(); #endif notification_notified_hash_free(); hooks_unregister_hook(FOLDER_ITEM_UPDATE_HOOKLIST, hook_f_item); hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, hook_f); hooks_unregister_hook(MSGINFO_UPDATE_HOOKLIST, hook_m_info); hooks_unregister_hook(OFFLINE_SWITCH_HOOKLIST, hook_offline); hooks_unregister_hook(MAIN_WINDOW_CLOSE, hook_mw_close); hooks_unregister_hook(MAIN_WINDOW_GOT_ICONIFIED, hook_got_iconified); hooks_unregister_hook(ACCOUNT_LIST_CHANGED_HOOKLIST, hook_account); notify_gtk_done(); /* foldercheck cleanup */ notification_foldercheck_write_array(); notification_free_folder_specific_array(); #ifdef HAVE_LIBNOTIFY if(notify_is_initted()) notify_uninit(); #endif notification_pixbuf_free_all(); debug_print("Notification plugin unloaded\n"); return TRUE; } const gchar *plugin_name(void) { return _("Notification"); } const gchar *plugin_desc(void) { return _("This plugin provides various ways " "to notify the user of new and unread email.\nFeedback " "to is welcome."); } const gchar *plugin_type(void) { return "GTK2"; } const gchar *plugin_licence(void) { return "GPL3+"; } const gchar *plugin_version(void) { return PLUGINVERSION; } struct PluginFeature *plugin_provides(void) { static struct PluginFeature features[] = { {PLUGIN_NOTIFIER, N_("Various tools")}, {PLUGIN_NOTHING, NULL}}; return features; } #ifdef NOTIFICATION_BANNER void notification_update_banner(void) { notification_collected_msgs_free(banner_collected_msgs); banner_collected_msgs = NULL; if(notify_config.banner_show != NOTIFY_BANNER_SHOW_NEVER) { guint id; GSList *folder_list = NULL; if(notify_config.banner_folder_specific) { id = notification_register_folder_specific_list (BANNER_SPECIFIC_FOLDER_ID_STR); folder_list = notification_foldercheck_get_list(id); } if(!(notify_config.banner_folder_specific && (folder_list == NULL))) banner_collected_msgs = notification_collect_msgs(notify_config.banner_include_unread, notify_config.banner_folder_specific ? folder_list : NULL, notify_config.banner_max_msgs); } notification_banner_show(banner_collected_msgs); } #endif