comparison src/gtksavedstatuses.c @ 10418:bed2c96bc1fb

[gaim-migrate @ 11669] I split the status-saving code into it's own little API, because it really is separate from the other status.c savedstatuses.c sits on top of the rest of the status API. And you can delete saved statuses now. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Sun, 26 Dec 2004 00:46:26 +0000
parents
children c9b1f3fac753
comparison
equal deleted inserted replaced
10417:823ad21cd95a 10418:bed2c96bc1fb
1 /**
2 * @file gtksavedstatus.c GTK+ Saved Status Editor UI
3 * @ingroup gtkui
4 *
5 * gaim
6 *
7 * Gaim is the legal property of its developers, whose names are too numerous
8 * to list here. Please refer to the COPYRIGHT file distributed with this
9 * source distribution.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #include "account.h"
27 #include "internal.h"
28 #include "request.h"
29 #include "savedstatuses.h"
30 #include "status.h"
31 #include "util.h"
32
33 #include "gtkblist.h"
34 #include "gtkgaim.h"
35 #include "gtkgaim-disclosure.h"
36 #include "gtkimhtml.h"
37 #include "gtkimhtmltoolbar.h"
38 #include "gtksavedstatuses.h"
39 #include "gtkstock.h"
40 #include "gtkutils.h"
41
42 enum
43 {
44 STATUS_EDITOR_COLUMN_CUSTOM_STATUS,
45 STATUS_EDITOR_COLUMN_ICON,
46 STATUS_EDITOR_COLUMN_SCREENNAME,
47 STATUS_EDITOR_NUM_COLUMNS
48 };
49
50 enum
51 {
52 STATUS_WINDOW_COLUMN_TITLE,
53 STATUS_WINDOW_COLUMN_MESSAGE,
54 STATUS_WINDOW_NUM_COLUMNS
55 };
56
57 typedef struct
58 {
59 GtkWidget *window;
60 GtkListStore *model;
61 GtkWidget *treeview;
62 } StatusEditor;
63
64 typedef struct
65 {
66 GtkWidget *window;
67 GtkListStore *model;
68 GtkWidget *treeview;
69 GtkWidget *modify_button;
70 GtkWidget *delete_button;
71 } StatusWindow;
72
73 static StatusWindow *status_window = NULL;
74
75 static gboolean
76 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
77 {
78 StatusWindow *dialog = user_data;
79
80 g_free(dialog);
81
82 return FALSE;
83 }
84
85 static void
86 status_editor_cancel_cb(GtkButton *button, gpointer user_data)
87 {
88 StatusWindow *dialog = user_data;
89
90 gtk_widget_destroy(dialog->window);
91
92 g_free(dialog);
93 }
94
95 static void
96 status_editor_save_cb(GtkButton *button, gpointer user_data)
97 {
98 /* TODO: Save the status */
99 }
100
101 /* TODO: Can this menu be created more automatically? */
102 static GtkWidget *
103 create_status_type_menu()
104 {
105 GtkWidget *dropdown;
106 GtkWidget *menu;
107 GtkWidget *item;
108
109 dropdown = gtk_option_menu_new();
110 menu = gtk_menu_new();
111
112 /* GAIM_STATUS_AVAILABLE */
113 item = gtk_menu_item_new_with_label(_("Available"));
114 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
115 gtk_widget_show(item);
116
117 /* GAIM_STATUS_UNAVAILABLE */
118 item = gtk_menu_item_new_with_label(_("Unavailable"));
119 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
120 gtk_widget_show(item);
121
122 /* GAIM_STATUS_HIDDEN */
123 item = gtk_menu_item_new_with_label(_("Hidden"));
124 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
125 gtk_widget_show(item);
126
127 /* GAIM_STATUS_AWAY */
128 item = gtk_menu_item_new_with_label(_("Away"));
129 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
130 gtk_widget_show(item);
131
132 /* GAIM_STATUS_EXTENDED_AWAY */
133 item = gtk_menu_item_new_with_label(_("Extended Away"));
134 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
135 gtk_widget_show(item);
136
137 gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
138 gtk_widget_show(menu);
139
140 return dropdown;
141 }
142
143 static void
144 status_editor_custom_status_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data)
145 {
146 /* StatusEditor *dialog = (StatusEditor *)data; */
147
148 /* TODO: Need to allow user to set a custom status for the highlighted account, somehow */
149 }
150
151 static void
152 status_editor_add_columns(StatusEditor *dialog)
153 {
154 GtkCellRenderer *renderer;
155 GtkTreeViewColumn *column;
156
157 /* Custom status column */
158 renderer = gtk_cell_renderer_toggle_new();
159 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog->treeview),
160 -1, _("Custom status"),
161 renderer,
162 "active", STATUS_EDITOR_COLUMN_CUSTOM_STATUS,
163 NULL);
164 column = gtk_tree_view_get_column(GTK_TREE_VIEW(dialog->treeview), 1);
165 g_signal_connect(G_OBJECT(renderer), "toggled",
166 G_CALLBACK(status_editor_custom_status_cb), dialog);
167
168 /* Screen Name column */
169 column = gtk_tree_view_column_new();
170 gtk_tree_view_column_set_resizable(column, TRUE);
171 gtk_tree_view_column_set_title(column, _("Screen Name"));
172 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1);
173 gtk_tree_view_column_set_resizable(column, TRUE);
174
175 /* Icon */
176 renderer = gtk_cell_renderer_pixbuf_new();
177 gtk_tree_view_column_pack_start(column, renderer, FALSE);
178 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf",
179 STATUS_EDITOR_COLUMN_ICON);
180
181 /* Screen Name */
182 renderer = gtk_cell_renderer_text_new();
183 gtk_tree_view_column_pack_start(column, renderer, TRUE);
184 gtk_tree_view_column_add_attribute(column, renderer, "text",
185 STATUS_EDITOR_COLUMN_SCREENNAME);
186 }
187
188 static void
189 status_editor_set_account(GtkListStore *store, GaimAccount *account, GtkTreeIter *iter)
190 {
191 GdkPixbuf *pixbuf;
192 GdkPixbuf *scale;
193
194 scale = NULL;
195
196 pixbuf = create_prpl_icon(account);
197
198 if (pixbuf != NULL)
199 {
200 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR);
201
202 if (!gaim_account_is_connected(account))
203 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE);
204 }
205
206 gtk_list_store_set(store, iter,
207 STATUS_EDITOR_COLUMN_ICON, scale,
208 STATUS_EDITOR_COLUMN_SCREENNAME, gaim_account_get_username(account),
209 -1);
210
211 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf));
212 if (scale != NULL) g_object_unref(G_OBJECT(scale));
213 }
214
215 static void
216 status_editor_add_account(StatusEditor *dialog, GaimAccount *account)
217 {
218 GtkTreeIter iter;
219
220 gtk_list_store_append(dialog->model, &iter);
221
222 status_editor_set_account(dialog->model, account, &iter);
223 }
224
225 static void
226 status_editor_populate_list(StatusEditor *dialog)
227 {
228 GList *l;
229
230 gtk_list_store_clear(dialog->model);
231
232 for (l = gaim_accounts_get_all(); l != NULL; l = l->next)
233 status_editor_add_account(dialog, (GaimAccount *)l->data);
234 }
235
236 void
237 gaim_gtk_status_editor_show(void)
238 {
239 StatusEditor *dialog;
240 GtkSizeGroup *sg;
241 GtkWidget *bbox;
242 GtkWidget *button;
243 GtkWidget *dbox;
244 GtkWidget *disclosure;
245 GtkWidget *dropdown;
246 GtkWidget *entry;
247 GtkWidget *frame;
248 GtkWidget *hbox;
249 GtkWidget *label;
250 GtkWidget *sep;
251 GtkWidget *sw;
252 GtkWidget *text;
253 GtkWidget *toolbar;
254 GtkWidget *vbox;
255 GtkWidget *win;
256
257 dialog = g_new0(StatusEditor, 1);
258
259 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
260 gtk_window_set_role(GTK_WINDOW(win), "status");
261 gtk_window_set_title(GTK_WINDOW(win), _("Status"));
262 gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
263 gtk_container_set_border_width(GTK_CONTAINER(win), 12);
264
265 g_signal_connect(G_OBJECT(win), "delete_event",
266 G_CALLBACK(status_editor_destroy_cb), dialog);
267
268 /* Setup the vbox */
269 vbox = gtk_vbox_new(FALSE, 12);
270 gtk_container_add(GTK_CONTAINER(win), vbox);
271 gtk_widget_show(vbox);
272
273 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
274
275 /* Title */
276 hbox = gtk_hbox_new(FALSE, 6);
277 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
278 gtk_widget_show(hbox);
279
280 label = gtk_label_new_with_mnemonic(_("_Title:"));
281 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
282 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
283 gtk_widget_show(label);
284 gtk_size_group_add_widget(sg, label);
285
286 entry = gtk_entry_new();
287 gtk_entry_set_text(GTK_ENTRY(entry), _("Out of the office"));
288 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
289 gtk_widget_show(entry);
290
291 /* Status type */
292 hbox = gtk_hbox_new(FALSE, 6);
293 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
294 gtk_widget_show(hbox);
295
296 label = gtk_label_new_with_mnemonic(_("_Status:"));
297 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
298 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
299 gtk_widget_show(label);
300 gtk_size_group_add_widget(sg, label);
301
302 dropdown = create_status_type_menu();
303 gtk_box_pack_start(GTK_BOX(hbox), dropdown, TRUE, TRUE, 0);
304 gtk_widget_show(dropdown);
305
306 /* Status message */
307 hbox = gtk_hbox_new(FALSE, 6);
308 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
309 gtk_widget_show(hbox);
310
311 label = gtk_label_new_with_mnemonic(_("_Message:"));
312 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
313 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
314 gtk_widget_show(label);
315 gtk_size_group_add_widget(sg, label);
316
317 frame = gaim_gtk_create_imhtml(TRUE, &text, &toolbar);
318 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
319 gtk_widget_show(frame);
320
321 /* Custom status message disclosure */
322 disclosure = gaim_disclosure_new(_("Use a different status for some accounts"),
323 _("Use a different status for some accounts"));
324 gtk_box_pack_start(GTK_BOX(vbox), disclosure, FALSE, FALSE, 0);
325 gtk_widget_show(disclosure);
326
327 /* Setup the box that the disclosure will cover */
328 dbox = gtk_vbox_new(FALSE, 18);
329 gtk_box_pack_start(GTK_BOX(vbox), dbox, FALSE, FALSE, 0);
330 gaim_disclosure_set_container(GAIM_DISCLOSURE(disclosure), dbox);
331
332 /* Custom status message treeview */
333 sw = gtk_scrolled_window_new(NULL, NULL);
334 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
335 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
336 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
337 GTK_SHADOW_IN);
338 gtk_box_pack_start(GTK_BOX(dbox), sw, TRUE, TRUE, 0);
339 gtk_widget_show(sw);
340
341 /* Create the list model */
342 dialog->model = gtk_list_store_new(STATUS_EDITOR_NUM_COLUMNS,
343 G_TYPE_BOOLEAN,
344 GDK_TYPE_PIXBUF, G_TYPE_STRING);
345
346 /* Create the treeview */
347 dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
348 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE);
349 gtk_widget_set_size_request(dialog->treeview, 400, 250);
350 gtk_container_add(GTK_CONTAINER(sw), dialog->treeview);
351 gtk_widget_show(dialog->treeview);
352
353 /* Add columns */
354 status_editor_add_columns(dialog);
355
356 /* Populate list */
357 status_editor_populate_list(dialog);
358
359 /* Separator */
360 sep = gtk_hseparator_new();
361 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
362 gtk_widget_show(sep);
363
364 /* Button box */
365 bbox = gtk_hbutton_box_new();
366 gtk_box_set_spacing(GTK_BOX(bbox), 6);
367 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
368 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
369 gtk_widget_show(bbox);
370
371 /* Cancel button */
372 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
373 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
374 gtk_widget_show(button);
375
376 g_signal_connect(G_OBJECT(button), "clicked",
377 G_CALLBACK(status_editor_cancel_cb), dialog);
378
379 /* Save button */
380 /* TODO: This button needs to be made sensitive when the title box contains text */
381 button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
382 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
383 gtk_widget_set_sensitive(button, FALSE);
384 gtk_widget_show(button);
385
386 g_signal_connect(G_OBJECT(button), "clicked",
387 G_CALLBACK(status_editor_save_cb), dialog);
388
389 gtk_widget_show(win);
390 }
391
392 static gboolean
393 status_window_find_savedstatus(GtkTreeIter *iter, const char *title)
394 {
395 GtkTreeModel *model = GTK_TREE_MODEL(status_window->model);
396 const char *cur;
397
398 if (!gtk_tree_model_get_iter_first(model, iter))
399 return FALSE;
400
401 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1);
402 if (!strcmp(title, cur))
403 return TRUE;
404
405 while (gtk_tree_model_iter_next(model, iter))
406 {
407 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1);
408 if (!strcmp(title, cur))
409 return TRUE;
410 }
411
412 return FALSE;
413 }
414
415 static gboolean
416 status_window_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data)
417 {
418 StatusWindow *dialog = user_data;
419
420 dialog->window = NULL;
421 gaim_gtk_status_window_hide();
422
423 return FALSE;
424 }
425
426 static void
427 status_window_add_cb(GtkButton *button, gpointer user_data)
428 {
429 gaim_gtk_status_editor_show();
430 }
431
432 static void
433 status_window_modify_foreach(GtkTreeModel *model, GtkTreePath *path,
434 GtkTreeIter *iter, gpointer user_data)
435 {
436 const char *title;
437 GaimStatusSaved *status;
438
439 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1);
440
441 status = gaim_savedstatuses_find(title);
442 /* TODO: Need to show a status editor pre-populated with this status */
443 }
444
445 static void
446 status_window_modify_cb(GtkButton *button, gpointer user_data)
447 {
448 StatusWindow *dialog = user_data;
449 GtkTreeSelection *selection;
450
451 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
452
453 gtk_tree_selection_selected_foreach(selection, status_window_modify_foreach, user_data);
454 }
455
456 static void
457 status_window_delete_confirm_cb(char *title)
458 {
459 GtkTreeIter iter;
460
461 if (status_window_find_savedstatus(&iter, title))
462 gtk_list_store_remove(status_window->model, &iter);
463
464 gaim_savedstatuses_delete(title);
465
466 g_free(title);
467 }
468
469 static void
470 status_window_delete_foreach(GtkTreeModel *model, GtkTreePath *path,
471 GtkTreeIter *iter, gpointer user_data)
472 {
473 const char *title;
474 char *buf;
475
476 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1);
477
478 buf = g_strdup_printf(_("Are you sure you want to delete %s?"), title);
479 gaim_request_action(NULL, NULL, buf, NULL, 0, g_strdup(title), 2,
480 _("Delete"), status_window_delete_confirm_cb,
481 _("Cancel"), g_free);
482 g_free(buf);
483 }
484
485 static void
486 status_window_delete_cb(GtkButton *button, gpointer user_data)
487 {
488 StatusWindow *dialog = user_data;
489 GtkTreeSelection *selection;
490
491 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview));
492
493 gtk_tree_selection_selected_foreach(selection, status_window_delete_foreach, user_data);
494 }
495
496 static void
497 status_window_close_cb(GtkButton *button, gpointer user_data)
498 {
499 gaim_gtk_status_window_hide();
500 }
501
502 static void
503 status_selected_cb(GtkTreeSelection *sel, gpointer user_data)
504 {
505 StatusWindow *dialog = user_data;
506 gboolean selected = FALSE;
507
508 #if GTK_CHECK_VERSION(2,2,0)
509 selected = (gtk_tree_selection_count_selected_rows(sel) > 0);
510 #else
511 gtk_tree_selection_selected_foreach(sel, get_selected_helper, &selected);
512 #endif
513
514 gtk_widget_set_sensitive(dialog->modify_button, selected);
515 gtk_widget_set_sensitive(dialog->delete_button, selected);
516 }
517
518 static void
519 populate_saved_status_list(StatusWindow *dialog)
520 {
521 GtkTreeIter iter;
522 const GList *saved_statuses;
523 GaimStatusSaved *saved_status;
524 char *message;
525
526 gtk_list_store_clear(dialog->model);
527
528 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL;
529 saved_statuses = g_list_next(saved_statuses))
530 {
531 saved_status = (GaimStatusSaved *)saved_statuses->data;
532 message = gaim_markup_strip_html(gaim_savedstatuses_get_message(saved_status));
533 if (strlen(message) > 70)
534 strcpy(&message[68], "...");
535
536 gtk_list_store_append(dialog->model, &iter);
537 gtk_list_store_set(dialog->model, &iter,
538 STATUS_WINDOW_COLUMN_TITLE, gaim_savedstatuses_get_title(saved_status),
539 STATUS_WINDOW_COLUMN_MESSAGE, message,
540 -1);
541 free(message);
542 }
543 }
544
545 static GtkWidget *
546 create_saved_status_list(StatusWindow *dialog)
547 {
548 GtkWidget *sw;
549 GtkWidget *treeview;
550 GtkTreeSelection *sel;
551 GtkTreeViewColumn *column;
552 GtkCellRenderer *renderer;
553
554 /* Create the scrolled window */
555 sw = gtk_scrolled_window_new(0, 0);
556 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
557 GTK_POLICY_AUTOMATIC,
558 GTK_POLICY_ALWAYS);
559 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
560 GTK_SHADOW_IN);
561 gtk_widget_show(sw);
562
563 /* Create the list model */
564 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS,
565 G_TYPE_STRING,
566 G_TYPE_STRING);
567
568 /* Create the treeview */
569 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model));
570 dialog->treeview = treeview;
571 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
572
573 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
574 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
575 g_signal_connect(G_OBJECT(sel), "changed",
576 G_CALLBACK(status_selected_cb), dialog);
577
578 gtk_container_add(GTK_CONTAINER(sw), treeview);
579 gtk_widget_show(treeview);
580
581
582 /* Add columns */
583 column = gtk_tree_view_column_new();
584 gtk_tree_view_column_set_title(column, _("Title"));
585 gtk_tree_view_column_set_resizable(column, TRUE);
586 gtk_tree_view_column_set_sort_column_id(column,
587 STATUS_WINDOW_COLUMN_TITLE);
588 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
589 renderer = gtk_cell_renderer_text_new();
590 gtk_tree_view_column_pack_start(column, renderer, TRUE);
591 gtk_tree_view_column_add_attribute(column, renderer, "text",
592 STATUS_WINDOW_COLUMN_TITLE);
593
594 column = gtk_tree_view_column_new();
595 gtk_tree_view_column_set_title(column, _("Message"));
596 gtk_tree_view_column_set_resizable(column, TRUE);
597 gtk_tree_view_column_set_sort_column_id(column,
598 STATUS_WINDOW_COLUMN_MESSAGE);
599 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
600 renderer = gtk_cell_renderer_text_new();
601 gtk_tree_view_column_pack_start(column, renderer, TRUE);
602 gtk_tree_view_column_add_attribute(column, renderer, "text",
603 STATUS_WINDOW_COLUMN_MESSAGE);
604
605 /* Populate list */
606 populate_saved_status_list(dialog);
607
608 return sw;
609 }
610
611 static gboolean
612 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog)
613 {
614 if (GTK_WIDGET_VISIBLE(widget)) {
615 gaim_prefs_set_int("/gaim/gtk/status/dialog/width", event->width);
616 gaim_prefs_set_int("/gaim/gtk/status/dialog/height", event->height);
617 }
618
619 return FALSE;
620 }
621
622 void
623 gaim_gtk_status_window_show(void)
624 {
625 StatusWindow *dialog;
626 GtkWidget *bbox;
627 GtkWidget *button;
628 GtkWidget *list;
629 GtkWidget *sep;
630 GtkWidget *vbox;
631 GtkWidget *win;
632 int width, height;
633
634 if (status_window != NULL) {
635 gtk_window_present(GTK_WINDOW(status_window->window));
636 return;
637 }
638
639 status_window = dialog = g_new0(StatusWindow, 1);
640
641 width = gaim_prefs_get_int("/gaim/gtk/status/dialog/width");
642 height = gaim_prefs_get_int("/gaim/gtk/status/dialog/height");
643
644 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
645 gtk_window_set_default_size(GTK_WINDOW(win), width, height);
646 gtk_window_set_role(GTK_WINDOW(win), "statuses");
647 gtk_window_set_title(GTK_WINDOW(win), _("Saved Statuses"));
648 gtk_container_set_border_width(GTK_CONTAINER(win), 12);
649
650 g_signal_connect(G_OBJECT(win), "delete_event",
651 G_CALLBACK(status_window_destroy_cb), dialog);
652 g_signal_connect(G_OBJECT(win), "configure_event",
653 G_CALLBACK(configure_cb), dialog);
654
655 /* Setup the vbox */
656 vbox = gtk_vbox_new(FALSE, 12);
657 gtk_container_add(GTK_CONTAINER(win), vbox);
658 gtk_widget_show(vbox);
659
660 /* List of saved status states */
661 list = create_saved_status_list(dialog);
662 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0);
663
664 /* Separator... */
665 sep = gtk_hseparator_new();
666 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0);
667 gtk_widget_show(sep);
668
669 /* Button box. */
670 bbox = gtk_hbutton_box_new();
671 gtk_box_set_spacing(GTK_BOX(bbox), 6);
672 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
673 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
674 gtk_widget_show(bbox);
675
676 /* Add button */
677 button = gtk_button_new_from_stock(GTK_STOCK_ADD);
678 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
679 gtk_widget_show(button);
680
681 g_signal_connect(G_OBJECT(button), "clicked",
682 G_CALLBACK(status_window_add_cb), dialog);
683
684 /* Modify button */
685 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY);
686 dialog->modify_button = button;
687 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
688 gtk_widget_set_sensitive(button, FALSE);
689 gtk_widget_show(button);
690
691 g_signal_connect(G_OBJECT(button), "clicked",
692 G_CALLBACK(status_window_modify_cb), dialog);
693
694 /* Delete button */
695 button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
696 dialog->delete_button = button;
697 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
698 gtk_widget_set_sensitive(button, FALSE);
699 gtk_widget_show(button);
700
701 g_signal_connect(G_OBJECT(button), "clicked",
702 G_CALLBACK(status_window_delete_cb), dialog);
703
704 /* Close button */
705 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
706 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
707 gtk_widget_show(button);
708
709 g_signal_connect(G_OBJECT(button), "clicked",
710 G_CALLBACK(status_window_close_cb), dialog);
711
712 gtk_widget_show(win);
713 }
714
715 void
716 gaim_gtk_status_window_hide(void)
717 {
718 if (status_window == NULL)
719 return;
720
721 if (status_window->window != NULL)
722 gtk_widget_destroy(status_window->window);
723
724 g_free(status_window);
725 status_window = NULL;
726 }
727
728 void *
729 gaim_gtk_status_get_handle()
730 {
731 static int handle;
732
733 return &handle;
734 }
735
736 void
737 gaim_gtk_status_init(void)
738 {
739 gaim_prefs_add_none("/gaim/gtk/status");
740 gaim_prefs_add_none("/gaim/gtk/status/dialog");
741 gaim_prefs_add_int("/gaim/gtk/status/dialog/width", 550);
742 gaim_prefs_add_int("/gaim/gtk/status/dialog/height", 250);
743 }
744
745 void
746 gaim_gtk_status_uninit(void)
747 {
748 gaim_gtk_status_window_hide();
749 }