~ubuntu-branches/ubuntu/vivid/liferea/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/notification-append/src/notification/libnotify.c

  • Committer: Package Import Robot
  • Author(s): bojo42
  • Date: 2012-03-29 14:17:21 UTC
  • mfrom: (1.3.9) (3.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20120329141721-tbfopcrc5797wxt7
Tags: 1.8.3-0.1ubuntu1
* New upstream release (LP: #290666, #371754, #741543, #716688)
* Merge from Debian unstable (LP: #935147), remaining changes:
* debian/patches:
  - drop gtk-status-icon.patch & notification-append as in upstream
  - drop fix_systray_behavior as mostly upstreamed and rest seems unused
  - 01_ubuntu_feedlists: update & rename, move planets to "Open Source"  
  - add_X-Ubuntu-Gettext-Domain: rebase
  - libunity.patch: rebase, apply before indicator patch (liferea_shell.c)
  - libindicate_increase_version.patch: exclude from libindicate.patch
  - deactivate libindicate.patch, seems partly upstreamed and needs rework
* debian/control: libindicate-dev, libindicate-gtk-dev & libunity-dev
* debian/liferea.indicate & liferea.install: ship indicator desktop file
* debian/rules: enable libindicate

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/** 
2
 
 * @file notif_libnotify.c notifications via libnotify
3
 
 *
4
 
 * Copyright (c) 2006, Norman Jonas <liferea.sf.net@devport.codepilot.net>
5
 
 *            
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version. 
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
 
21
 
#ifdef HAVE_CONFIG_H
22
 
#  include <config.h>
23
 
#endif
24
 
 
25
 
#include <string.h>
26
 
#include <gtk/gtk.h>
27
 
#include <glib.h>
28
 
 
29
 
#include <libnotify/notify.h>
30
 
 
31
 
#include "common.h"
32
 
#include "conf.h"
33
 
#include "debug.h"
34
 
#include "node.h"
35
 
#include "item.h"
36
 
#include "item_state.h"
37
 
#include "plugin.h"
38
 
#include "feedlist.h"
39
 
#include "ui/liferea_shell.h"
40
 
#include "ui/ui_feedlist.h"
41
 
#include "ui/ui_tray.h"
42
 
#include "ui/ui_common.h"
43
 
 
44
 
#include "notification/notification.h"
45
 
 
46
 
static gboolean supports_actions = FALSE;
47
 
 
48
 
static void notif_libnotify_callback_open ( NotifyNotification *n, gchar *action, gpointer user_data ) {
49
 
        g_assert(action != NULL);
50
 
        g_assert(strcmp(action, "open") == 0);
51
 
 
52
 
        nodePtr node_p = node_from_id(user_data);
53
 
        
54
 
        if(node_p)
55
 
                ui_feedlist_select(node_p);
56
 
        else
57
 
                ui_show_error_box(_("This feed does not exist anymore!"));
58
 
 
59
 
        notify_notification_close(n, NULL);
60
 
 
61
 
        liferea_shell_present ();
62
 
}
63
 
 
64
 
static void
65
 
notif_libnotify_callback_mark_read (NotifyNotification *n, gchar *action, gpointer user_data)
66
 
{
67
 
        g_assert (action != NULL);
68
 
        g_assert (strcmp (action, "mark_read") == 0);
69
 
 
70
 
        nodePtr node = node_from_id (user_data);
71
 
        
72
 
        if (node) {
73
 
                feedlist_mark_all_read (node);
74
 
                feedlist_reset_new_item_count ();
75
 
                item_state_set_all_popup (node->id);
76
 
        } else {
77
 
                ui_show_error_box (_("This feed does not exist anymore!"));
78
 
        }
79
 
        
80
 
        notify_notification_close (n, NULL);
81
 
}
82
 
 
83
 
static void notif_libnotify_callback_show_details ( NotifyNotification *n, gchar *action, gpointer user_data ) {
84
 
        nodePtr node_p;
85
 
 
86
 
        GList *list_p;
87
 
        itemPtr item_p;
88
 
 
89
 
        gchar *labelText_p;
90
 
        gchar *labelText_now_p = NULL;
91
 
        gchar *labelText_prev_p;
92
 
 
93
 
        gchar *labelHeadline_p;
94
 
        const gchar *labelURL_p;
95
 
 
96
 
        gint item_count = 0;
97
 
        
98
 
        g_assert(action != NULL);
99
 
        g_assert(strcmp(action, "show_details") == 0);
100
 
        node_p = node_from_id(user_data);
101
 
        
102
 
        if(node_p) {
103
 
                itemSetPtr itemSet = node_get_itemset (node_p);
104
 
 
105
 
                labelText_now_p = g_strdup("");
106
 
 
107
 
                /* Gather the feed's headlines */
108
 
                list_p = itemSet->ids;
109
 
                while (list_p) {
110
 
                        item_p = item_load ( GPOINTER_TO_UINT (list_p->data));
111
 
                        if (item_p->popupStatus && !item_p->readStatus) {
112
 
                                item_p->popupStatus = FALSE;
113
 
                                item_count += 1;
114
 
 
115
 
                                labelHeadline_p = g_strdup (item_get_title(item_p));
116
 
                                if (labelHeadline_p == NULL ) {
117
 
                                        labelHeadline_p = g_strdup_printf (_("This news entry has no headline") );
118
 
                                }
119
 
 
120
 
                                labelURL_p = item_get_base_url(item_p);
121
 
                                if (labelURL_p != NULL ) {
122
 
                                        labelText_p = g_strdup_printf ("%s <a href='%s'>%s</a>\n", labelHeadline_p, labelURL_p, _("Visit") );
123
 
                                } else {
124
 
                                        labelText_p = g_strdup_printf ("%s\n", labelHeadline_p );
125
 
                                }
126
 
 
127
 
                                labelText_prev_p = labelText_now_p;
128
 
                                labelText_now_p = g_strconcat( labelText_now_p, labelText_p, NULL);
129
 
 
130
 
                                g_free(labelHeadline_p);
131
 
                                g_free(labelText_p);
132
 
                                g_free(labelText_prev_p);
133
 
                        }
134
 
                        item_unload (item_p);
135
 
                        list_p = g_list_next (list_p);
136
 
                }
137
 
                itemset_free (itemSet);
138
 
 
139
 
                if (item_count == 0) {
140
 
                        g_free (labelText_now_p);
141
 
                        return;
142
 
                }
143
 
        } else {
144
 
                ui_show_error_box(_("This feed does not exist anymore!"));
145
 
        }
146
 
 
147
 
        notify_notification_close ( n,NULL);
148
 
        
149
 
        if(node_p) {
150
 
//              notify_notification_update ( n, node_get_title(node_p), labelText_now_p, NULL);
151
 
//              notify_notification_clear_actions(n);
152
 
 
153
 
                n = notify_notification_new (node_get_title(node_p), labelText_now_p, NULL, NULL);
154
 
 
155
 
                notify_notification_set_icon_from_pixbuf (n,node_get_icon(node_p));
156
 
 
157
 
                notify_notification_set_category (n, "feed");
158
 
 
159
 
                notify_notification_set_timeout (n, NOTIFY_EXPIRES_NEVER );
160
 
 
161
 
                if (supports_actions) {
162
 
                        notify_notification_add_action(n, "open", _("Open feed"),
163
 
                                                        (NotifyActionCallback)notif_libnotify_callback_open,
164
 
                                                        node_p->id, NULL);
165
 
                        notify_notification_add_action(n, "mark_read", _("Mark all as read"),
166
 
                                                        (NotifyActionCallback)notif_libnotify_callback_mark_read,
167
 
                                                        node_p->id, NULL);
168
 
                }
169
 
 
170
 
                conf_get_bool_value(SHOW_TRAY_ICON);
171
 
                if (!notify_notification_show (n, NULL)) {
172
 
                        fprintf(stderr, "PLUGIN:notif_libnotify.c - failed to update notification via libnotify\n");
173
 
                }
174
 
 
175
 
                g_free(labelText_now_p);
176
 
        }
177
 
}
178
 
 
179
 
static gboolean notif_libnotify_init(void) {
180
 
 
181
 
        GList *caps, *c;
182
 
 
183
 
        /* Check whether the notification daemon supports actions, per Actions
184
 
           in http://www.galago-project.org/specs/notification/0.9/x81.html */
185
 
        if (notify_init ("liferea")) {
186
 
                caps = notify_get_server_caps ();
187
 
                if (caps != NULL) {
188
 
                        for (c = caps; c != NULL; c = c->next) {
189
 
                                if (g_str_equal ((char*)c->data, "actions")) {
190
 
                                        supports_actions = TRUE;
191
 
                                        break;
192
 
                                }
193
 
                        }
194
 
                        g_list_foreach (caps, (GFunc)g_free, NULL);
195
 
                        g_list_free (caps);
196
 
                }
197
 
 
198
 
                return TRUE;
199
 
        } else {
200
 
                debug0 (DEBUG_GUI, "libnotify.c: notify_init returned FALSE");
201
 
                return FALSE;
202
 
        }
203
 
}
204
 
 
205
 
static void notif_libnotify_deinit(void) {
206
 
        notify_uninit();
207
 
}
208
 
 
209
 
static void notif_libnotify_enable(void) { }
210
 
 
211
 
static void notif_libnotify_disable(void) { }
212
 
 
213
 
static void
214
 
notif_libnotify_node_has_new_items (nodePtr node, gboolean enforced)
215
 
{       
216
 
        itemSetPtr      itemSet;
217
 
        GList           *iter;
218
 
        
219
 
        NotifyNotification *n;
220
 
 
221
 
        GtkRequisition  size;
222
 
        gint            x, y;
223
 
 
224
 
        gchar           *labelSummary_p;
225
 
        gint            item_count = 0;
226
 
 
227
 
        if (!conf_get_bool_value(SHOW_POPUP_WINDOWS) && !enforced)
228
 
                return;
229
 
 
230
 
        /* Count updated feed */
231
 
        itemSet = node_get_itemset (node);
232
 
        iter = itemSet->ids;
233
 
        while (iter) {
234
 
                itemPtr item = item_load (GPOINTER_TO_UINT (iter->data));
235
 
                if (item->popupStatus && !item->readStatus)
236
 
                        item_count++;
237
 
                item_unload (item);
238
 
                iter = g_list_next (iter);
239
 
        }
240
 
        itemset_free (itemSet);
241
 
 
242
 
        if (item_count == 0)
243
 
                return;
244
 
 
245
 
        labelSummary_p = g_strdup_printf (ngettext ("%s has %d new / updated headline\n", "%s has %d new / updated headlines\n", item_count), 
246
 
                                          node_get_title (node), item_count);
247
 
        n = notify_notification_new ( _("Feed Update"), labelSummary_p, NULL, NULL);
248
 
        g_free(labelSummary_p);
249
 
 
250
 
        notify_notification_set_icon_from_pixbuf (n, node_get_icon (node));
251
 
        notify_notification_set_timeout (n, NOTIFY_EXPIRES_DEFAULT);
252
 
        if (supports_actions) {
253
 
                notify_notification_add_action (n, "show_details", _("Show details"),
254
 
                                        (NotifyActionCallback)notif_libnotify_callback_show_details,
255
 
                                        node->id, NULL);
256
 
                notify_notification_add_action (n, "open", _("Open feed"),
257
 
                                        (NotifyActionCallback)notif_libnotify_callback_open,
258
 
                                        node->id, NULL);
259
 
                notify_notification_add_action (n, "mark_read", _("Mark all as read"),
260
 
                                        (NotifyActionCallback)notif_libnotify_callback_mark_read,
261
 
                                        node->id, NULL);
262
 
        }
263
 
        notify_notification_set_category (n, "feed");
264
 
 
265
 
        if (ui_tray_get_origin (&x, &y) == TRUE) {
266
 
                ui_tray_size_request (&size);
267
 
 
268
 
                x += size.width / 2;
269
 
                y += size.height;
270
 
 
271
 
                notify_notification_set_hint_int32 (n, "x", x);
272
 
                notify_notification_set_hint_int32 (n, "y", y);
273
 
        }
274
 
 
275
 
        if (!notify_notification_show (n, NULL))
276
 
                g_warning ("PLUGIN:notif_libnotify.c - failed to send notification via libnotify");
277
 
}
278
 
        
279
 
static void notif_libnotify_node_removed(nodePtr node) { }
280
 
 
281
 
/* notification plugin definition */
282
 
 
283
 
static struct notificationPlugin npi = {
284
 
        NOTIFICATION_PLUGIN_API_VERSION,
285
 
        NOTIFICATION_TYPE_POPUP,
286
 
        10,
287
 
        "libnotify",
288
 
        notif_libnotify_init,
289
 
        notif_libnotify_deinit,
290
 
        notif_libnotify_enable,
291
 
        notif_libnotify_disable,
292
 
        notif_libnotify_node_has_new_items,
293
 
        notif_libnotify_node_removed
294
 
};
295
 
 
296
 
static struct plugin pi = {
297
 
        PLUGIN_API_VERSION,
298
 
        "libnotify notification",
299
 
        PLUGIN_TYPE_NOTIFICATION,
300
 
        //"Implementation of a notification using libnotify.",
301
 
        &npi
302
 
};
303
 
 
304
 
DECLARE_PLUGIN(pi);
305
 
DECLARE_NOTIFICATION_PLUGIN(npi);