From 6cb13b10b6c87bd6fd89454049dd9b58c1f9808c Mon Sep 17 00:00:00 2001 From: Johnny Jacob Date: Sat, 15 Dec 2007 11:59:39 +0000 Subject: Part of fix for #492702 from Milan Crha : New mail notify and preferences ui movement. svn path=/trunk/; revision=34702 --- plugins/mail-notification/ChangeLog | 10 + .../apps-evolution-mail-notification.schemas.in | 85 ++- plugins/mail-notification/mail-notification.c | 791 ++++++++++++++++++--- .../org-gnome-mail-notification.eplug.xml | 13 +- 4 files changed, 786 insertions(+), 113 deletions(-) (limited to 'plugins/mail-notification') diff --git a/plugins/mail-notification/ChangeLog b/plugins/mail-notification/ChangeLog index a3f7fed466..fad75f1101 100644 --- a/plugins/mail-notification/ChangeLog +++ b/plugins/mail-notification/ChangeLog @@ -1,3 +1,13 @@ +2007-12-07 Milan Crha + + ** Fix for bug #492702 + + * apps-evolution-mail-notification.schemas.in: + * mail-notification.c: + * org-gnome-mail-notification.eplug.xml: + New-mail-notification plugin and sound notification has been merged + to this plugin, with couple of options in plugins Configuration tab. + 2007-10-11 Matthew Barnes * mail-notification.c: diff --git a/plugins/mail-notification/apps-evolution-mail-notification.schemas.in b/plugins/mail-notification/apps-evolution-mail-notification.schemas.in index 5cc552d0d0..c6cec4803b 100644 --- a/plugins/mail-notification/apps-evolution-mail-notification.schemas.in +++ b/plugins/mail-notification/apps-evolution-mail-notification.schemas.in @@ -1,25 +1,94 @@ - /schemas/apps/evolution/mail/notification/notification - /apps/evolution/mail/notification/notification + /schemas/apps/evolution/eplugin/mail-notification/notify-only-inbox + /apps/evolution/eplugin/mail-notification/notify-only-inbox evolution-mail bool true - Enable libnotify notifications of new mail - Every time a new mail arrives, pop up a libnotify notification. + Notify messages in Inbox only. + Whether to notify new messages in Inbox folder only. + + + + + /schemas/apps/evolution/eplugin/mail-notification/dbus-enabled + /apps/evolution/eplugin/mail-notification/dbus-enabled + evolution-mail + bool + true + + Enable D-Bus messages. + Generates a D-Bus message when new mail messages arrive. + + + + + /schemas/apps/evolution/eplugin/mail-notification/status-enabled + /apps/evolution/eplugin/mail-notification/status-enabled + evolution-mail + bool + true + + Enable icon in notification area. + Show new mail icon in notification area when new messages arrive. - /schemas/apps/evolution/mail/notification/blink-status-icon - /apps/evolution/mail/notification/blink-status-icon + /schemas/apps/evolution/eplugin/mail-notification/status-blink-icon + /apps/evolution/eplugin/mail-notification/status-blink-icon evolution-mail bool true - Make the status icon blink - When the new-mail status icon is visible, make it blink. + Blink icon in notification area. + Whether the icon should blink or not. + + + + /schemas/apps/evolution/eplugin/mail-notification/status-notification + /apps/evolution/eplugin/mail-notification/status-notification + evolution-mail + bool + true + + Popup message together with the icon. + Whether show message over the icon when new messages arrive. + + + + + /schemas/apps/evolution/eplugin/mail-notification/sound-enabled + /apps/evolution/eplugin/mail-notification/sound-enabled + evolution-mail + bool + true + + Play sound when new messages arrive. + Whether play sound or beep when new messages arrive. + + + + /schemas/apps/evolution/eplugin/mail-notification/sound-beep + /apps/evolution/eplugin/mail-notification/sound-beep + evolution-mail + bool + true + + Beep or play sound file. + If true, then Beep, otherwise will play sound file when new messages arrive. + + + + /schemas/apps/evolution/eplugin/mail-notification/sound-file + /apps/evolution/eplugin/mail-notification/sound-file + evolution-mail + string + + + Sound file name to be played. + Sound file to be played when new messages arrive, if not in beep mode. diff --git a/plugins/mail-notification/mail-notification.c b/plugins/mail-notification/mail-notification.c index 7025579172..b2f80829ab 100644 --- a/plugins/mail-notification/mail-notification.c +++ b/plugins/mail-notification/mail-notification.c @@ -28,165 +28,768 @@ #include #include #include -#include -#include - -#include -#include -#include -#include +#include +#include +#include +#include + +#include "e-util/e-config.h" +#include "e-util/e-icon-factory.h" +#include "mail/em-utils.h" +#include "mail/em-event.h" +#include "mail/em-folder-tree-model.h" +#include "camel/camel-folder.h" #ifdef HAVE_LIBNOTIFY #include #endif -#define GCONF_KEY_NOTIFICATION "/apps/evolution/mail/notification/notification" -#define GCONF_KEY_BLINK "/apps/evolution/mail/notification/blink-status-icon" - -int e_plugin_lib_enable (EPluginLib *ep, int enable); -void org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t); -void org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t); +#define GCONF_KEY_ROOT "/apps/evolution/eplugin/mail-notification/" +#define GCONF_KEY_NOTIFY_ONLY_INBOX GCONF_KEY_ROOT "notify-only-inbox" +#define GCONF_KEY_ENABLED_DBUS GCONF_KEY_ROOT "dbus-enabled" +#define GCONF_KEY_ENABLED_STATUS GCONF_KEY_ROOT "status-enabled" +#define GCONF_KEY_ENABLED_SOUND GCONF_KEY_ROOT "sound-enabled" static gboolean enabled = FALSE; -static GtkStatusIcon *status_icon = NULL; -#ifdef HAVE_LIBNOTIFY -static gboolean notification_callback (gpointer notify); -static NotifyNotification *notify = NULL; -#endif +/** + * each part should "implement" its own "public" functions: + * a) void new_notify_... (EMEventTargetFolder *t) + * when new_notify message is sent by Evolution + * + * b) void read_notify_... (EMEventTargetMessage *t) + * it is called when read_notify message is sent by Evolution + * + * c) void enable_... (int enable) + * when plugin itself or the part is enabled/disabled + * + * d) GtkWidget *get_config_widget_...(void) + * to obtain config widget for the particular part + * + * It also should have its own gconf key for enabled state. In each particular + * function it should do its work as expected. enable_... will be called always + * when disabling plugin, but only when enabling/disabling part itself. + **/ -static GStaticMutex mlock = G_STATIC_MUTEX_INIT; +/* ------------------------------------------------------------------- */ +/* Helper functions */ +/* ------------------------------------------------------------------- */ -void -org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t) +static gboolean +is_part_enabled (const gchar *gconf_key) { - g_static_mutex_lock (&mlock); + /* the part is enabled by defaul */ + gboolean res = TRUE; + GConfClient *client; + GConfValue *is_key; - if (!status_icon) { - g_static_mutex_unlock (&mlock); - return; + client = gconf_client_get_default (); + + is_key = gconf_client_get (client, gconf_key, NULL); + if (is_key) { + res = gconf_client_get_bool (client, gconf_key, NULL); + gconf_value_free (is_key); } -#ifdef HAVE_LIBNOTIFY - notify_notification_close (notify, NULL); -#endif - gtk_status_icon_set_visible (status_icon, FALSE); + g_object_unref (client); - g_static_mutex_unlock (&mlock); + return res; } static void -#ifdef HAVE_LIBNOTIFY -icon_activated (GtkStatusIcon *icon, NotifyNotification *notify) +set_part_enabled (const gchar *gconf_key, gboolean enable) +{ + GConfClient *client; + + client = gconf_client_get_default (); + + gconf_client_set_bool (client, gconf_key, enable, NULL); + g_object_unref (client); +} + +/* ------------------------------------------------------------------- */ +/* DBUS part */ +/* ------------------------------------------------------------------- */ + +#define DBUS_PATH "/org/gnome/evolution/mail/newmail" +#define DBUS_INTERFACE "org.gnome.evolution.mail.dbus.Signal" + +static DBusConnection *bus = NULL; + +static gboolean init_dbus (void); + +static void +send_dbus_message (const char *name, const char *data, guint new) +{ + DBusMessage *message; + + /* Create a new message on the DBUS_INTERFACE */ + if (!(message = dbus_message_new_signal (DBUS_PATH, DBUS_INTERFACE, name))) + return; + + /* Appends the data as an argument to the message */ + dbus_message_append_args (message, +#if DBUS_VERSION >= 310 + DBUS_TYPE_STRING, &data, #else -icon_activated (GtkStatusIcon *icon, gpointer notify) + DBUS_TYPE_STRING, data, #endif + DBUS_TYPE_INVALID); + + if (new) { + char * display_name = em_utils_folder_name_from_uri (data); + dbus_message_append_args (message, +#if DBUS_VERSION >= 310 + DBUS_TYPE_STRING, &display_name, DBUS_TYPE_UINT32, &new, +#else + DBUS_TYPE_STRING, display_name, DBUS_TYPE_UINT32, new, +#endif + DBUS_TYPE_INVALID); + + } + + /* Sends the message */ + dbus_connection_send (bus, message, NULL); + + /* Frees the message */ + dbus_message_unref (message); +} + +static gboolean +reinit_dbus (gpointer user_data) { - g_static_mutex_lock (&mlock); + if (!enabled || init_dbus ()) + return FALSE; + + /* keep trying to re-establish dbus connection */ + return TRUE; +} + +static DBusHandlerResult +filter_function (DBusConnection *connection, DBusMessage *message, void *user_data) +{ + if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && + strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) { + dbus_connection_unref (bus); + bus = NULL; + + g_timeout_add (3000, reinit_dbus, NULL); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static gboolean +init_dbus (void) +{ + DBusError error; + + if (bus != NULL) + return TRUE; + + dbus_error_init (&error); + if (!(bus = dbus_bus_get (DBUS_BUS_SESSION, &error))) { + g_warning ("could not get system bus: %s\n", error.message); + dbus_error_free (&error); + return FALSE; + } + + dbus_connection_setup_with_g_main (bus, NULL); + dbus_connection_set_exit_on_disconnect (bus, FALSE); + + dbus_connection_add_filter (bus, filter_function, NULL, NULL); + + return TRUE; +} + +static void +toggled_dbus_cb (GtkWidget *widget, gpointer data) +{ + g_return_if_fail (widget != NULL); + + set_part_enabled (GCONF_KEY_ENABLED_DBUS, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +/* ------------------------------------------------------------------- */ + +static void +new_notify_dbus (EMEventTargetFolder *t) +{ + if (bus != NULL) + send_dbus_message ("Newmail", t->uri, t->new); +} + +static void +read_notify_dbus (EMEventTargetMessage *t) +{ + if (bus != NULL) + send_dbus_message ("MessageReading", t->folder->name, 0); +} + +static void +enable_dbus (int enable) +{ + if (enable) { + /* we ignore errors here */ + init_dbus (); + } else if (bus != NULL) { + dbus_connection_unref (bus); + bus = NULL; + } +} + +static GtkWidget * +get_config_widget_dbus (void) +{ + GtkWidget *w; + + w = gtk_check_button_new_with_mnemonic (_("Generate a _D-Bus message")); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), is_part_enabled (GCONF_KEY_ENABLED_DBUS)); + g_signal_connect (G_OBJECT (w), "toggled", G_CALLBACK (toggled_dbus_cb), NULL); + gtk_widget_show (w); + + return w; +} + +/* ------------------------------------------------------------------- */ +/* Notification area part */ +/* ------------------------------------------------------------------- */ + +#define GCONF_KEY_STATUS_BLINK GCONF_KEY_ROOT "status-blink-icon" +#define GCONF_KEY_STATUS_NOTIFICATION GCONF_KEY_ROOT "status-notification" + +static GtkStatusIcon *status_icon = NULL; +static unsigned int status_count = 0; + #ifdef HAVE_LIBNOTIFY - notify_notification_close (notify, NULL); +static gboolean notification_callback (gpointer notify); +static NotifyNotification *notify = NULL; #endif + +static void +#ifdef HAVE_LIBNOTIFY +icon_activated (GtkStatusIcon *icon, NotifyNotification *pnotify) +#else +icon_activated (GtkStatusIcon *icon, gpointer pnotify) +#endif +{ + #ifdef HAVE_LIBNOTIFY + if (notify) + notify_notification_close (notify, NULL); + + notify = NULL; + #endif + gtk_status_icon_set_visible (status_icon, FALSE); - g_static_mutex_unlock (&mlock); + g_object_unref (status_icon); + status_icon = NULL; + status_count = 0; } #ifdef HAVE_LIBNOTIFY -gboolean +static gboolean notification_callback (gpointer notify) { - printf("fff\n"); - return (!notify_notification_show(notify, NULL)); - + return (!notify_notification_show (notify, NULL)); } #endif -void -org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t) +struct _StatusConfigureWidgets { - char *msg = NULL; - char *folder; - GConfClient *client; - GConfValue *is_key; + GtkWidget *enable; + GtkWidget *blink; + #ifdef HAVE_LIBNOTIFY + GtkWidget *message; + #endif +}; - /* FIXME: Should this is_inbox be configurable? */ - if (!t->new || !t->is_inbox) - return; +static void +toggled_status_cb (GtkWidget *widget, gpointer data) +{ + struct _StatusConfigureWidgets *scw = (struct _StatusConfigureWidgets *) data; + gboolean enabl; + + g_return_if_fail (scw != NULL); + g_return_if_fail (scw->enable != NULL); + g_return_if_fail (scw->blink != NULL); + #ifdef HAVE_LIBNOTIFY + g_return_if_fail (scw->message != NULL); + #endif + + enabl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->enable)); + if (widget == scw->enable) + set_part_enabled (GCONF_KEY_ENABLED_STATUS, enabl); + + #define work_widget(w, key) \ + gtk_widget_set_sensitive (w, enabl); \ + if (widget == w) \ + set_part_enabled (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (w))); + + work_widget (scw->blink, GCONF_KEY_STATUS_BLINK); + #ifdef HAVE_LIBNOTIFY + work_widget (scw->message, GCONF_KEY_STATUS_NOTIFICATION); + #endif + + #undef work_widget +} - g_static_mutex_lock (&mlock); - client = gconf_client_get_default (); +/* ------------------------------------------------------------------- */ - is_key = gconf_client_get (client, GCONF_KEY_BLINK, NULL); - if (!is_key) - gconf_client_set_bool (client, GCONF_KEY_BLINK, TRUE, NULL); - else - gconf_value_free (is_key); +static void +new_notify_status (EMEventTargetFolder *t) +{ + char *msg; if (!status_icon) { - printf("creating\n"); status_icon = gtk_status_icon_new (); - gtk_status_icon_set_from_pixbuf (status_icon, e_icon_factory_get_icon ("stock_mail", E_ICON_SIZE_LARGE_TOOLBAR)); + gtk_status_icon_set_from_pixbuf (status_icon, e_icon_factory_get_icon ("mail-unread", E_ICON_SIZE_LARGE_TOOLBAR)); } - folder = em_utils_folder_name_from_uri (t->uri); - msg = g_strdup_printf (ngettext("You have received %d new message in %s.", "You have received %d new messages in %s.", t->new), t->new, folder); + if (!status_count) { + char *folder; + + status_count = t->new; + folder = em_utils_folder_name_from_uri (t->uri); + msg = g_strdup_printf (_("You have received %d new messages\nin %s."), status_count, folder); + + g_free (folder); + } else { + status_count += t->new; + msg = g_strdup_printf (_("You have received %d new messages."), status_count); + } gtk_status_icon_set_tooltip (status_icon, msg); gtk_status_icon_set_visible (status_icon, TRUE); - gtk_status_icon_set_blinking (status_icon, - gconf_client_get_bool (client, GCONF_KEY_BLINK, NULL)); + gtk_status_icon_set_blinking (status_icon, is_part_enabled (GCONF_KEY_STATUS_BLINK)); -#ifdef HAVE_LIBNOTIFY - /* See whether the notification key has already been set */ - is_key = gconf_client_get (client, GCONF_KEY_NOTIFICATION, NULL); - if (!is_key) - gconf_client_set_bool (client, GCONF_KEY_NOTIFICATION, TRUE, NULL); + #ifdef HAVE_LIBNOTIFY + /* Now check whether we're supposed to send notifications */ + if (is_part_enabled (GCONF_KEY_STATUS_NOTIFICATION)) { + if (notify) { + notify_notification_update (notify, _("New email"), msg, "mail-unread"); + } else { + if (!notify_init ("evolution-mail-notification")) + fprintf (stderr,"notify init error"); + + notify = notify_notification_new (_("New email"), msg, "mail-unread", NULL); + notify_notification_attach_to_status_icon (notify, status_icon); + + notify_notification_set_urgency (notify, NOTIFY_URGENCY_NORMAL); + notify_notification_set_timeout (notify, NOTIFY_EXPIRES_DEFAULT); + g_timeout_add (500, notification_callback, notify); + } + } + #endif + + g_free (msg); + + #ifdef HAVE_LIBNOTIFY + g_signal_connect (G_OBJECT (status_icon), "activate", G_CALLBACK (icon_activated), notify); + #else + g_signal_connect (G_OBJECT (status_icon), "activate", G_CALLBACK (icon_activated), NULL); + #endif +} + +static void +read_notify_status (EMEventTargetMessage *t) +{ + if (!status_icon) + return; + + #ifdef HAVE_LIBNOTIFY + icon_activated (status_icon, notify); + #else + icon_activated (status_icon, NULL); + #endif +} + +static void +enable_status (int enable) +{ + /* this does nothing on enable, it's here just to be + consistent with other parts of this plugin */ +} + +static GtkWidget * +get_config_widget_status (void) +{ + GtkWidget *vbox, *parent, *alignment; + struct _StatusConfigureWidgets *scw; + + vbox = gtk_vbox_new (FALSE, 0); + scw = g_malloc0 (sizeof (struct _StatusConfigureWidgets)); + + #define create_check(c, key, desc) \ + c = gtk_check_button_new_with_mnemonic (desc); \ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (c), is_part_enabled (key)); \ + gtk_box_pack_start (GTK_BOX (parent), c, FALSE, FALSE, 0); \ + g_signal_connect (G_OBJECT (c), "toggled", G_CALLBACK (toggled_status_cb), scw); + + parent = vbox; + create_check (scw->enable, GCONF_KEY_ENABLED_STATUS, _("Show icon in _notification area")); + + parent = gtk_vbox_new (FALSE, 0); + create_check (scw->blink, GCONF_KEY_STATUS_BLINK, _("B_link icon in notification area")); + #ifdef HAVE_LIBNOTIFY + create_check (scw->message, GCONF_KEY_STATUS_NOTIFICATION, _("Popup _message together with the icon")); + #endif + + alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 20, 0); + gtk_container_add (GTK_CONTAINER (alignment), parent); + gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0); + + #undef create_check + + /* to let structure free properly */ + g_object_set_data_full (G_OBJECT (vbox), "scw-data", scw, g_free); + + toggled_status_cb (NULL, scw); + gtk_widget_show_all (vbox); + + return vbox; +} + +/* ------------------------------------------------------------------- */ +/* Sound part */ +/* ------------------------------------------------------------------- */ + +/* min no. seconds between newmail notifications */ +#define NOTIFY_THROTTLE 30 + +#define GCONF_KEY_SOUND_BEEP GCONF_KEY_ROOT "sound-beep" +#define GCONF_KEY_SOUND_FILE GCONF_KEY_ROOT "sound-file" + +static void +do_play_sound (gboolean beep, const gchar *file) +{ + if (beep) + gdk_beep (); + else if (!file || !*file) + g_warning ("No file to play!"); else - gconf_value_free (is_key); + gnome_sound_play (file); +} - /* Now check whether we're supposed to send notifications */ - if (gconf_client_get_bool (client, GCONF_KEY_NOTIFICATION, NULL)) { - if (!notify_init ("evolution-mail-notification")) - fprintf(stderr,"notify init error"); +struct _SoundConfigureWidgets +{ + GtkWidget *enable; + GtkWidget *beep; + GtkWidget *file; + GtkWidget *label; + GtkWidget *filechooser; + GtkWidget *play; +}; - notify = notify_notification_new ( - _("New email"), - msg, - "stock_mail", - NULL); - notify_notification_attach_to_status_icon (notify, status_icon); +static void +toggled_sound_cb (GtkWidget *widget, gpointer data) +{ + struct _SoundConfigureWidgets *scw = (struct _SoundConfigureWidgets *) data; + gboolean enabl; + + g_return_if_fail (data != NULL); + g_return_if_fail (scw->enable != NULL); + g_return_if_fail (scw->beep != NULL); + g_return_if_fail (scw->file != NULL); + g_return_if_fail (scw->label != NULL); + g_return_if_fail (scw->filechooser != NULL); + g_return_if_fail (scw->play != NULL); + + enabl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->enable)); + if (widget == scw->enable) + set_part_enabled (GCONF_KEY_ENABLED_SOUND, enabl); + + gtk_widget_set_sensitive (scw->beep, enabl); + gtk_widget_set_sensitive (scw->file, enabl); + gtk_widget_set_sensitive (scw->label, enabl); + gtk_widget_set_sensitive (scw->filechooser, enabl && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->file))); + gtk_widget_set_sensitive (scw->play, enabl); + + if (widget == scw->beep || widget == scw->file) + set_part_enabled (GCONF_KEY_SOUND_BEEP, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->beep))); +} - notify_notification_set_urgency(notify, NOTIFY_URGENCY_NORMAL); - notify_notification_set_timeout(notify, NOTIFY_EXPIRES_DEFAULT); - g_timeout_add(500, notification_callback, notify); +static void +sound_file_set_cb (GtkWidget *widget, gpointer data) +{ + gchar *file; + GConfClient *client; - } -#endif + g_return_if_fail (widget != NULL); + + client = gconf_client_get_default (); + file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget)); + + gconf_client_set_string (client, GCONF_KEY_SOUND_FILE, file ? file : "", NULL); - g_free (folder); - g_free (msg); g_object_unref (client); -#ifdef HAVE_LIBNOTIFY - g_signal_connect (G_OBJECT (status_icon), "activate", - G_CALLBACK (icon_activated), notify); -#else - g_signal_connect (G_OBJECT (status_icon), "activate", - G_CALLBACK (icon_activated), NULL); -#endif + g_free (file); +} + +static void +sound_play_cb (GtkWidget *widget, gpointer data) +{ + struct _SoundConfigureWidgets *scw = (struct _SoundConfigureWidgets *) data; + gchar *file; + + g_return_if_fail (data != NULL); + + if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->enable))) + return; + + file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (scw->filechooser)); + do_play_sound (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (scw->beep)), file); + g_free (file); +} + +struct _SoundNotifyData { + time_t last_notify; + guint notify_idle_id; +}; + +static gboolean +sound_notify_idle_cb (gpointer user_data) +{ + gchar *file; + GConfClient *client; + struct _SoundNotifyData *data = (struct _SoundNotifyData *) user_data; + + g_return_val_if_fail (data != NULL, FALSE); + + client = gconf_client_get_default (); + file = gconf_client_get_string (client, GCONF_KEY_SOUND_FILE, NULL); + + do_play_sound (is_part_enabled (GCONF_KEY_SOUND_BEEP), file); + + g_object_unref (client); + g_free (file); + + time (&data->last_notify); + + data->notify_idle_id = 0; + + return FALSE; +} + +/* ------------------------------------------------------------------- */ + +static void +new_notify_sound (EMEventTargetFolder *t) +{ + time_t last_newmail; + struct _SoundNotifyData data = {0, 0}; + + time (&last_newmail); + + /* just put it to the idle queue */ + if (data.notify_idle_id == 0 && (last_newmail - data.last_notify >= NOTIFY_THROTTLE)) + data.notify_idle_id = g_idle_add_full (G_PRIORITY_LOW, sound_notify_idle_cb, &data, NULL); +} + +static void +read_notify_sound (EMEventTargetMessage *t) +{ + /* we do nothing here */ +} + +static void +enable_sound (int enable) +{ + if (enable) + gnome_sound_init ("localhost"); + else + gnome_sound_shutdown (); +} + +static GtkWidget * +get_config_widget_sound (void) +{ + GtkWidget *vbox, *alignment, *parent, *hbox; + gchar *file; + GConfClient *client; + struct _SoundConfigureWidgets *scw; + + vbox = gtk_vbox_new (FALSE, 0); + scw = g_malloc0 (sizeof (struct _SoundConfigureWidgets)); + + scw->enable = gtk_check_button_new_with_mnemonic (_("_Play sound when new messages arrive")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scw->enable), is_part_enabled (GCONF_KEY_ENABLED_SOUND)); + gtk_box_pack_start (GTK_BOX (vbox), scw->enable, FALSE, FALSE, 0); + g_signal_connect (G_OBJECT (scw->enable), "toggled", G_CALLBACK (toggled_sound_cb), scw); + + parent = gtk_vbox_new (FALSE, 0); + scw->beep = gtk_radio_button_new_with_mnemonic (NULL, _("_Beep")); + scw->file = gtk_radio_button_new_with_mnemonic_from_widget (GTK_RADIO_BUTTON (scw->beep), _("Play _sound file")); + + if (is_part_enabled (GCONF_KEY_SOUND_BEEP)) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scw->beep), TRUE); + else + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scw->file), TRUE); + + g_signal_connect (G_OBJECT (scw->beep), "toggled", G_CALLBACK (toggled_sound_cb), scw); + g_signal_connect (G_OBJECT (scw->file), "toggled", G_CALLBACK (toggled_sound_cb), scw); + + hbox = gtk_hbox_new (FALSE, 0); + scw->label = gtk_label_new_with_mnemonic (_("Specify _filename:")); + scw->filechooser = gtk_file_chooser_button_new (_("Select sound file"), GTK_FILE_CHOOSER_ACTION_OPEN); + scw->play = gtk_button_new_with_mnemonic (_("Pl_ay")); + + gtk_label_set_mnemonic_widget (GTK_LABEL (scw->label), scw->filechooser); + gtk_button_set_image (GTK_BUTTON (scw->play), gtk_image_new_from_icon_name ("media-playback-start", GTK_ICON_SIZE_BUTTON)); + + client = gconf_client_get_default (); + file = gconf_client_get_string (client, GCONF_KEY_SOUND_FILE, NULL); + + if (file && *file) + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (scw->filechooser), file); + + g_object_unref (client); + g_free (file); + + g_signal_connect (G_OBJECT (scw->filechooser), "file-set", G_CALLBACK (sound_file_set_cb), scw); + g_signal_connect (G_OBJECT (scw->play), "clicked", G_CALLBACK (sound_play_cb), scw); + + gtk_box_pack_start (GTK_BOX (hbox), scw->label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), scw->filechooser, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), scw->play, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (parent), scw->beep, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (parent), scw->file, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (parent), hbox, FALSE, FALSE, 0); + + alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 20, 0); + gtk_container_add (GTK_CONTAINER (alignment), parent); + gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0); + + /* to let structure free properly */ + g_object_set_data_full (G_OBJECT (vbox), "scw-data", scw, g_free); + + toggled_sound_cb (NULL, scw); + gtk_widget_show_all (vbox); + + return vbox; +} + +/* ------------------------------------------------------------------- */ +/* Plugin itself part */ +/* ------------------------------------------------------------------- */ + +static void +toggled_only_inbox_cb (GtkWidget *widget, gpointer data) +{ + g_return_if_fail (widget != NULL); + + set_part_enabled (GCONF_KEY_NOTIFY_ONLY_INBOX, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); +} + +void org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t); +void org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t); + +int e_plugin_lib_enable (EPluginLib *ep, int enable); +GtkWidget *e_plugin_lib_get_configure_widget (EPlugin *epl); + +static GStaticMutex mlock = G_STATIC_MUTEX_INIT; + +void +org_gnome_mail_new_notify (EPlugin *ep, EMEventTargetFolder *t) +{ + g_return_if_fail (t != NULL); + + if (!enabled || !t->new || (!t->is_inbox && is_part_enabled (GCONF_KEY_NOTIFY_ONLY_INBOX))) + return; + + g_static_mutex_lock (&mlock); + + if (is_part_enabled (GCONF_KEY_ENABLED_DBUS)) + new_notify_dbus (t); + + if (is_part_enabled (GCONF_KEY_ENABLED_STATUS)) + new_notify_status (t); + + if (is_part_enabled (GCONF_KEY_ENABLED_SOUND)) + new_notify_sound (t); + g_static_mutex_unlock (&mlock); } +void +org_gnome_mail_read_notify (EPlugin *ep, EMEventTargetMessage *t) +{ + g_return_if_fail (t != NULL); + + if (!enabled) + return; + + g_static_mutex_lock (&mlock); + + if (is_part_enabled (GCONF_KEY_ENABLED_DBUS)) + read_notify_dbus (t); + if (is_part_enabled (GCONF_KEY_ENABLED_STATUS)) + read_notify_status (t); + if (is_part_enabled (GCONF_KEY_ENABLED_SOUND)) + read_notify_sound (t); + + g_static_mutex_unlock (&mlock); +} int e_plugin_lib_enable (EPluginLib *ep, int enable) { - if (enable) + if (enable) { + if (is_part_enabled (GCONF_KEY_ENABLED_DBUS)) + enable_dbus (enable); + + if (is_part_enabled (GCONF_KEY_ENABLED_STATUS)) + enable_status (enable); + + if (is_part_enabled (GCONF_KEY_ENABLED_SOUND)) + enable_sound (enable); + enabled = TRUE; - else + } else { + enable_dbus (enable); + enable_status (enable); + enable_sound (enable); + enabled = FALSE; + } return 0; } +GtkWidget * +e_plugin_lib_get_configure_widget (EPlugin *epl) +{ + GtkWidget *cfg, *vbox, *check; + + vbox = gtk_vbox_new (FALSE, 6); + check = gtk_check_button_new_with_mnemonic (_("Notify new messages for _Inbox only")); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), is_part_enabled (GCONF_KEY_NOTIFY_ONLY_INBOX)); + g_signal_connect (G_OBJECT (check), "toggled", G_CALLBACK (toggled_only_inbox_cb), NULL); + gtk_widget_show (check); + gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0); + + cfg = get_config_widget_dbus (); + if (cfg) + gtk_box_pack_start (GTK_BOX (vbox), cfg, FALSE, FALSE, 0); + + cfg = get_config_widget_status (); + if (cfg) + gtk_box_pack_start (GTK_BOX (vbox), cfg, FALSE, FALSE, 0); + + cfg = get_config_widget_sound (); + if (cfg) + gtk_box_pack_start (GTK_BOX (vbox), cfg, FALSE, FALSE, 0); + + gtk_widget_show (vbox); + + return vbox; +} diff --git a/plugins/mail-notification/org-gnome-mail-notification.eplug.xml b/plugins/mail-notification/org-gnome-mail-notification.eplug.xml index b6bcc6e350..9cc4530e73 100644 --- a/plugins/mail-notification/org-gnome-mail-notification.eplug.xml +++ b/plugins/mail-notification/org-gnome-mail-notification.eplug.xml @@ -5,7 +5,8 @@ _name="Mail Notification" location="@PLUGINDIR@/liborg-gnome-mail-notification@SOEXT@"> - <_description>Notifies the user with an icon in notification area and a notification message whenever a new message has arrived. + <_description>Generates a D-Bus message or notifies the user with an icon in notification area and a notification message whenever a new message has arrived. + @@ -20,15 +21,5 @@ handle="org_gnome_mail_read_notify" target="message"/> - -- cgit v1.2.3