Mercurial > pidgin
comparison src/gtksavedstatuses.c @ 10421:ee56a3e54fbd
[gaim-migrate @ 11672]
Swap the order of status_window and status_editor code in gtksavedstatuses.
This way we avoid 2 forward function declarations for static functions.
I also added gaim_gtk_status_editor_show() to gtksavedstatus.h
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 26 Dec 2004 05:34:49 +0000 |
parents | 854c972ea863 |
children | e0cf2f3f9929 |
comparison
equal
deleted
inserted
replaced
10420:854c972ea863 | 10421:ee56a3e54fbd |
---|---|
40 #include "gtkstock.h" | 40 #include "gtkstock.h" |
41 #include "gtkutils.h" | 41 #include "gtkutils.h" |
42 | 42 |
43 enum | 43 enum |
44 { | 44 { |
45 STATUS_WINDOW_COLUMN_TITLE, | |
46 STATUS_WINDOW_COLUMN_TYPE, | |
47 STATUS_WINDOW_COLUMN_MESSAGE, | |
48 STATUS_WINDOW_NUM_COLUMNS | |
49 }; | |
50 | |
51 enum | |
52 { | |
45 STATUS_EDITOR_COLUMN_CUSTOM_STATUS, | 53 STATUS_EDITOR_COLUMN_CUSTOM_STATUS, |
46 STATUS_EDITOR_COLUMN_ICON, | 54 STATUS_EDITOR_COLUMN_ICON, |
47 STATUS_EDITOR_COLUMN_SCREENNAME, | 55 STATUS_EDITOR_COLUMN_SCREENNAME, |
48 STATUS_EDITOR_NUM_COLUMNS | 56 STATUS_EDITOR_NUM_COLUMNS |
49 }; | 57 }; |
50 | |
51 enum | |
52 { | |
53 STATUS_WINDOW_COLUMN_TITLE, | |
54 STATUS_WINDOW_COLUMN_TYPE, | |
55 STATUS_WINDOW_COLUMN_MESSAGE, | |
56 STATUS_WINDOW_NUM_COLUMNS | |
57 }; | |
58 | |
59 typedef struct | |
60 { | |
61 GtkWidget *window; | |
62 GtkListStore *model; | |
63 GtkWidget *treeview; | |
64 GtkWidget *save_button; | |
65 | |
66 gchar *original_title; | |
67 GtkEntry *title; | |
68 GtkOptionMenu *type; | |
69 GtkIMHtml *message; | |
70 } StatusEditor; | |
71 | 58 |
72 typedef struct | 59 typedef struct |
73 { | 60 { |
74 GtkWidget *window; | 61 GtkWidget *window; |
75 GtkListStore *model; | 62 GtkListStore *model; |
76 GtkWidget *treeview; | 63 GtkWidget *treeview; |
77 GtkWidget *modify_button; | 64 GtkWidget *modify_button; |
78 GtkWidget *delete_button; | 65 GtkWidget *delete_button; |
79 } StatusWindow; | 66 } StatusWindow; |
80 | 67 |
68 typedef struct | |
69 { | |
70 GtkWidget *window; | |
71 GtkListStore *model; | |
72 GtkWidget *treeview; | |
73 GtkWidget *save_button; | |
74 | |
75 gchar *original_title; | |
76 GtkEntry *title; | |
77 GtkOptionMenu *type; | |
78 GtkIMHtml *message; | |
79 } StatusEditor; | |
80 | |
81 static StatusWindow *status_window = NULL; | 81 static StatusWindow *status_window = NULL; |
82 | 82 |
83 static void add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status); | 83 |
84 static gboolean status_window_find_savedstatus(GtkTreeIter *iter, const char *title); | 84 /************************************************************************** |
85 * Status window | |
86 **************************************************************************/ | |
87 | |
88 static gboolean | |
89 status_window_find_savedstatus(GtkTreeIter *iter, const char *title) | |
90 { | |
91 GtkTreeModel *model = GTK_TREE_MODEL(status_window->model); | |
92 const char *cur; | |
93 | |
94 if (!gtk_tree_model_get_iter_first(model, iter)) | |
95 return FALSE; | |
96 | |
97 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
98 if (!strcmp(title, cur)) | |
99 return TRUE; | |
100 | |
101 while (gtk_tree_model_iter_next(model, iter)) | |
102 { | |
103 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
104 if (!strcmp(title, cur)) | |
105 return TRUE; | |
106 } | |
107 | |
108 return FALSE; | |
109 } | |
110 | |
111 static gboolean | |
112 status_window_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
113 { | |
114 StatusWindow *dialog = user_data; | |
115 | |
116 dialog->window = NULL; | |
117 gaim_gtk_status_window_hide(); | |
118 | |
119 return FALSE; | |
120 } | |
121 | |
122 static void | |
123 status_window_add_cb(GtkButton *button, gpointer user_data) | |
124 { | |
125 gaim_gtk_status_editor_show(NULL); | |
126 } | |
127 | |
128 static void | |
129 status_window_modify_foreach(GtkTreeModel *model, GtkTreePath *path, | |
130 GtkTreeIter *iter, gpointer user_data) | |
131 { | |
132 const char *title; | |
133 GaimSavedStatus *status; | |
134 | |
135 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
136 | |
137 status = gaim_savedstatus_find(title); | |
138 gaim_gtk_status_editor_show(status); | |
139 } | |
140 | |
141 static void | |
142 status_window_modify_cb(GtkButton *button, gpointer user_data) | |
143 { | |
144 StatusWindow *dialog = user_data; | |
145 GtkTreeSelection *selection; | |
146 | |
147 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
148 | |
149 gtk_tree_selection_selected_foreach(selection, status_window_modify_foreach, user_data); | |
150 } | |
151 | |
152 static void | |
153 status_window_delete_confirm_cb(char *title) | |
154 { | |
155 GtkTreeIter iter; | |
156 | |
157 if (status_window_find_savedstatus(&iter, title)) | |
158 gtk_list_store_remove(status_window->model, &iter); | |
159 | |
160 gaim_savedstatus_delete(title); | |
161 | |
162 g_free(title); | |
163 } | |
164 | |
165 static void | |
166 status_window_delete_foreach(GtkTreeModel *model, GtkTreePath *path, | |
167 GtkTreeIter *iter, gpointer user_data) | |
168 { | |
169 const char *title; | |
170 char *buf; | |
171 | |
172 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
173 | |
174 buf = g_strdup_printf(_("Are you sure you want to delete %s?"), title); | |
175 gaim_request_action(NULL, NULL, buf, NULL, 0, g_strdup(title), 2, | |
176 _("Delete"), status_window_delete_confirm_cb, | |
177 _("Cancel"), g_free); | |
178 g_free(buf); | |
179 } | |
180 | |
181 static void | |
182 status_window_delete_cb(GtkButton *button, gpointer user_data) | |
183 { | |
184 StatusWindow *dialog = user_data; | |
185 GtkTreeSelection *selection; | |
186 | |
187 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
188 | |
189 gtk_tree_selection_selected_foreach(selection, status_window_delete_foreach, user_data); | |
190 } | |
191 | |
192 static void | |
193 status_window_close_cb(GtkButton *button, gpointer user_data) | |
194 { | |
195 gaim_gtk_status_window_hide(); | |
196 } | |
197 | |
198 static void | |
199 status_selected_cb(GtkTreeSelection *sel, gpointer user_data) | |
200 { | |
201 StatusWindow *dialog = user_data; | |
202 gboolean selected = FALSE; | |
203 | |
204 #if GTK_CHECK_VERSION(2,2,0) | |
205 selected = (gtk_tree_selection_count_selected_rows(sel) > 0); | |
206 #else | |
207 gtk_tree_selection_selected_foreach(sel, get_selected_helper, &selected); | |
208 #endif | |
209 | |
210 gtk_widget_set_sensitive(dialog->modify_button, selected); | |
211 gtk_widget_set_sensitive(dialog->delete_button, selected); | |
212 } | |
213 | |
214 static void | |
215 add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status) | |
216 { | |
217 GtkTreeIter iter; | |
218 const char *title; | |
219 const char *type; | |
220 char *message; | |
221 | |
222 title = gaim_savedstatus_get_title(saved_status); | |
223 type = gaim_primitive_get_name_from_type(gaim_savedstatus_get_type(saved_status)); | |
224 message = gaim_markup_strip_html(gaim_savedstatus_get_message(saved_status)); | |
225 if (strlen(message) > 70) | |
226 strcpy(&message[68], "..."); | |
227 | |
228 gtk_list_store_append(model, &iter); | |
229 gtk_list_store_set(model, &iter, | |
230 STATUS_WINDOW_COLUMN_TITLE, title, | |
231 STATUS_WINDOW_COLUMN_TYPE, type, | |
232 STATUS_WINDOW_COLUMN_MESSAGE, message, | |
233 -1); | |
234 free(message); | |
235 } | |
236 | |
237 static void | |
238 populate_saved_status_list(StatusWindow *dialog) | |
239 { | |
240 const GList *saved_statuses; | |
241 | |
242 gtk_list_store_clear(dialog->model); | |
243 | |
244 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL; | |
245 saved_statuses = g_list_next(saved_statuses)) | |
246 { | |
247 add_status_to_saved_status_list(dialog->model, saved_statuses->data); | |
248 } | |
249 } | |
250 | |
251 static GtkWidget * | |
252 create_saved_status_list(StatusWindow *dialog) | |
253 { | |
254 GtkWidget *sw; | |
255 GtkWidget *treeview; | |
256 GtkTreeSelection *sel; | |
257 GtkTreeViewColumn *column; | |
258 GtkCellRenderer *renderer; | |
259 | |
260 /* Create the scrolled window */ | |
261 sw = gtk_scrolled_window_new(0, 0); | |
262 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
263 GTK_POLICY_AUTOMATIC, | |
264 GTK_POLICY_ALWAYS); | |
265 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
266 GTK_SHADOW_IN); | |
267 gtk_widget_show(sw); | |
268 | |
269 /* Create the list model */ | |
270 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, | |
271 G_TYPE_STRING, | |
272 G_TYPE_STRING, | |
273 G_TYPE_STRING); | |
274 | |
275 /* Create the treeview */ | |
276 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
277 dialog->treeview = treeview; | |
278 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
279 | |
280 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
281 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
282 g_signal_connect(G_OBJECT(sel), "changed", | |
283 G_CALLBACK(status_selected_cb), dialog); | |
284 | |
285 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
286 gtk_widget_show(treeview); | |
287 | |
288 | |
289 /* Add columns */ | |
290 column = gtk_tree_view_column_new(); | |
291 gtk_tree_view_column_set_title(column, _("Title")); | |
292 gtk_tree_view_column_set_resizable(column, TRUE); | |
293 gtk_tree_view_column_set_sort_column_id(column, | |
294 STATUS_WINDOW_COLUMN_TITLE); | |
295 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
296 renderer = gtk_cell_renderer_text_new(); | |
297 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
298 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
299 STATUS_WINDOW_COLUMN_TITLE); | |
300 | |
301 column = gtk_tree_view_column_new(); | |
302 gtk_tree_view_column_set_title(column, _("Type")); | |
303 gtk_tree_view_column_set_resizable(column, TRUE); | |
304 gtk_tree_view_column_set_sort_column_id(column, | |
305 STATUS_WINDOW_COLUMN_TYPE); | |
306 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
307 renderer = gtk_cell_renderer_text_new(); | |
308 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
309 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
310 STATUS_WINDOW_COLUMN_TYPE); | |
311 | |
312 column = gtk_tree_view_column_new(); | |
313 gtk_tree_view_column_set_title(column, _("Message")); | |
314 gtk_tree_view_column_set_resizable(column, TRUE); | |
315 gtk_tree_view_column_set_sort_column_id(column, | |
316 STATUS_WINDOW_COLUMN_MESSAGE); | |
317 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
318 renderer = gtk_cell_renderer_text_new(); | |
319 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
320 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
321 STATUS_WINDOW_COLUMN_MESSAGE); | |
322 | |
323 /* Populate list */ | |
324 populate_saved_status_list(dialog); | |
325 | |
326 return sw; | |
327 } | |
328 | |
329 static gboolean | |
330 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog) | |
331 { | |
332 if (GTK_WIDGET_VISIBLE(widget)) { | |
333 gaim_prefs_set_int("/gaim/gtk/status/dialog/width", event->width); | |
334 gaim_prefs_set_int("/gaim/gtk/status/dialog/height", event->height); | |
335 } | |
336 | |
337 return FALSE; | |
338 } | |
339 | |
340 void | |
341 gaim_gtk_status_window_show(void) | |
342 { | |
343 StatusWindow *dialog; | |
344 GtkWidget *bbox; | |
345 GtkWidget *button; | |
346 GtkWidget *list; | |
347 GtkWidget *sep; | |
348 GtkWidget *vbox; | |
349 GtkWidget *win; | |
350 int width, height; | |
351 | |
352 if (status_window != NULL) { | |
353 gtk_window_present(GTK_WINDOW(status_window->window)); | |
354 return; | |
355 } | |
356 | |
357 status_window = dialog = g_new0(StatusWindow, 1); | |
358 | |
359 width = gaim_prefs_get_int("/gaim/gtk/status/dialog/width"); | |
360 height = gaim_prefs_get_int("/gaim/gtk/status/dialog/height"); | |
361 | |
362 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
363 gtk_window_set_default_size(GTK_WINDOW(win), width, height); | |
364 gtk_window_set_role(GTK_WINDOW(win), "statuses"); | |
365 gtk_window_set_title(GTK_WINDOW(win), _("Saved Statuses")); | |
366 gtk_container_set_border_width(GTK_CONTAINER(win), 12); | |
367 | |
368 g_signal_connect(G_OBJECT(win), "delete_event", | |
369 G_CALLBACK(status_window_destroy_cb), dialog); | |
370 g_signal_connect(G_OBJECT(win), "configure_event", | |
371 G_CALLBACK(configure_cb), dialog); | |
372 | |
373 /* Setup the vbox */ | |
374 vbox = gtk_vbox_new(FALSE, 12); | |
375 gtk_container_add(GTK_CONTAINER(win), vbox); | |
376 gtk_widget_show(vbox); | |
377 | |
378 /* List of saved status states */ | |
379 list = create_saved_status_list(dialog); | |
380 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); | |
381 | |
382 /* Separator... */ | |
383 sep = gtk_hseparator_new(); | |
384 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0); | |
385 gtk_widget_show(sep); | |
386 | |
387 /* Button box. */ | |
388 bbox = gtk_hbutton_box_new(); | |
389 gtk_box_set_spacing(GTK_BOX(bbox), 6); | |
390 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
391 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
392 gtk_widget_show(bbox); | |
393 | |
394 /* Add button */ | |
395 button = gtk_button_new_from_stock(GTK_STOCK_ADD); | |
396 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
397 gtk_widget_show(button); | |
398 | |
399 g_signal_connect(G_OBJECT(button), "clicked", | |
400 G_CALLBACK(status_window_add_cb), dialog); | |
401 | |
402 /* Modify button */ | |
403 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY); | |
404 dialog->modify_button = button; | |
405 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
406 gtk_widget_set_sensitive(button, FALSE); | |
407 gtk_widget_show(button); | |
408 | |
409 g_signal_connect(G_OBJECT(button), "clicked", | |
410 G_CALLBACK(status_window_modify_cb), dialog); | |
411 | |
412 /* Delete button */ | |
413 button = gtk_button_new_from_stock(GTK_STOCK_DELETE); | |
414 dialog->delete_button = button; | |
415 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
416 gtk_widget_set_sensitive(button, FALSE); | |
417 gtk_widget_show(button); | |
418 | |
419 g_signal_connect(G_OBJECT(button), "clicked", | |
420 G_CALLBACK(status_window_delete_cb), dialog); | |
421 | |
422 /* Close button */ | |
423 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
424 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
425 gtk_widget_show(button); | |
426 | |
427 g_signal_connect(G_OBJECT(button), "clicked", | |
428 G_CALLBACK(status_window_close_cb), dialog); | |
429 | |
430 gtk_widget_show(win); | |
431 } | |
432 | |
433 void | |
434 gaim_gtk_status_window_hide(void) | |
435 { | |
436 if (status_window == NULL) | |
437 return; | |
438 | |
439 if (status_window->window != NULL) | |
440 gtk_widget_destroy(status_window->window); | |
441 | |
442 g_free(status_window); | |
443 status_window = NULL; | |
444 } | |
445 | |
446 | |
447 /************************************************************************** | |
448 * Status editor | |
449 **************************************************************************/ | |
85 | 450 |
86 static gboolean | 451 static gboolean |
87 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | 452 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) |
88 { | 453 { |
89 StatusWindow *dialog = user_data; | 454 StatusWindow *dialog = user_data; |
460 G_CALLBACK(status_editor_save_cb), dialog); | 825 G_CALLBACK(status_editor_save_cb), dialog); |
461 | 826 |
462 gtk_widget_show(win); | 827 gtk_widget_show(win); |
463 } | 828 } |
464 | 829 |
465 static gboolean | 830 |
466 status_window_find_savedstatus(GtkTreeIter *iter, const char *title) | 831 /************************************************************************** |
467 { | 832 * GTK saved status glue |
468 GtkTreeModel *model = GTK_TREE_MODEL(status_window->model); | 833 **************************************************************************/ |
469 const char *cur; | |
470 | |
471 if (!gtk_tree_model_get_iter_first(model, iter)) | |
472 return FALSE; | |
473 | |
474 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
475 if (!strcmp(title, cur)) | |
476 return TRUE; | |
477 | |
478 while (gtk_tree_model_iter_next(model, iter)) | |
479 { | |
480 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
481 if (!strcmp(title, cur)) | |
482 return TRUE; | |
483 } | |
484 | |
485 return FALSE; | |
486 } | |
487 | |
488 static gboolean | |
489 status_window_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
490 { | |
491 StatusWindow *dialog = user_data; | |
492 | |
493 dialog->window = NULL; | |
494 gaim_gtk_status_window_hide(); | |
495 | |
496 return FALSE; | |
497 } | |
498 | |
499 static void | |
500 status_window_add_cb(GtkButton *button, gpointer user_data) | |
501 { | |
502 gaim_gtk_status_editor_show(NULL); | |
503 } | |
504 | |
505 static void | |
506 status_window_modify_foreach(GtkTreeModel *model, GtkTreePath *path, | |
507 GtkTreeIter *iter, gpointer user_data) | |
508 { | |
509 const char *title; | |
510 GaimSavedStatus *status; | |
511 | |
512 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
513 | |
514 status = gaim_savedstatus_find(title); | |
515 gaim_gtk_status_editor_show(status); | |
516 } | |
517 | |
518 static void | |
519 status_window_modify_cb(GtkButton *button, gpointer user_data) | |
520 { | |
521 StatusWindow *dialog = user_data; | |
522 GtkTreeSelection *selection; | |
523 | |
524 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
525 | |
526 gtk_tree_selection_selected_foreach(selection, status_window_modify_foreach, user_data); | |
527 } | |
528 | |
529 static void | |
530 status_window_delete_confirm_cb(char *title) | |
531 { | |
532 GtkTreeIter iter; | |
533 | |
534 if (status_window_find_savedstatus(&iter, title)) | |
535 gtk_list_store_remove(status_window->model, &iter); | |
536 | |
537 gaim_savedstatus_delete(title); | |
538 | |
539 g_free(title); | |
540 } | |
541 | |
542 static void | |
543 status_window_delete_foreach(GtkTreeModel *model, GtkTreePath *path, | |
544 GtkTreeIter *iter, gpointer user_data) | |
545 { | |
546 const char *title; | |
547 char *buf; | |
548 | |
549 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
550 | |
551 buf = g_strdup_printf(_("Are you sure you want to delete %s?"), title); | |
552 gaim_request_action(NULL, NULL, buf, NULL, 0, g_strdup(title), 2, | |
553 _("Delete"), status_window_delete_confirm_cb, | |
554 _("Cancel"), g_free); | |
555 g_free(buf); | |
556 } | |
557 | |
558 static void | |
559 status_window_delete_cb(GtkButton *button, gpointer user_data) | |
560 { | |
561 StatusWindow *dialog = user_data; | |
562 GtkTreeSelection *selection; | |
563 | |
564 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
565 | |
566 gtk_tree_selection_selected_foreach(selection, status_window_delete_foreach, user_data); | |
567 } | |
568 | |
569 static void | |
570 status_window_close_cb(GtkButton *button, gpointer user_data) | |
571 { | |
572 gaim_gtk_status_window_hide(); | |
573 } | |
574 | |
575 static void | |
576 status_selected_cb(GtkTreeSelection *sel, gpointer user_data) | |
577 { | |
578 StatusWindow *dialog = user_data; | |
579 gboolean selected = FALSE; | |
580 | |
581 #if GTK_CHECK_VERSION(2,2,0) | |
582 selected = (gtk_tree_selection_count_selected_rows(sel) > 0); | |
583 #else | |
584 gtk_tree_selection_selected_foreach(sel, get_selected_helper, &selected); | |
585 #endif | |
586 | |
587 gtk_widget_set_sensitive(dialog->modify_button, selected); | |
588 gtk_widget_set_sensitive(dialog->delete_button, selected); | |
589 } | |
590 | |
591 static void | |
592 add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status) | |
593 { | |
594 GtkTreeIter iter; | |
595 const char *title; | |
596 const char *type; | |
597 char *message; | |
598 | |
599 title = gaim_savedstatus_get_title(saved_status); | |
600 type = gaim_primitive_get_name_from_type(gaim_savedstatus_get_type(saved_status)); | |
601 message = gaim_markup_strip_html(gaim_savedstatus_get_message(saved_status)); | |
602 if (strlen(message) > 70) | |
603 strcpy(&message[68], "..."); | |
604 | |
605 gtk_list_store_append(model, &iter); | |
606 gtk_list_store_set(model, &iter, | |
607 STATUS_WINDOW_COLUMN_TITLE, title, | |
608 STATUS_WINDOW_COLUMN_TYPE, type, | |
609 STATUS_WINDOW_COLUMN_MESSAGE, message, | |
610 -1); | |
611 free(message); | |
612 } | |
613 | |
614 static void | |
615 populate_saved_status_list(StatusWindow *dialog) | |
616 { | |
617 const GList *saved_statuses; | |
618 | |
619 gtk_list_store_clear(dialog->model); | |
620 | |
621 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL; | |
622 saved_statuses = g_list_next(saved_statuses)) | |
623 { | |
624 add_status_to_saved_status_list(dialog->model, saved_statuses->data); | |
625 } | |
626 } | |
627 | |
628 static GtkWidget * | |
629 create_saved_status_list(StatusWindow *dialog) | |
630 { | |
631 GtkWidget *sw; | |
632 GtkWidget *treeview; | |
633 GtkTreeSelection *sel; | |
634 GtkTreeViewColumn *column; | |
635 GtkCellRenderer *renderer; | |
636 | |
637 /* Create the scrolled window */ | |
638 sw = gtk_scrolled_window_new(0, 0); | |
639 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
640 GTK_POLICY_AUTOMATIC, | |
641 GTK_POLICY_ALWAYS); | |
642 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
643 GTK_SHADOW_IN); | |
644 gtk_widget_show(sw); | |
645 | |
646 /* Create the list model */ | |
647 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, | |
648 G_TYPE_STRING, | |
649 G_TYPE_STRING, | |
650 G_TYPE_STRING); | |
651 | |
652 /* Create the treeview */ | |
653 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
654 dialog->treeview = treeview; | |
655 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
656 | |
657 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
658 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
659 g_signal_connect(G_OBJECT(sel), "changed", | |
660 G_CALLBACK(status_selected_cb), dialog); | |
661 | |
662 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
663 gtk_widget_show(treeview); | |
664 | |
665 | |
666 /* Add columns */ | |
667 column = gtk_tree_view_column_new(); | |
668 gtk_tree_view_column_set_title(column, _("Title")); | |
669 gtk_tree_view_column_set_resizable(column, TRUE); | |
670 gtk_tree_view_column_set_sort_column_id(column, | |
671 STATUS_WINDOW_COLUMN_TITLE); | |
672 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
673 renderer = gtk_cell_renderer_text_new(); | |
674 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
675 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
676 STATUS_WINDOW_COLUMN_TITLE); | |
677 | |
678 column = gtk_tree_view_column_new(); | |
679 gtk_tree_view_column_set_title(column, _("Type")); | |
680 gtk_tree_view_column_set_resizable(column, TRUE); | |
681 gtk_tree_view_column_set_sort_column_id(column, | |
682 STATUS_WINDOW_COLUMN_TYPE); | |
683 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
684 renderer = gtk_cell_renderer_text_new(); | |
685 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
686 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
687 STATUS_WINDOW_COLUMN_TYPE); | |
688 | |
689 column = gtk_tree_view_column_new(); | |
690 gtk_tree_view_column_set_title(column, _("Message")); | |
691 gtk_tree_view_column_set_resizable(column, TRUE); | |
692 gtk_tree_view_column_set_sort_column_id(column, | |
693 STATUS_WINDOW_COLUMN_MESSAGE); | |
694 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
695 renderer = gtk_cell_renderer_text_new(); | |
696 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
697 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
698 STATUS_WINDOW_COLUMN_MESSAGE); | |
699 | |
700 /* Populate list */ | |
701 populate_saved_status_list(dialog); | |
702 | |
703 return sw; | |
704 } | |
705 | |
706 static gboolean | |
707 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog) | |
708 { | |
709 if (GTK_WIDGET_VISIBLE(widget)) { | |
710 gaim_prefs_set_int("/gaim/gtk/status/dialog/width", event->width); | |
711 gaim_prefs_set_int("/gaim/gtk/status/dialog/height", event->height); | |
712 } | |
713 | |
714 return FALSE; | |
715 } | |
716 | |
717 void | |
718 gaim_gtk_status_window_show(void) | |
719 { | |
720 StatusWindow *dialog; | |
721 GtkWidget *bbox; | |
722 GtkWidget *button; | |
723 GtkWidget *list; | |
724 GtkWidget *sep; | |
725 GtkWidget *vbox; | |
726 GtkWidget *win; | |
727 int width, height; | |
728 | |
729 if (status_window != NULL) { | |
730 gtk_window_present(GTK_WINDOW(status_window->window)); | |
731 return; | |
732 } | |
733 | |
734 status_window = dialog = g_new0(StatusWindow, 1); | |
735 | |
736 width = gaim_prefs_get_int("/gaim/gtk/status/dialog/width"); | |
737 height = gaim_prefs_get_int("/gaim/gtk/status/dialog/height"); | |
738 | |
739 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
740 gtk_window_set_default_size(GTK_WINDOW(win), width, height); | |
741 gtk_window_set_role(GTK_WINDOW(win), "statuses"); | |
742 gtk_window_set_title(GTK_WINDOW(win), _("Saved Statuses")); | |
743 gtk_container_set_border_width(GTK_CONTAINER(win), 12); | |
744 | |
745 g_signal_connect(G_OBJECT(win), "delete_event", | |
746 G_CALLBACK(status_window_destroy_cb), dialog); | |
747 g_signal_connect(G_OBJECT(win), "configure_event", | |
748 G_CALLBACK(configure_cb), dialog); | |
749 | |
750 /* Setup the vbox */ | |
751 vbox = gtk_vbox_new(FALSE, 12); | |
752 gtk_container_add(GTK_CONTAINER(win), vbox); | |
753 gtk_widget_show(vbox); | |
754 | |
755 /* List of saved status states */ | |
756 list = create_saved_status_list(dialog); | |
757 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); | |
758 | |
759 /* Separator... */ | |
760 sep = gtk_hseparator_new(); | |
761 gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, FALSE, 0); | |
762 gtk_widget_show(sep); | |
763 | |
764 /* Button box. */ | |
765 bbox = gtk_hbutton_box_new(); | |
766 gtk_box_set_spacing(GTK_BOX(bbox), 6); | |
767 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
768 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
769 gtk_widget_show(bbox); | |
770 | |
771 /* Add button */ | |
772 button = gtk_button_new_from_stock(GTK_STOCK_ADD); | |
773 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
774 gtk_widget_show(button); | |
775 | |
776 g_signal_connect(G_OBJECT(button), "clicked", | |
777 G_CALLBACK(status_window_add_cb), dialog); | |
778 | |
779 /* Modify button */ | |
780 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY); | |
781 dialog->modify_button = button; | |
782 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
783 gtk_widget_set_sensitive(button, FALSE); | |
784 gtk_widget_show(button); | |
785 | |
786 g_signal_connect(G_OBJECT(button), "clicked", | |
787 G_CALLBACK(status_window_modify_cb), dialog); | |
788 | |
789 /* Delete button */ | |
790 button = gtk_button_new_from_stock(GTK_STOCK_DELETE); | |
791 dialog->delete_button = button; | |
792 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
793 gtk_widget_set_sensitive(button, FALSE); | |
794 gtk_widget_show(button); | |
795 | |
796 g_signal_connect(G_OBJECT(button), "clicked", | |
797 G_CALLBACK(status_window_delete_cb), dialog); | |
798 | |
799 /* Close button */ | |
800 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
801 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
802 gtk_widget_show(button); | |
803 | |
804 g_signal_connect(G_OBJECT(button), "clicked", | |
805 G_CALLBACK(status_window_close_cb), dialog); | |
806 | |
807 gtk_widget_show(win); | |
808 } | |
809 | |
810 void | |
811 gaim_gtk_status_window_hide(void) | |
812 { | |
813 if (status_window == NULL) | |
814 return; | |
815 | |
816 if (status_window->window != NULL) | |
817 gtk_widget_destroy(status_window->window); | |
818 | |
819 g_free(status_window); | |
820 status_window = NULL; | |
821 } | |
822 | 834 |
823 void * | 835 void * |
824 gaim_gtk_status_get_handle() | 836 gaim_gtk_status_get_handle() |
825 { | 837 { |
826 static int handle; | 838 static int handle; |