381eabc3496ebd6c109eb6e65e04523c2a1ac947
[claws.git] / src / plugins / notification / notification_indicator.c
1 /* Notification plugin for Claws-Mail
2  * Copyright (C) 2005-2009 Holger Berndt and the Claws Mail Team.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #ifdef HAVE_CONFIG_H
19 #  include "config.h"
20 #  include "claws-features.h"
21 #endif
22
23 #ifdef NOTIFICATION_INDICATOR
24
25 #include "notification_indicator.h"
26 #include "notification_prefs.h"
27 #include "notification_core.h"
28
29 #include "folder.h"
30 #include "common/utils.h"
31
32 #include <libindicate/server.h>
33 #include <libindicate/indicator.h>
34 #include <libindicate/indicator-messages.h>
35
36 static IndicateServer *server = NULL;
37 static GHashTable *indicators = NULL;
38 static gulong mainwin_state_changed_signal_id = 0;
39
40 void notification_indicator_destroy(void)
41 {
42   if(indicators) {
43     g_hash_table_destroy(indicators);
44     indicators = NULL;
45   }
46   if(server) {
47     indicate_server_hide(server);
48     g_object_unref(server);
49     server = NULL;
50   }
51   if(mainwin_state_changed_signal_id != 0) {
52     MainWindow *mainwin;
53     if((mainwin = mainwindow_get_mainwindow()) != NULL)
54       g_signal_handler_disconnect(mainwin->window, mainwin_state_changed_signal_id);
55     mainwin_state_changed_signal_id = 0;
56   }
57
58 }
59
60 static void show_claws_mail(IndicateIndicator *indicator, guint dummy, gpointer data)
61 {
62   MainWindow *mainwin;
63
64   if((mainwin = mainwindow_get_mainwindow()) == NULL)
65     return;
66
67   notification_show_mainwindow(mainwin);
68   if(data) {
69     Folder *folder = data;
70     FolderItem *item = folder->inbox;
71
72     gchar *path = folder_item_get_identifier(item);
73     mainwindow_jump_to(path, FALSE);
74     g_free(path);
75   }
76 }
77
78 static void set_indicator_unread_count(IndicateIndicator *indicator, gint new, gint unread)
79 {
80   gchar *count_str;
81
82   count_str = g_strdup_printf("%d / %d", new, unread);
83   indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count_str);
84   g_free(count_str);
85 }
86
87 static void create_indicators(void)
88 {
89   IndicateIndicator *indicator;
90   GList *cur_mb;
91
92   indicators = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
93
94   for(cur_mb = folder_get_list(); cur_mb; cur_mb = cur_mb->next) {
95     gchar *name;
96     Folder *folder = cur_mb->data;
97
98     if(!folder->name) {
99       debug_print("Notification plugin: Warning: Ignoring unnamed mailbox in indicator applet\n");
100       continue;
101     }
102     name = g_strdup(folder->name);
103
104     indicator = indicate_indicator_new();
105     indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, name);
106     set_indicator_unread_count(indicator, 0, 0);
107     g_object_set_data(G_OBJECT(indicator), "new_msgs", GINT_TO_POINTER(0));
108     g_object_set_data(G_OBJECT(indicator), "unread_msgs", GINT_TO_POINTER(0));
109     g_signal_connect(indicator, "user-display", G_CALLBACK (show_claws_mail), folder);
110     indicate_indicator_show(indicator);
111     g_hash_table_insert(indicators, name, indicator);
112   }
113 }
114
115 static gboolean mainwin_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
116 {
117   if(notify_config.indicator_hide_minimized) {
118     MainWindow *mainwin;
119
120     if((mainwin = mainwindow_get_mainwindow()) == NULL)
121       return FALSE;
122
123     if((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
124       gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwin->window), TRUE);
125     }
126     else if((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) && !(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
127       gtk_window_set_skip_taskbar_hint(GTK_WINDOW(mainwin->window), FALSE);
128     }
129   }
130   return FALSE;
131 }
132
133 void notification_update_indicator(void)
134 {
135   GHashTableIter iter;
136   gpointer key, value;
137
138   if(!mainwin_state_changed_signal_id) {
139     MainWindow *mainwin;
140
141     if((mainwin = mainwindow_get_mainwindow()) != NULL)
142       mainwin_state_changed_signal_id = g_signal_connect(G_OBJECT(mainwin->window), "window-state-event", G_CALLBACK(mainwin_state_event), NULL);
143   }
144
145
146   if(!notify_config.indicator_enabled)
147     return;
148
149   if(!server) {
150     server = indicate_server_ref_default();
151     indicate_server_set_type (server, "message.mail");
152     indicate_server_set_desktop_file(server, get_desktop_file());
153     g_signal_connect(server, "server-display", G_CALLBACK(show_claws_mail), NULL);
154     indicate_server_show(server);
155   }
156
157   if(!indicators)
158     create_indicators();
159
160   /* check accounts for new/unread counts */
161   g_hash_table_iter_init(&iter, indicators);
162   while(g_hash_table_iter_next(&iter, &key, &value)) {
163     NotificationMsgCount count;
164     gchar *foldername = key;
165     IndicateIndicator *indicator = value;
166
167     notification_core_get_msg_count_of_foldername(foldername, &count);
168
169     set_indicator_unread_count(indicator, count.new_msgs, count.unread_msgs);
170     indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION,
171                                     (count.new_msgs > 0) ? "true" : "false");
172     g_object_set_data(G_OBJECT(indicator), "new_msgs", GINT_TO_POINTER(count.new_msgs));
173     g_object_set_data(G_OBJECT(indicator), "unread_msgs", GINT_TO_POINTER(count.unread_msgs));
174   }
175 }
176
177 #endif /* NOTIFICATION_INDICATOR */