comparison src/gtkprivacy.c @ 6371:8f94cce8faa5

[gaim-migrate @ 6876] I think I touched almost every file. Here's what happened. I started off fixing up the Makefile.am and configure.ac files to help with the core/UI split some. Then I got annoyed with the build_{allow,deny}_list() functions that everything used, and decided to core/UI split privacy. While doing that, I decided to redesign the dialog. So now, a lot has changed, but not really so much. Just that most files got affected. Oh yeah, and the UI stuff was taken out of internal.h and moved to gtkinternal.h. If you use this, please be aware of this change. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Tue, 05 Aug 2003 10:55:04 +0000
parents
children ca73fdf3eb38
comparison
equal deleted inserted replaced
6370:a4b83df2165b 6371:8f94cce8faa5
1 /**
2 * @file gtkprivacy.c GTK+ Privacy UI
3 * @ingroup gtkui
4 *
5 * gaim
6 *
7 * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org>
8 * Copyright (C) 2002-2003 Rob Flynn <rob@marko.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 #include "gtkinternal.h"
25
26 #include "connection.h"
27 #include "debug.h"
28 #include "privacy.h"
29 #include "request.h"
30 #include "util.h"
31
32 #include "gtkprivacy.h"
33 #include "gtkutils.h"
34
35 typedef enum
36 {
37 GAIM_GTK_PRIVACY_ALLOW_ALL = 0,
38 GAIM_GTK_PRIVACY_ALLOW_BUDDYLIST,
39 GAIM_GTK_PRIVACY_ALLOW_USERS,
40 GAIM_GTK_PRIVACY_DENY_ALL,
41 GAIM_GTK_PRIVACY_DENY_USERS
42
43 } GaimGtkPrivacyType;
44
45 typedef struct
46 {
47 GtkWidget *win;
48
49 GtkWidget *type_menu;
50
51 GtkWidget *add_button;
52 GtkWidget *remove_button;
53 GtkWidget *clear_button;
54
55 GtkWidget *button_box;
56 GtkWidget *allow_widget;
57 GtkWidget *block_widget;
58
59 GtkListStore *allow_store;
60 GtkListStore *block_store;
61
62 GtkWidget *allow_list;
63 GtkWidget *block_list;
64
65 gboolean in_allow_list;
66
67 GaimAccount *account;
68
69 } GaimGtkPrivacyDialog;
70
71 typedef struct
72 {
73 GaimAccount *account;
74 char *name;
75 gboolean block;
76
77 } GaimGtkPrivacyRequestData;
78
79 static struct
80 {
81 const char *text;
82 int num;
83
84 } menu_entries[] =
85 {
86 { N_("Allow all users to contact me"), 1 },
87 { N_("Allow only the users on my buddy list"), 5 },
88 { N_("Allow only the users below"), 3 },
89 { N_("Block all users"), 2 },
90 { N_("Block the users below"), 4 }
91 };
92
93 static size_t menu_entry_count = sizeof(menu_entries) / sizeof(*menu_entries);
94
95 static GaimGtkPrivacyDialog *privacy_dialog = NULL;
96
97 static void
98 rebuild_allow_list(GaimGtkPrivacyDialog *dialog)
99 {
100 GSList *l;
101 GtkTreeIter iter;
102
103 gtk_list_store_clear(dialog->allow_store);
104
105 for (l = dialog->account->permit; l != NULL; l = l->next) {
106 gtk_list_store_append(dialog->allow_store, &iter);
107 gtk_list_store_set(dialog->allow_store, &iter, 0, l->data, -1);
108 }
109 }
110
111 static void
112 rebuild_block_list(GaimGtkPrivacyDialog *dialog)
113 {
114 GSList *l;
115 GtkTreeIter iter;
116
117 gtk_list_store_clear(dialog->block_store);
118
119 for (l = dialog->account->deny; l != NULL; l = l->next) {
120 gtk_list_store_append(dialog->block_store, &iter);
121 gtk_list_store_set(dialog->block_store, &iter, 0, l->data, -1);
122 }
123 }
124
125 static const char *
126 find_permit_block_by_name(GSList *list, const char *name)
127 {
128 const char *temp_name;
129 GSList *l;
130
131 for (l = list; l != NULL; l = l->next) {
132 temp_name = (const char *)l->data;
133
134 if (!gaim_utf8_strcasecmp(name, temp_name))
135 return temp_name;
136 }
137
138 return NULL;
139 }
140
141 static void
142 user_selected_cb(GtkTreeSelection *sel, GaimGtkPrivacyDialog *dialog)
143 {
144 gtk_widget_set_sensitive(dialog->remove_button, TRUE);
145 }
146
147 static GtkWidget *
148 build_list(GaimGtkPrivacyDialog *dialog, GtkListStore *model,
149 GtkWidget **ret_treeview)
150 {
151 GtkWidget *sw;
152 GtkWidget *treeview;
153 GtkCellRenderer *rend;
154 GtkTreeViewColumn *column;
155 GtkTreeSelection *sel;
156
157 sw = gtk_scrolled_window_new(NULL, NULL);
158 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
159 GTK_POLICY_NEVER,
160 GTK_POLICY_AUTOMATIC);
161
162 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
163 *ret_treeview = treeview;
164
165 rend = gtk_cell_renderer_text_new();
166
167 column = gtk_tree_view_column_new_with_attributes(NULL, rend,
168 "text", 0,
169 NULL);
170 gtk_tree_view_column_set_clickable(GTK_TREE_VIEW_COLUMN(column), TRUE);
171 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
172 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
173 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), treeview);
174 gtk_widget_show(treeview);
175
176 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
177
178 g_signal_connect(G_OBJECT(sel), "changed",
179 G_CALLBACK(user_selected_cb), dialog);
180
181 return sw;
182 }
183
184 static GtkWidget *
185 build_allow_list(GaimGtkPrivacyDialog *dialog)
186 {
187 GtkWidget *widget;
188 GtkWidget *list;
189
190 dialog->allow_store = gtk_list_store_new(1, G_TYPE_STRING);
191
192 widget = build_list(dialog, dialog->allow_store, &list);
193
194 dialog->allow_list = list;
195
196 rebuild_allow_list(dialog);
197
198 return widget;
199 }
200
201 static GtkWidget *
202 build_block_list(GaimGtkPrivacyDialog *dialog)
203 {
204 GtkWidget *widget;
205 GtkWidget *list;
206
207 dialog->block_store = gtk_list_store_new(1, G_TYPE_STRING);
208
209 widget = build_list(dialog, dialog->block_store, &list);
210
211 dialog->block_list = list;
212
213 rebuild_block_list(dialog);
214
215 return widget;
216 }
217
218 static gint
219 destroy_cb(GtkWidget *w, GdkEvent *event, GaimGtkPrivacyDialog *dialog)
220 {
221 g_free(dialog);
222
223 privacy_dialog = NULL;
224
225 return 0;
226 }
227
228 static void
229 select_account_cb(GtkWidget *dropdown, GaimAccount *account,
230 GaimGtkPrivacyDialog *dialog)
231 {
232 int i;
233
234 dialog->account = account;
235
236 gaim_debug(GAIM_DEBUG_MISC, "select_account_cb",
237 "dialog = %p\n", dialog);
238 gaim_debug(GAIM_DEBUG_MISC, "select_account_cb",
239 "menu_entry_count = %d\n", menu_entry_count);
240
241 for (i = 0; i < menu_entry_count; i++) {
242 if (menu_entries[i].num == account->perm_deny) {
243 gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->type_menu), i);
244 break;
245 }
246 }
247
248 rebuild_allow_list(dialog);
249 rebuild_block_list(dialog);
250 }
251
252 static void
253 type_changed_cb(GtkOptionMenu *optmenu, GaimGtkPrivacyDialog *dialog)
254 {
255 int new_type = gtk_option_menu_get_history(optmenu);
256
257 dialog->account->perm_deny = menu_entries[new_type].num;
258 serv_set_permit_deny(gaim_account_get_connection(dialog->account));
259 gaim_blist_save();
260
261 gtk_widget_hide(dialog->allow_widget);
262 gtk_widget_hide(dialog->block_widget);
263 gtk_widget_hide(dialog->button_box);
264
265 if (new_type == 2) {
266 gtk_widget_show(dialog->allow_widget);
267 gtk_widget_show(dialog->button_box);
268 dialog->in_allow_list = TRUE;
269 }
270 else if (new_type == 4) {
271 gtk_widget_show(dialog->block_widget);
272 gtk_widget_show(dialog->button_box);
273 dialog->in_allow_list = FALSE;
274 }
275 }
276
277 static void
278 add_cb(GtkWidget *button, GaimGtkPrivacyDialog *dialog)
279 {
280 if (dialog->in_allow_list)
281 gaim_gtk_request_add_permit(dialog->account, NULL);
282 else
283 gaim_gtk_request_add_block(dialog->account, NULL);
284 }
285
286 static void
287 remove_cb(GtkWidget *button, GaimGtkPrivacyDialog *dialog)
288 {
289 GtkTreeIter iter;
290 GtkTreeModel *model;
291 GtkTreeSelection *sel;
292 char *name;
293
294 if (dialog->in_allow_list && dialog->allow_store == NULL)
295 return;
296
297 if (!dialog->in_allow_list && dialog->block_store == NULL)
298 return;
299
300 if (dialog->in_allow_list) {
301 model = GTK_TREE_MODEL(dialog->allow_store);
302 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->allow_list));
303 }
304 else {
305 model = GTK_TREE_MODEL(dialog->block_store);
306 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->block_list));
307 }
308
309 if (gtk_tree_selection_get_selected(sel, NULL, &iter))
310 gtk_tree_model_get(model, &iter, 0, &name, -1);
311 else
312 return;
313
314 if (dialog->in_allow_list) {
315 const char *new_name;
316
317 new_name = find_permit_block_by_name(dialog->account->permit, name);
318
319 if (new_name != NULL)
320 gaim_privacy_permit_remove(dialog->account, new_name);
321 }
322 else {
323 const char *new_name;
324
325 new_name = find_permit_block_by_name(dialog->account->deny, name);
326
327 if (new_name != NULL)
328 gaim_privacy_deny_remove(dialog->account, new_name);
329 }
330 }
331
332 static void
333 clear_cb(GtkWidget *button, GaimGtkPrivacyDialog *dialog)
334 {
335 }
336
337 static void
338 close_cb(GtkWidget *button, void *user_data)
339 {
340 gaim_gtk_privacy_dialog_hide();
341 }
342
343 static GaimGtkPrivacyDialog *
344 privacy_dialog_new(void)
345 {
346 GaimGtkPrivacyDialog *dialog;
347 GaimConnection *gc;
348 GtkWidget *bbox;
349 GtkWidget *hbox;
350 GtkWidget *vbox;
351 GtkWidget *button;
352 GtkWidget *dropdown;
353 GtkWidget *label;
354 GtkWidget *menu;
355 GtkWidget *sep;
356 int selected = 0;
357 int i;
358
359 dialog = g_new0(GaimGtkPrivacyDialog, 1);
360
361 gc = (GaimConnection *)gaim_connections_get_all()->data;
362 dialog->account = gaim_connection_get_account(gc);
363
364 dialog->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
365 gtk_window_set_resizable(GTK_WINDOW(dialog->win), FALSE);
366 gtk_window_set_role(GTK_WINDOW(dialog->win), "privacy");
367 gtk_window_set_title(GTK_WINDOW(dialog->win), _("Privacy"));
368 gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 12);
369
370 g_signal_connect(G_OBJECT(dialog->win), "delete_event",
371 G_CALLBACK(destroy_cb), dialog);
372
373 gtk_widget_realize(dialog->win);
374
375 /* Main vbox */
376 vbox = gtk_vbox_new(FALSE, 12);
377 gtk_container_add(GTK_CONTAINER(dialog->win), vbox);
378 gtk_widget_show(vbox);
379
380 /* Description label */
381 label = gtk_label_new(
382 _("Changes to privacy settings take effect immediately."));
383
384 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
385 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
386 gtk_widget_show(label);
387
388 /* Hbox for the accounts drop-down and label. */
389 hbox = gtk_hbox_new(FALSE, 12);
390 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
391 gtk_widget_show(hbox);
392
393 /* "Set privacy for:" label */
394 label = gtk_label_new(_("Set privacy for:"));
395 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
396 gtk_widget_show(label);
397
398 /* Accounts drop-down */
399 dropdown = gaim_gtk_account_option_menu_new(dialog->account, FALSE,
400 G_CALLBACK(select_account_cb),
401 dialog);
402 gtk_box_pack_start(GTK_BOX(hbox), dropdown, FALSE, FALSE, 0);
403 gtk_widget_show(dropdown);
404
405 /* Add the drop-down list with the allow/block types. */
406 dialog->type_menu = gtk_option_menu_new();
407 gtk_box_pack_start(GTK_BOX(vbox), dialog->type_menu, FALSE, FALSE, 0);
408 gtk_widget_show(dialog->type_menu);
409
410 /* Build the menu for that. */
411 menu = gtk_menu_new();
412
413 for (i = 0; i < menu_entry_count; i++) {
414 gaim_new_item(menu, _(menu_entries[i].text));
415
416 if (menu_entries[i].num == dialog->account->perm_deny)
417 selected = i;
418 }
419
420 gtk_option_menu_set_menu(GTK_OPTION_MENU(dialog->type_menu), menu);
421 gtk_option_menu_set_history(GTK_OPTION_MENU(dialog->type_menu), selected);
422
423 g_signal_connect(G_OBJECT(dialog->type_menu), "changed",
424 G_CALLBACK(type_changed_cb), dialog);
425
426 /* Build the treeview for the allow list. */
427 dialog->allow_widget = build_allow_list(dialog);
428 gtk_box_pack_start(GTK_BOX(vbox), dialog->allow_widget, TRUE, TRUE, 0);
429
430 /* Build the treeview for the block list. */
431 dialog->block_widget = build_block_list(dialog);
432 gtk_box_pack_start(GTK_BOX(vbox), dialog->block_widget, TRUE, TRUE, 0);
433
434 /* Add the button box for Add, Remove, Clear */
435 dialog->button_box = bbox = gtk_hbutton_box_new();
436 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD);
437 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
438
439 /* Add button */
440 button = gtk_button_new_from_stock(GTK_STOCK_ADD);
441 dialog->add_button = button;
442 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
443 gtk_widget_show(button);
444
445 g_signal_connect(G_OBJECT(button), "clicked",
446 G_CALLBACK(add_cb), dialog);
447
448 /* Remove button */
449 button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
450 dialog->remove_button = button;
451 gtk_widget_set_sensitive(button, FALSE);
452 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
453 gtk_widget_show(button);
454
455 g_signal_connect(G_OBJECT(button), "clicked",
456 G_CALLBACK(remove_cb), dialog);
457
458 /* Clear button */
459 button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
460 dialog->clear_button = button;
461 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
462 gtk_widget_show(button);
463
464 g_signal_connect(G_OBJECT(button), "clicked",
465 G_CALLBACK(clear_cb), dialog);
466
467 /* Separator */
468 sep = gtk_hseparator_new();
469 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
470 gtk_widget_show(sep);
471
472 /* Another button box. */
473 bbox = gtk_hbutton_box_new();
474 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
475 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
476 gtk_widget_show(bbox);
477
478 /* Close button */
479 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
480 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
481 gtk_widget_show(button);
482
483 g_signal_connect(G_OBJECT(button), "clicked",
484 G_CALLBACK(close_cb), dialog);
485
486 if (dialog->account->perm_deny == 2) {
487 gtk_widget_show(dialog->allow_widget);
488 gtk_widget_show(dialog->button_box);
489 dialog->in_allow_list = TRUE;
490 }
491 else if (dialog->account->perm_deny == 4) {
492 gtk_widget_show(dialog->block_widget);
493 gtk_widget_show(dialog->button_box);
494 dialog->in_allow_list = FALSE;
495 }
496
497 return dialog;
498 }
499
500 void
501 gaim_gtk_privacy_dialog_show(void)
502 {
503 if (privacy_dialog == NULL)
504 privacy_dialog = privacy_dialog_new();
505
506 gtk_widget_show(privacy_dialog->win);
507 gdk_window_raise(privacy_dialog->win->window);
508 }
509
510 void
511 gaim_gtk_privacy_dialog_hide(void)
512 {
513 if (privacy_dialog == NULL)
514 return;
515
516 gtk_widget_destroy(privacy_dialog->win);
517 privacy_dialog = NULL;
518 }
519
520 static void
521 destroy_request_data(GaimGtkPrivacyRequestData *data)
522 {
523 if (data->name != NULL)
524 g_free(data->name);
525
526 g_free(data);
527 }
528
529 static void
530 confirm_permit_block_cb(GaimGtkPrivacyRequestData *data, int option)
531 {
532 if (data->block)
533 gaim_privacy_deny_add(data->account, data->name);
534 else
535 gaim_privacy_permit_add(data->account, data->name);
536
537 destroy_request_data(data);
538 }
539
540 static void
541 add_permit_block_cb(GaimGtkPrivacyRequestData *data, const char *name)
542 {
543 data->name = g_strdup(name);
544
545 confirm_permit_block_cb(data, 0);
546 }
547
548 void
549 gaim_gtk_request_add_permit(GaimAccount *account, const char *name)
550 {
551 GaimGtkPrivacyRequestData *data;
552
553 g_return_if_fail(account != NULL);
554
555 data = g_new0(GaimGtkPrivacyRequestData, 1);
556 data->account = account;
557 data->name = g_strdup(name);
558 data->block = FALSE;
559
560 if (name == NULL) {
561 gaim_request_input(account, _("Permit User"),
562 _("Type a user you permit to contact you."),
563 _("Please enter the name of the user you wish to be "
564 "able to contact you."),
565 NULL, FALSE, FALSE,
566 _("Permit"), G_CALLBACK(add_permit_block_cb),
567 _("Cancel"), G_CALLBACK(destroy_request_data),
568 data);
569 }
570 else {
571 char *primary = g_strdup_printf(_("Allow %s to contact you?"), name);
572 char *secondary =
573 g_strdup_printf(_("Are you sure you wish to allow "
574 "%s to contact you?"), name);
575
576
577 gaim_request_action(account, _("Permit User"), primary, secondary,
578 0, data, 2,
579 _("Permit"), G_CALLBACK(confirm_permit_block_cb),
580 _("Cancel"), G_CALLBACK(destroy_request_data));
581
582 g_free(primary);
583 g_free(secondary);
584 }
585 }
586
587 void
588 gaim_gtk_request_add_block(GaimAccount *account, const char *name)
589 {
590 GaimGtkPrivacyRequestData *data;
591
592 g_return_if_fail(account != NULL);
593
594 data = g_new0(GaimGtkPrivacyRequestData, 1);
595 data->account = account;
596 data->name = g_strdup(name);
597 data->block = TRUE;
598
599 if (name == NULL) {
600 gaim_request_input(account, _("Block User"),
601 _("Type a user to block."),
602 _("Please enter the name of the user you wish to block."),
603 NULL, FALSE, FALSE,
604 _("Block"), G_CALLBACK(add_permit_block_cb),
605 _("Cancel"), G_CALLBACK(destroy_request_data),
606 data);
607 }
608 else {
609 char *primary = g_strdup_printf(_("Block %s?"), name);
610 char *secondary =
611 g_strdup_printf(_("Are you sure you want to block %s?"), name);
612
613 gaim_request_action(account, _("Block User"), primary, secondary,
614 0, data, 2,
615 _("Block"), G_CALLBACK(confirm_permit_block_cb),
616 _("Cancel"), G_CALLBACK(destroy_request_data));
617
618 g_free(primary);
619 g_free(secondary);
620 }
621 }
622
623 static void
624 gaim_gtk_permit_added_removed(GaimAccount *account, const char *name)
625 {
626 if (privacy_dialog != NULL)
627 rebuild_allow_list(privacy_dialog);
628 }
629
630 static void
631 gaim_gtk_deny_added_removed(GaimAccount *account, const char *name)
632 {
633 if (privacy_dialog != NULL)
634 rebuild_block_list(privacy_dialog);
635 }
636
637 static GaimPrivacyUiOps privacy_ops =
638 {
639 gaim_gtk_permit_added_removed,
640 gaim_gtk_permit_added_removed,
641 gaim_gtk_deny_added_removed,
642 gaim_gtk_deny_added_removed
643 };
644
645 GaimPrivacyUiOps *
646 gaim_gtk_privacy_get_ui_ops(void)
647 {
648 return &privacy_ops;
649 }
650
651 void
652 gaim_gtk_privacy_init(void)
653 {
654 }