finch/finchnotifications.c

changeset 42678
0b9b81b6ff18
parent 42677
66b49e545c53
child 42679
192a8112562f
equal deleted inserted replaced
42677:66b49e545c53 42678:0b9b81b6ff18
1 /*
2 * Finch - Universal Text Chat Client
3 * Copyright (C) Pidgin Developers <devel@pidgin.im>
4 *
5 * Finch is the legal property of its developers, whose names are too numerous
6 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * source distribution.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23 #include <purpleconfig.h>
24
25 #include <glib.h>
26 #include <glib/gi18n-lib.h>
27 #include <glib/gstdio.h>
28
29 #include <purple.h>
30
31 #include <gnt.h>
32
33 #include "finchnotifications.h"
34
35 #include "gntaccount.h"
36
37 static struct {
38 GntWidget *window;
39 GntWidget *list;
40 } notifications;
41
42 /*******************************************************************************
43 * Helpers
44 ******************************************************************************/
45 static void
46 finch_notifications_update(GntTree *list, GListModel *model) {
47 guint index = 0;
48
49 gnt_tree_remove_all(GNT_TREE(list));
50
51 for(index = 0; index < g_list_model_get_n_items(model); index++) {
52 PurpleNotification *notification = g_list_model_get_item(model, index);
53 GntTreeRow *row = NULL;
54
55 row = gnt_tree_create_row(list,
56 purple_notification_get_title(notification));
57 gnt_tree_add_row_last(list, notification, row, NULL);
58 }
59 }
60
61 static void
62 finch_notification_delete_notification(PurpleNotification *notification) {
63 if(PURPLE_IS_NOTIFICATION(notification)) {
64 PurpleNotificationManager *manager = NULL;
65
66 purple_notification_delete(notification);
67
68 manager = purple_notification_manager_get_default();
69 purple_notification_manager_remove(manager, notification);
70 }
71 }
72
73 /*******************************************************************************
74 * Finch Notification Callbacks
75 ******************************************************************************/
76 static void
77 finch_notification_delete(G_GNUC_UNUSED GntWidget *widget, gpointer data) {
78 PurpleNotification *notification = g_object_get_data(data, "notification");
79
80 finch_notification_delete_notification(notification);
81
82 gnt_widget_destroy(GNT_WIDGET(data));
83 }
84
85 static void
86 finch_notification_reconnect_account(G_GNUC_UNUSED GntWidget *widget,
87 gpointer data)
88 {
89 PurpleNotification *notification = g_object_get_data(data, "notification");
90 PurpleAccount *account = purple_notification_get_account(notification);
91
92 if(PURPLE_IS_ACCOUNT(account)) {
93 purple_account_connect(account);
94 }
95
96 gnt_widget_destroy(GNT_WIDGET(data));
97 }
98
99 static void
100 finch_notification_reenable_account(G_GNUC_UNUSED GntWidget *widget,
101 gpointer data)
102 {
103 PurpleNotification *notification = g_object_get_data(data, "notification");
104 PurpleAccount *account = purple_notification_get_account(notification);
105
106 if(PURPLE_IS_ACCOUNT(account)) {
107 purple_account_set_enabled(account, TRUE);
108 }
109
110 gnt_widget_destroy(GNT_WIDGET(data));
111 }
112
113 static void
114 finch_notification_modify_account(G_GNUC_UNUSED GntWidget *widget,
115 gpointer data)
116 {
117 PurpleNotification *notification = g_object_get_data(data, "notification");
118 PurpleAccount *account = purple_notification_get_account(notification);
119
120 if(PURPLE_IS_ACCOUNT(account)) {
121 finch_account_dialog_show(account);
122 }
123
124 gnt_widget_destroy(GNT_WIDGET(data));
125 }
126
127 static void
128 finch_notification_contact_authorize(G_GNUC_UNUSED GntWidget *widget,
129 gpointer data)
130 {
131 PurpleAccount *account = NULL;
132 PurpleNotification *notification = NULL;
133 PurpleNotificationManager *manager = NULL;
134 PurpleAuthorizationRequest *auth_request = NULL;
135 const gchar *alias = NULL, *username = NULL;
136
137 /* Get the notification and authorization request from the data. */
138 notification = g_object_get_data(data, "notification");
139 auth_request = purple_notification_get_data(notification);
140
141 /* Accept the authorization request. */
142 purple_authorization_request_accept(auth_request);
143
144 /* Remove the notification from the manager. */
145 manager = purple_notification_manager_get_default();
146 purple_notification_manager_remove(manager, notification);
147
148 /* Request the user to add the person they just authorized. */
149 account = purple_authorization_request_get_account(auth_request);
150 alias = purple_authorization_request_get_alias(auth_request);
151 username = purple_authorization_request_get_username(auth_request);
152 purple_blist_request_add_buddy(account, username, NULL, alias);
153
154 /* Destroy the dialog. */
155 gnt_widget_destroy(GNT_WIDGET(data));
156 }
157
158 static void
159 finch_notification_contact_deny(G_GNUC_UNUSED GntWidget *widget, gpointer data)
160 {
161 PurpleNotification *notification = NULL;
162 PurpleNotificationManager *manager = NULL;
163 PurpleAuthorizationRequest *auth_request = NULL;
164
165 /* Get the notification and authorization request from the data. */
166 notification = g_object_get_data(data, "notification");
167 auth_request = purple_notification_get_data(notification);
168
169 /* Deny the request. */
170 purple_authorization_request_deny(auth_request, NULL);
171
172 /* Remove the notification from the manager. */
173 manager = purple_notification_manager_get_default();
174 purple_notification_manager_remove(manager, notification);
175
176 /* Destroy the dialog. */
177 gnt_widget_destroy(GNT_WIDGET(data));
178 }
179
180 /*******************************************************************************
181 * Finch Notification API
182 ******************************************************************************/
183 static void
184 finch_notification_show(PurpleNotification *notification) {
185 GntWidget *dialog = NULL, *label = NULL, *hbox = NULL, *button = NULL;
186 PurpleAccount *account = NULL;
187 PurpleNotificationType type;
188 gpointer data = NULL;
189
190 account = purple_notification_get_account(notification);
191
192 dialog = gnt_box_new(FALSE, TRUE);
193 gnt_box_set_toplevel(GNT_BOX(dialog), TRUE);
194 gnt_box_set_alignment(GNT_BOX(dialog), GNT_ALIGN_MID);
195 g_object_set_data(G_OBJECT(dialog), "notification", notification);
196
197 label = gnt_label_new(purple_notification_get_title(notification));
198 gnt_box_add_widget(GNT_BOX(dialog), label);
199
200 hbox = gnt_box_new(FALSE, FALSE);
201
202 type = purple_notification_get_notification_type(notification);
203 data = purple_notification_get_data(notification);
204
205 if(type == PURPLE_NOTIFICATION_TYPE_GENERIC) {
206 gnt_box_set_title(GNT_BOX(dialog),
207 purple_notification_get_title(notification));
208 label = gnt_label_new(purple_notification_get_data(notification));
209 gnt_box_add_widget(GNT_BOX(dialog), label);
210 } else if(type == PURPLE_NOTIFICATION_TYPE_CONNECTION_ERROR) {
211 PurpleConnectionErrorInfo *info = data;
212
213 /* Set the title. */
214 gnt_box_set_title(GNT_BOX(dialog), _("Connection Error"));
215
216 /* Add the connection error reason. */
217 label = gnt_label_new(info->description);
218 gnt_box_add_widget(GNT_BOX(dialog), label);
219
220 /* Add the buttons. */
221 if(purple_account_get_enabled(account)) {
222 button = gnt_button_new(_("Reconnect"));
223 g_signal_connect(button, "activate",
224 G_CALLBACK(finch_notification_reconnect_account),
225 dialog);
226 } else {
227 button = gnt_button_new(_("Re-enable"));
228 g_signal_connect(button, "activate",
229 G_CALLBACK(finch_notification_reenable_account),
230 dialog);
231 }
232 gnt_box_add_widget(GNT_BOX(hbox), button);
233
234 button = gnt_button_new(_("Modify Account"));
235 g_signal_connect(button, "activate",
236 G_CALLBACK(finch_notification_modify_account),
237 dialog);
238 gnt_box_add_widget(GNT_BOX(hbox), button);
239 } else if(type == PURPLE_NOTIFICATION_TYPE_AUTHORIZATION_REQUEST) {
240 PurpleAuthorizationRequest *auth_request = NULL;
241 const gchar *message = NULL;
242
243 /* Set the title. */
244 gnt_box_set_title(GNT_BOX(dialog), _("Authorization Request"));
245
246 auth_request = purple_notification_get_data(notification);
247 message = purple_authorization_request_get_message(auth_request);
248
249 /* Add the message if we have one. */
250 if(message != NULL && *message != '\0') {
251 label = gnt_label_new(message);
252 gnt_box_add_widget(GNT_BOX(dialog), label);
253 }
254
255 /* Add the buttons. */
256 button = gnt_button_new(_("Authorize"));
257 g_signal_connect(button, "activate",
258 G_CALLBACK(finch_notification_contact_authorize),
259 dialog);
260 gnt_box_add_widget(GNT_BOX(hbox), button);
261
262 button = gnt_button_new(_("Deny"));
263 g_signal_connect(button, "activate",
264 G_CALLBACK(finch_notification_contact_deny), dialog);
265 gnt_box_add_widget(GNT_BOX(hbox), button);
266 }
267
268 gnt_box_add_widget(GNT_BOX(dialog), hbox);
269
270 button = gnt_button_new(_("Delete"));
271 g_signal_connect(button, "activate",
272 G_CALLBACK(finch_notification_delete), dialog);
273 gnt_box_add_widget(GNT_BOX(hbox), button);
274
275 gnt_widget_show(dialog);
276 }
277
278 /*******************************************************************************
279 * Callbacks
280 ******************************************************************************/
281 static void
282 finch_notifications_changed_cb(GListModel *model,
283 G_GNUC_UNUSED guint position,
284 G_GNUC_UNUSED guint removed,
285 guint added,
286 gpointer data)
287 {
288 finch_notifications_update(data, model);
289
290 if(added > 0) {
291 gnt_widget_set_urgent(notifications.window);
292 }
293 }
294
295 static void
296 finch_notifications_open_cb(G_GNUC_UNUSED GntWidget *w,
297 G_GNUC_UNUSED gpointer data)
298 {
299 PurpleNotification *notification = NULL;
300
301 notification = gnt_tree_get_selection_data(GNT_TREE(notifications.list));
302 if(!PURPLE_IS_NOTIFICATION(notification)) {
303 return;
304 }
305
306 finch_notification_show(notification);
307 }
308
309 static void
310 finch_notifications_delete_cb(G_GNUC_UNUSED GntWidget *widget,
311 G_GNUC_UNUSED gpointer data)
312 {
313 PurpleNotification *notification = NULL;
314
315 notification = gnt_tree_get_selection_data(GNT_TREE(notifications.list));
316
317 finch_notification_delete_notification(notification);
318 }
319
320
321 static void
322 finch_notifications_activate_cb(G_GNUC_UNUSED GntWidget *w,
323 G_GNUC_UNUSED gpointer data)
324 {
325 PurpleNotification *notification = NULL;
326
327 notification = gnt_tree_get_selection_data(GNT_TREE(notifications.list));
328
329 finch_notification_show(notification);
330 }
331
332 /*******************************************************************************
333 * Public API
334 ******************************************************************************/
335 void
336 finch_notifications_window_show(void) {
337 GntWidget *wid, *box;
338 GListModel *model = NULL;
339
340 if(notifications.window) {
341 gnt_window_present(notifications.window);
342
343 return;
344 }
345
346 notifications.window = gnt_vbox_new(FALSE);
347 gnt_box_set_toplevel(GNT_BOX(notifications.window), TRUE);
348 gnt_box_set_fill(GNT_BOX(notifications.window), TRUE);
349 gnt_box_set_title(GNT_BOX(notifications.window), _("Notifications"));
350 gnt_box_set_alignment(GNT_BOX(notifications.window), GNT_ALIGN_MID);
351 gnt_box_set_pad(GNT_BOX(notifications.window), 0);
352 gnt_widget_set_name(notifications.window, "notifications");
353
354 /* Create the box that lists all of the notifications. */
355 notifications.list = gnt_tree_new_with_columns(1);
356 gnt_tree_set_compare_func(GNT_TREE(notifications.list),
357 purple_notification_compare);
358 gnt_widget_set_has_border(notifications.list, FALSE);
359 gnt_box_add_widget(GNT_BOX(notifications.window), notifications.list);
360 g_signal_connect(notifications.list, "activate",
361 G_CALLBACK(finch_notifications_activate_cb), NULL);
362
363 /* Get the notification manager to get the model and populate the list. */
364 model = purple_notification_manager_get_default_as_model();
365 finch_notifications_update(GNT_TREE(notifications.list), model);
366 g_signal_connect_object(model, "items-changed",
367 G_CALLBACK(finch_notifications_changed_cb),
368 notifications.list, 0);
369
370 gnt_box_add_widget(GNT_BOX(notifications.window), gnt_line_new(FALSE));
371
372 box = gnt_hbox_new(FALSE);
373 gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID);
374 gnt_box_set_fill(GNT_BOX(box), FALSE);
375
376 wid = gnt_button_new(_("Open"));
377 g_signal_connect(wid, "activate", G_CALLBACK(finch_notifications_open_cb),
378 NULL);
379 gnt_box_add_widget(GNT_BOX(box), wid);
380
381 wid = gnt_button_new(_("Delete"));
382 g_signal_connect(wid, "activate", G_CALLBACK(finch_notifications_delete_cb),
383 NULL);
384 gnt_box_add_widget(GNT_BOX(box), wid);
385
386 gnt_box_add_widget(GNT_BOX(notifications.window), box);
387
388 gnt_widget_show(notifications.window);
389 }
390
391 void
392 finch_notifications_init(void) {
393 }
394
395 void
396 finch_notifications_uninit(void) {
397 g_clear_pointer(&notifications.window, gnt_widget_destroy);
398 }

mercurial