Mercurial > pidgin
annotate src/gtksavedstatuses.c @ 12360:3153661f4d5c
[gaim-migrate @ 14664]
Faceprint is concerned about 2 things:
1)some of the random colors are very close together.
as best we can tell, there are two ways to fix this
1a) for each proposed color, iterate the entire list of selected
colors, looking to ensure that it is not too close to any of them.
this is an O(n^2) operation, with n >= 220 (the current number of
colors we look for)
1b) iterate the entire set of possible colors, skipping ahead by some
guess (rather than iterating by 1). this is an O(n^3) operation,
where n is 65535/(whatever we skip ahead by). This is not only a
more expensive operation, but because of the nature of the color
list, it is not _necessarily_ going to yield more predictable
results, skipping ahead 5 (or any other number) does not necessarily
guarantee that you've skipped 5 very similar colors.
2) as you can see, either solution to #1 is potentially a resource hog.
#1a is a random delay, #1b is inherently expensive. How often #1a will
exceed the bound #1b, if ever, is unknown.
rather than doing either of these, we settled on a middle course: a .h
file has been created containing a set of colors. currently the set we
were previously hard coded to. Gaim will search that list for usable
colors and start randomly looking only if that list does not contain
sufficient usable colors. ideally this list would be generated to have
colors that are known to be a "safe" distance appart, that is colors that
you can tell appart. and Ideally it would have a (small) multiple of the
number of colors we are searching for. This should ensure that IF we go
to randomly searching, we need do so only for a few colors.
Right now I have no good way to generate a "safe" list of colors though.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Mon, 05 Dec 2005 21:46:47 +0000 |
parents | a83644e2a2a8 |
children | 07d6cc1b5a98 |
rev | line source |
---|---|
10418 | 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" | |
10420 | 28 #include "notify.h" |
10418 | 29 #include "request.h" |
30 #include "savedstatuses.h" | |
31 #include "status.h" | |
32 #include "util.h" | |
33 | |
34 #include "gtkblist.h" | |
11735 | 35 #include "gtkexpander.h" |
10418 | 36 #include "gtkgaim.h" |
37 #include "gtkimhtml.h" | |
38 #include "gtkimhtmltoolbar.h" | |
39 #include "gtksavedstatuses.h" | |
40 #include "gtkstock.h" | |
41 #include "gtkutils.h" | |
42 | |
12080 | 43 /* |
44 * TODO: Should attach to the account-deleted and account-added signals | |
45 * and update the GtkListStores in any StatusEditor windows that | |
46 * may be open. | |
47 */ | |
48 | |
49 /** | |
50 * These are used for the GtkTreeView when you're scrolling through | |
51 * all your saved statuses. | |
52 */ | |
10418 | 53 enum |
54 { | |
10421 | 55 STATUS_WINDOW_COLUMN_TITLE, |
56 STATUS_WINDOW_COLUMN_TYPE, | |
57 STATUS_WINDOW_COLUMN_MESSAGE, | |
58 STATUS_WINDOW_NUM_COLUMNS | |
59 }; | |
60 | |
12080 | 61 /** |
62 * These is used for the GtkTreeView containing the list of accounts | |
63 * at the bottom of the window when you're editing a particular | |
64 * saved status. | |
65 */ | |
10421 | 66 enum |
67 { | |
12080 | 68 /** A hidden column containing a pointer to the GaimAccount */ |
69 STATUS_EDITOR_COLUMN_ACCOUNT, | |
70 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, | |
10418 | 71 STATUS_EDITOR_COLUMN_ICON, |
72 STATUS_EDITOR_COLUMN_SCREENNAME, | |
12080 | 73 /** A hidden column containing the ID of this GaimStatusType. */ |
74 STATUS_EDITOR_COLUMN_STATUS_ID, | |
75 STATUS_EDITOR_COLUMN_STATUS_NAME, | |
76 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, | |
10418 | 77 STATUS_EDITOR_NUM_COLUMNS |
78 }; | |
79 | |
12080 | 80 /** |
81 * These are used in the GtkComboBox to select the specific | |
82 * GaimStatusType when setting a substatus for a particular saved | |
83 * status. | |
84 */ | |
85 enum | |
86 { | |
87 /** A hidden column containing a pointer to the GaimAccount. */ | |
88 SUBSTATUS_COLUMN_ACCOUNT, | |
89 SUBSTATUS_COLUMN_ICON, | |
90 /** A hidden column containing the ID of this GaimStatusType. */ | |
91 SUBSTATUS_COLUMN_STATUS_ID, | |
92 SUBSTATUS_COLUMN_STATUS_NAME, | |
93 SUBSTATUS_NUM_COLUMNS | |
94 }; | |
95 | |
10421 | 96 typedef struct |
10418 | 97 { |
10421 | 98 GtkWidget *window; |
99 GtkListStore *model; | |
100 GtkWidget *treeview; | |
11811 | 101 GtkWidget *use_button; |
10421 | 102 GtkWidget *modify_button; |
103 GtkWidget *delete_button; | |
104 } StatusWindow; | |
10418 | 105 |
106 typedef struct | |
107 { | |
108 GtkWidget *window; | |
109 GtkListStore *model; | |
110 GtkWidget *treeview; | |
12329 | 111 GtkButton *saveanduse_button; |
112 GtkButton *save_button; | |
10420 | 113 |
114 gchar *original_title; | |
115 GtkEntry *title; | |
116 GtkOptionMenu *type; | |
117 GtkIMHtml *message; | |
10418 | 118 } StatusEditor; |
119 | |
12080 | 120 typedef struct |
121 { | |
122 StatusEditor *status_editor; | |
123 GaimAccount *account; | |
124 | |
125 GtkWidget *window; | |
126 GtkListStore *model; | |
127 GtkComboBox *box; | |
128 GtkIMHtml *message; | |
129 GtkIMHtmlToolbar *toolbar; | |
130 } SubStatusEditor; | |
131 | |
10418 | 132 static StatusWindow *status_window = NULL; |
133 | |
10421 | 134 |
135 /************************************************************************** | |
136 * Status window | |
137 **************************************************************************/ | |
138 | |
139 static gboolean | |
140 status_window_find_savedstatus(GtkTreeIter *iter, const char *title) | |
141 { | |
142 GtkTreeModel *model = GTK_TREE_MODEL(status_window->model); | |
10439 | 143 char *cur; |
10421 | 144 |
145 if (!gtk_tree_model_get_iter_first(model, iter)) | |
146 return FALSE; | |
147 | |
148 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
149 if (!strcmp(title, cur)) | |
10439 | 150 { |
151 g_free(cur); | |
10421 | 152 return TRUE; |
10439 | 153 } |
154 g_free(cur); | |
10421 | 155 |
156 while (gtk_tree_model_iter_next(model, iter)) | |
157 { | |
158 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
159 if (!strcmp(title, cur)) | |
10439 | 160 { |
161 g_free(cur); | |
10421 | 162 return TRUE; |
10439 | 163 } |
164 g_free(cur); | |
10421 | 165 } |
166 | |
167 return FALSE; | |
168 } | |
169 | |
170 static gboolean | |
171 status_window_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
172 { | |
173 StatusWindow *dialog = user_data; | |
174 | |
175 dialog->window = NULL; | |
176 gaim_gtk_status_window_hide(); | |
177 | |
178 return FALSE; | |
179 } | |
180 | |
11888 | 181 #if !GTK_CHECK_VERSION(2,2,0) |
182 static void | |
183 count_selected_helper(GtkTreeModel *model, GtkTreePath *path, | |
184 GtkTreeIter *iter, gpointer user_data) | |
185 { | |
186 (*(gint *)user_data)++; | |
187 } | |
188 | |
189 static void | |
190 list_selected_helper(GtkTreeModel *model, GtkTreePath *path, | |
191 GtkTreeIter *iter, gpointer user_data) | |
192 { | |
11889 | 193 GList **list = (GList **)user_data; |
194 *list = g_list_append(*list, gtk_tree_path_copy(path)); | |
11888 | 195 } |
196 #endif | |
197 | |
10421 | 198 static void |
11811 | 199 status_window_use_cb(GtkButton *button, StatusWindow *dialog) |
200 { | |
201 GtkTreeSelection *selection; | |
202 GtkTreeIter iter; | |
11889 | 203 GList *list = NULL; |
11888 | 204 int num_selected = 0; |
11811 | 205 |
206 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
207 | |
11888 | 208 #if GTK_CHECK_VERSION(2,2,0) |
209 num_selected = gtk_tree_selection_count_selected_rows(selection); | |
210 #else | |
211 gtk_tree_selection_selected_foreach(selection, count_selected_helper, &num_selected); | |
212 #endif | |
213 if (num_selected != 1) | |
11811 | 214 /* |
215 * This shouldn't happen because the "Use" button should have | |
216 * been grayed out. Oh well. | |
217 */ | |
218 return; | |
219 | |
11888 | 220 #if GTK_CHECK_VERSION(2,2,0) |
11811 | 221 list = gtk_tree_selection_get_selected_rows(selection, NULL); |
11888 | 222 #else |
223 gtk_tree_selection_selected_foreach(selection, list_selected_helper, &list); | |
224 #endif | |
11811 | 225 |
226 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), | |
227 &iter, list->data)) | |
228 { | |
12080 | 229 gchar *title; |
230 GaimSavedStatus *saved_status; | |
11811 | 231 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, |
12080 | 232 STATUS_WINDOW_COLUMN_TITLE, &title, |
11811 | 233 -1); |
12080 | 234 saved_status = gaim_savedstatus_find(title); |
235 g_free(title); | |
11811 | 236 gaim_savedstatus_activate(saved_status); |
237 } | |
238 | |
239 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL); | |
240 g_list_free(list); | |
241 } | |
242 | |
243 static void | |
10421 | 244 status_window_add_cb(GtkButton *button, gpointer user_data) |
245 { | |
246 gaim_gtk_status_editor_show(NULL); | |
247 } | |
248 | |
249 static void | |
250 status_window_modify_foreach(GtkTreeModel *model, GtkTreePath *path, | |
251 GtkTreeIter *iter, gpointer user_data) | |
252 { | |
12080 | 253 gchar *title; |
254 GaimSavedStatus *saved_status; | |
10421 | 255 |
12080 | 256 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); |
257 saved_status = gaim_savedstatus_find(title); | |
258 g_free(title); | |
259 gaim_gtk_status_editor_show(saved_status); | |
10421 | 260 } |
261 | |
262 static void | |
263 status_window_modify_cb(GtkButton *button, gpointer user_data) | |
264 { | |
265 StatusWindow *dialog = user_data; | |
266 GtkTreeSelection *selection; | |
267 | |
268 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
269 | |
270 gtk_tree_selection_selected_foreach(selection, status_window_modify_foreach, user_data); | |
271 } | |
272 | |
273 static void | |
274 status_window_delete_confirm_cb(char *title) | |
275 { | |
276 GtkTreeIter iter; | |
277 | |
278 if (status_window_find_savedstatus(&iter, title)) | |
279 gtk_list_store_remove(status_window->model, &iter); | |
280 | |
281 gaim_savedstatus_delete(title); | |
282 | |
283 g_free(title); | |
284 } | |
285 | |
286 static void | |
287 status_window_delete_foreach(GtkTreeModel *model, GtkTreePath *path, | |
288 GtkTreeIter *iter, gpointer user_data) | |
289 { | |
10439 | 290 char *title; |
12237 | 291 char *buf; |
10421 | 292 |
293 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
294 | |
12237 | 295 buf = g_strdup_printf(_("Are you sure you want to delete %s?"), title); |
10439 | 296 gaim_request_action(NULL, NULL, buf, NULL, 0, title, 2, |
10421 | 297 _("Delete"), status_window_delete_confirm_cb, |
298 _("Cancel"), g_free); | |
299 g_free(buf); | |
300 } | |
301 | |
302 static void | |
303 status_window_delete_cb(GtkButton *button, gpointer user_data) | |
304 { | |
305 StatusWindow *dialog = user_data; | |
306 GtkTreeSelection *selection; | |
307 | |
308 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
309 | |
310 gtk_tree_selection_selected_foreach(selection, status_window_delete_foreach, user_data); | |
311 } | |
312 | |
313 static void | |
314 status_window_close_cb(GtkButton *button, gpointer user_data) | |
315 { | |
316 gaim_gtk_status_window_hide(); | |
317 } | |
318 | |
319 static void | |
320 status_selected_cb(GtkTreeSelection *sel, gpointer user_data) | |
321 { | |
322 StatusWindow *dialog = user_data; | |
11888 | 323 int num_selected = 0; |
10421 | 324 |
325 #if GTK_CHECK_VERSION(2,2,0) | |
11811 | 326 num_selected = gtk_tree_selection_count_selected_rows(sel); |
10421 | 327 #else |
11888 | 328 gtk_tree_selection_selected_foreach(sel, count_selected_helper, &num_selected); |
10421 | 329 #endif |
330 | |
11811 | 331 gtk_widget_set_sensitive(dialog->use_button, (num_selected == 1)); |
332 gtk_widget_set_sensitive(dialog->modify_button, (num_selected > 0)); | |
333 gtk_widget_set_sensitive(dialog->delete_button, (num_selected > 0)); | |
10421 | 334 } |
335 | |
336 static void | |
337 add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status) | |
338 { | |
339 GtkTreeIter iter; | |
340 const char *title; | |
341 const char *type; | |
342 char *message; | |
343 | |
11651 | 344 if (gaim_savedstatus_is_transient(saved_status)) |
345 return; | |
346 | |
10421 | 347 title = gaim_savedstatus_get_title(saved_status); |
348 type = gaim_primitive_get_name_from_type(gaim_savedstatus_get_type(saved_status)); | |
349 message = gaim_markup_strip_html(gaim_savedstatus_get_message(saved_status)); | |
350 | |
351 gtk_list_store_append(model, &iter); | |
352 gtk_list_store_set(model, &iter, | |
353 STATUS_WINDOW_COLUMN_TITLE, title, | |
354 STATUS_WINDOW_COLUMN_TYPE, type, | |
355 STATUS_WINDOW_COLUMN_MESSAGE, message, | |
356 -1); | |
357 free(message); | |
358 } | |
359 | |
360 static void | |
361 populate_saved_status_list(StatusWindow *dialog) | |
362 { | |
363 const GList *saved_statuses; | |
364 | |
365 gtk_list_store_clear(dialog->model); | |
366 | |
367 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL; | |
368 saved_statuses = g_list_next(saved_statuses)) | |
369 { | |
12199 | 370 add_status_to_saved_status_list(dialog->model, saved_statuses->data); |
10421 | 371 } |
372 } | |
373 | |
10435 | 374 static gboolean |
375 search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) | |
376 { | |
10439 | 377 gboolean result; |
378 char *haystack; | |
10435 | 379 |
380 gtk_tree_model_get(model, iter, column, &haystack, -1); | |
381 | |
10439 | 382 result = (gaim_strcasestr(haystack, key) == NULL); |
383 | |
384 g_free(haystack); | |
385 | |
386 return result; | |
10435 | 387 } |
388 | |
12162
5e24b8e49522
[gaim-migrate @ 14463]
Richard Laager <rlaager@wiktel.com>
parents:
12080
diff
changeset
|
389 static void |
12173
81c63578aa39
[gaim-migrate @ 14475]
Richard Laager <rlaager@wiktel.com>
parents:
12162
diff
changeset
|
390 savedstatus_activated_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, StatusWindow *dialog) |
12162
5e24b8e49522
[gaim-migrate @ 14463]
Richard Laager <rlaager@wiktel.com>
parents:
12080
diff
changeset
|
391 { |
12173
81c63578aa39
[gaim-migrate @ 14475]
Richard Laager <rlaager@wiktel.com>
parents:
12162
diff
changeset
|
392 status_window_modify_cb(NULL, dialog); |
12162
5e24b8e49522
[gaim-migrate @ 14463]
Richard Laager <rlaager@wiktel.com>
parents:
12080
diff
changeset
|
393 } |
5e24b8e49522
[gaim-migrate @ 14463]
Richard Laager <rlaager@wiktel.com>
parents:
12080
diff
changeset
|
394 |
10421 | 395 static GtkWidget * |
396 create_saved_status_list(StatusWindow *dialog) | |
397 { | |
398 GtkWidget *sw; | |
399 GtkWidget *treeview; | |
400 GtkTreeSelection *sel; | |
401 GtkTreeViewColumn *column; | |
402 GtkCellRenderer *renderer; | |
403 | |
404 /* Create the scrolled window */ | |
405 sw = gtk_scrolled_window_new(0, 0); | |
406 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
407 GTK_POLICY_AUTOMATIC, | |
408 GTK_POLICY_ALWAYS); | |
409 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
410 GTK_SHADOW_IN); | |
411 gtk_widget_show(sw); | |
412 | |
413 /* Create the list model */ | |
414 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, | |
415 G_TYPE_STRING, | |
416 G_TYPE_STRING, | |
417 G_TYPE_STRING); | |
418 | |
419 /* Create the treeview */ | |
420 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
421 dialog->treeview = treeview; | |
422 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
12162
5e24b8e49522
[gaim-migrate @ 14463]
Richard Laager <rlaager@wiktel.com>
parents:
12080
diff
changeset
|
423 g_signal_connect(G_OBJECT(treeview), "row-activated", |
12173
81c63578aa39
[gaim-migrate @ 14475]
Richard Laager <rlaager@wiktel.com>
parents:
12162
diff
changeset
|
424 G_CALLBACK(savedstatus_activated_cb), dialog); |
10421 | 425 |
426 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
427 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
428 g_signal_connect(G_OBJECT(sel), "changed", | |
429 G_CALLBACK(status_selected_cb), dialog); | |
430 | |
431 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
432 gtk_widget_show(treeview); | |
433 | |
434 /* Add columns */ | |
435 column = gtk_tree_view_column_new(); | |
436 gtk_tree_view_column_set_title(column, _("Title")); | |
437 gtk_tree_view_column_set_resizable(column, TRUE); | |
11548 | 438 gtk_tree_view_column_set_min_width(column, 100); |
10421 | 439 gtk_tree_view_column_set_sort_column_id(column, |
440 STATUS_WINDOW_COLUMN_TITLE); | |
441 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
442 renderer = gtk_cell_renderer_text_new(); | |
443 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
444 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
445 STATUS_WINDOW_COLUMN_TITLE); | |
11548 | 446 #if GTK_CHECK_VERSION(2,6,0) |
447 g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); | |
448 #endif | |
10421 | 449 |
450 column = gtk_tree_view_column_new(); | |
451 gtk_tree_view_column_set_title(column, _("Type")); | |
452 gtk_tree_view_column_set_resizable(column, TRUE); | |
453 gtk_tree_view_column_set_sort_column_id(column, | |
454 STATUS_WINDOW_COLUMN_TYPE); | |
455 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
456 renderer = gtk_cell_renderer_text_new(); | |
457 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
458 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
459 STATUS_WINDOW_COLUMN_TYPE); | |
460 | |
461 column = gtk_tree_view_column_new(); | |
462 gtk_tree_view_column_set_title(column, _("Message")); | |
463 gtk_tree_view_column_set_resizable(column, TRUE); | |
464 gtk_tree_view_column_set_sort_column_id(column, | |
465 STATUS_WINDOW_COLUMN_MESSAGE); | |
466 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
467 renderer = gtk_cell_renderer_text_new(); | |
468 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
469 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
470 STATUS_WINDOW_COLUMN_MESSAGE); | |
10435 | 471 #if GTK_CHECK_VERSION(2,6,0) |
10502 | 472 g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
10435 | 473 #endif |
474 | |
475 /* Enable CTRL+F searching */ | |
476 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), STATUS_WINDOW_COLUMN_TITLE); | |
477 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), search_func, NULL, NULL); | |
10421 | 478 |
10422 | 479 /* Sort the title column by default */ |
480 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->model), | |
481 STATUS_WINDOW_COLUMN_TITLE, | |
482 GTK_SORT_ASCENDING); | |
483 | |
10421 | 484 /* Populate list */ |
485 populate_saved_status_list(dialog); | |
486 | |
487 return sw; | |
488 } | |
489 | |
490 static gboolean | |
491 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog) | |
492 { | |
493 if (GTK_WIDGET_VISIBLE(widget)) { | |
494 gaim_prefs_set_int("/gaim/gtk/status/dialog/width", event->width); | |
495 gaim_prefs_set_int("/gaim/gtk/status/dialog/height", event->height); | |
496 } | |
497 | |
498 return FALSE; | |
499 } | |
500 | |
501 void | |
502 gaim_gtk_status_window_show(void) | |
503 { | |
504 StatusWindow *dialog; | |
505 GtkWidget *bbox; | |
506 GtkWidget *button; | |
507 GtkWidget *list; | |
508 GtkWidget *vbox; | |
509 GtkWidget *win; | |
510 int width, height; | |
511 | |
512 if (status_window != NULL) { | |
513 gtk_window_present(GTK_WINDOW(status_window->window)); | |
514 return; | |
515 } | |
516 | |
517 status_window = dialog = g_new0(StatusWindow, 1); | |
518 | |
519 width = gaim_prefs_get_int("/gaim/gtk/status/dialog/width"); | |
520 height = gaim_prefs_get_int("/gaim/gtk/status/dialog/height"); | |
521 | |
522 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
523 gtk_window_set_default_size(GTK_WINDOW(win), width, height); | |
524 gtk_window_set_role(GTK_WINDOW(win), "statuses"); | |
525 gtk_window_set_title(GTK_WINDOW(win), _("Saved Statuses")); | |
11243 | 526 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); |
10421 | 527 |
528 g_signal_connect(G_OBJECT(win), "delete_event", | |
529 G_CALLBACK(status_window_destroy_cb), dialog); | |
530 g_signal_connect(G_OBJECT(win), "configure_event", | |
531 G_CALLBACK(configure_cb), dialog); | |
532 | |
533 /* Setup the vbox */ | |
11243 | 534 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); |
10421 | 535 gtk_container_add(GTK_CONTAINER(win), vbox); |
536 gtk_widget_show(vbox); | |
537 | |
538 /* List of saved status states */ | |
539 list = create_saved_status_list(dialog); | |
540 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); | |
541 | |
542 /* Button box. */ | |
543 bbox = gtk_hbutton_box_new(); | |
11243 | 544 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); |
10421 | 545 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); |
546 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
547 gtk_widget_show(bbox); | |
548 | |
11811 | 549 /* Use button */ |
11832 | 550 button = gaim_pixbuf_button_from_stock(_("_Use"), GTK_STOCK_EXECUTE, |
551 GAIM_BUTTON_HORIZONTAL); | |
11811 | 552 dialog->use_button = button; |
553 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
554 gtk_widget_set_sensitive(button, FALSE); | |
555 gtk_widget_show(button); | |
556 | |
557 g_signal_connect(G_OBJECT(button), "clicked", | |
558 G_CALLBACK(status_window_use_cb), dialog); | |
559 | |
10421 | 560 /* Add button */ |
561 button = gtk_button_new_from_stock(GTK_STOCK_ADD); | |
562 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
563 gtk_widget_show(button); | |
564 | |
565 g_signal_connect(G_OBJECT(button), "clicked", | |
566 G_CALLBACK(status_window_add_cb), dialog); | |
567 | |
568 /* Modify button */ | |
569 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY); | |
570 dialog->modify_button = button; | |
571 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
572 gtk_widget_set_sensitive(button, FALSE); | |
573 gtk_widget_show(button); | |
574 | |
575 g_signal_connect(G_OBJECT(button), "clicked", | |
576 G_CALLBACK(status_window_modify_cb), dialog); | |
577 | |
578 /* Delete button */ | |
579 button = gtk_button_new_from_stock(GTK_STOCK_DELETE); | |
580 dialog->delete_button = button; | |
581 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
582 gtk_widget_set_sensitive(button, FALSE); | |
583 gtk_widget_show(button); | |
584 | |
585 g_signal_connect(G_OBJECT(button), "clicked", | |
586 G_CALLBACK(status_window_delete_cb), dialog); | |
587 | |
588 /* Close button */ | |
589 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
590 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
591 gtk_widget_show(button); | |
592 | |
593 g_signal_connect(G_OBJECT(button), "clicked", | |
594 G_CALLBACK(status_window_close_cb), dialog); | |
595 | |
596 gtk_widget_show(win); | |
597 } | |
598 | |
599 void | |
600 gaim_gtk_status_window_hide(void) | |
601 { | |
602 if (status_window == NULL) | |
603 return; | |
604 | |
605 if (status_window->window != NULL) | |
606 gtk_widget_destroy(status_window->window); | |
607 | |
608 g_free(status_window); | |
609 status_window = NULL; | |
610 } | |
611 | |
612 | |
613 /************************************************************************** | |
614 * Status editor | |
615 **************************************************************************/ | |
10420 | 616 |
10418 | 617 static gboolean |
618 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
619 { | |
10574 | 620 StatusEditor *dialog = user_data; |
10418 | 621 |
10574 | 622 g_free(dialog->original_title); |
10418 | 623 g_free(dialog); |
624 | |
625 return FALSE; | |
626 } | |
627 | |
628 static void | |
629 status_editor_cancel_cb(GtkButton *button, gpointer user_data) | |
630 { | |
10574 | 631 StatusEditor *dialog = user_data; |
10418 | 632 |
633 gtk_widget_destroy(dialog->window); | |
634 | |
10574 | 635 g_free(dialog->original_title); |
10418 | 636 g_free(dialog); |
637 } | |
638 | |
639 static void | |
12329 | 640 status_editor_ok_cb(GtkButton *button, gpointer user_data) |
10418 | 641 { |
10420 | 642 StatusEditor *dialog = user_data; |
643 const char *title; | |
644 GaimStatusPrimitive type; | |
645 char *message, *unformatted; | |
12080 | 646 GaimSavedStatus *saved_status = NULL; |
647 GtkTreeModel *model; | |
648 GtkTreeIter iter; | |
10420 | 649 |
650 title = gtk_entry_get_text(dialog->title); | |
651 | |
652 /* | |
12329 | 653 * If we're saving this status, and the title is already taken |
654 * then show an error dialog and don't do anything. | |
10420 | 655 */ |
12329 | 656 if (((button == dialog->saveanduse_button) || (button == dialog->save_button)) && |
657 (gaim_savedstatus_find(title) != NULL) && | |
10420 | 658 ((dialog->original_title == NULL) || (strcmp(title, dialog->original_title)))) |
659 { | |
660 gaim_notify_error(NULL, NULL, _("Title already in use. You must " | |
661 "choose a unique title."), NULL); | |
662 return; | |
663 } | |
664 | |
665 type = gtk_option_menu_get_history(dialog->type); | |
666 message = gtk_imhtml_get_markup(dialog->message); | |
667 unformatted = gaim_markup_strip_html(message); | |
668 | |
669 /* | |
12080 | 670 * If we're editing an old status, then lookup the old status (it's |
671 * possible that it has been deleted or renamed or something, and | |
672 * no longer exists). | |
10420 | 673 */ |
674 if (dialog->original_title != NULL) | |
675 { | |
676 GtkTreeIter iter; | |
677 | |
12080 | 678 saved_status = gaim_savedstatus_find(dialog->original_title); |
10420 | 679 |
680 if (status_window_find_savedstatus(&iter, dialog->original_title)) | |
681 { | |
682 gtk_list_store_remove(status_window->model, &iter); | |
683 } | |
684 } | |
685 | |
12080 | 686 if (saved_status == NULL) |
687 { | |
688 /* This is a new status */ | |
12329 | 689 if ((button == dialog->saveanduse_button) |
690 || (button == dialog->save_button)) | |
691 saved_status = gaim_savedstatus_new(title, type); | |
692 else | |
693 saved_status = gaim_savedstatus_new(NULL, type); | |
12080 | 694 } |
695 else | |
696 { | |
697 /* Modify the old status */ | |
698 if (strcmp(title, dialog->original_title)) | |
699 gaim_savedstatus_set_title(saved_status, title); | |
700 gaim_savedstatus_set_type(saved_status, type); | |
701 } | |
702 | |
10420 | 703 if (*unformatted != '\0') |
12080 | 704 gaim_savedstatus_set_message(saved_status, message); |
705 | |
706 /* Set any substatuses */ | |
707 model = GTK_TREE_MODEL(dialog->model); | |
708 if (gtk_tree_model_get_iter_first(model, &iter)) | |
709 { | |
710 GaimAccount *account; | |
711 gboolean enabled; | |
712 char *id; | |
713 char *message; | |
714 GaimStatusType *type; | |
715 | |
716 gtk_tree_model_get(model, &iter, | |
717 STATUS_EDITOR_COLUMN_ACCOUNT, &account, | |
718 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &enabled, | |
719 STATUS_EDITOR_COLUMN_STATUS_ID, &id, | |
720 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, &message, | |
721 -1); | |
722 if (enabled) | |
723 { | |
724 type = gaim_account_get_status_type(account, id); | |
725 gaim_savedstatus_set_substatus(saved_status, account, type, message); | |
726 } | |
727 g_free(id); | |
728 g_free(message); | |
729 | |
730 while (gtk_tree_model_iter_next(model, &iter)) | |
731 { | |
732 gtk_tree_model_get(model, &iter, | |
733 STATUS_EDITOR_COLUMN_ACCOUNT, &account, | |
734 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &enabled, | |
735 STATUS_EDITOR_COLUMN_STATUS_ID, &id, | |
736 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, &message, | |
737 -1); | |
738 if (enabled) | |
739 { | |
740 type = gaim_account_get_status_type(account, id); | |
741 gaim_savedstatus_set_substatus(saved_status, account, type, message); | |
742 } | |
743 g_free(id); | |
744 g_free(message); | |
745 } | |
746 } | |
747 | |
10420 | 748 g_free(message); |
749 g_free(unformatted); | |
750 | |
751 gtk_widget_destroy(dialog->window); | |
10574 | 752 g_free(dialog->original_title); |
10420 | 753 g_free(dialog); |
754 | |
12080 | 755 if (status_window != NULL) |
12199 | 756 add_status_to_saved_status_list(status_window->model, saved_status); |
12329 | 757 |
758 if ((button == dialog->saveanduse_button) | |
759 || (button != dialog->save_button)) | |
760 gaim_savedstatus_activate(saved_status); | |
10420 | 761 } |
762 | |
763 static void | |
764 editor_title_changed_cb(GtkWidget *widget, gpointer user_data) | |
765 { | |
766 StatusEditor *dialog = user_data; | |
767 const gchar *text; | |
768 | |
769 text = gtk_entry_get_text(dialog->title); | |
770 | |
12329 | 771 gtk_widget_set_sensitive(GTK_WIDGET(dialog->saveanduse_button), (*text != '\0')); |
772 gtk_widget_set_sensitive(GTK_WIDGET(dialog->save_button), (*text != '\0')); | |
10418 | 773 } |
774 | |
775 static GtkWidget * | |
10419 | 776 create_status_type_menu(GaimStatusPrimitive type) |
10418 | 777 { |
10419 | 778 int i; |
10418 | 779 GtkWidget *dropdown; |
780 GtkWidget *menu; | |
781 GtkWidget *item; | |
782 | |
783 dropdown = gtk_option_menu_new(); | |
784 menu = gtk_menu_new(); | |
785 | |
10419 | 786 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) |
787 { | |
788 item = gtk_menu_item_new_with_label(gaim_primitive_get_name_from_type(i)); | |
789 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
790 gtk_widget_show(item); | |
791 } | |
10418 | 792 |
10419 | 793 gtk_menu_set_active(GTK_MENU(menu), type); |
10418 | 794 gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu); |
795 gtk_widget_show(menu); | |
796 | |
797 return dropdown; | |
798 } | |
799 | |
12080 | 800 static void edit_substatus(StatusEditor *status_editor, GaimAccount *account); |
801 | |
802 static void | |
803 edit_substatus_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data) | |
804 { | |
805 StatusEditor *dialog = user_data; | |
806 GtkTreeIter iter; | |
807 GaimAccount *account; | |
808 | |
809 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); | |
810 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, | |
811 STATUS_EDITOR_COLUMN_ACCOUNT, &account, | |
812 -1); | |
813 | |
814 edit_substatus(dialog, account); | |
815 } | |
816 | |
817 static void | |
818 status_editor_substatus_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data) | |
819 { | |
820 StatusEditor *dialog = (StatusEditor *)data; | |
821 GtkTreeIter iter; | |
822 gboolean enabled; | |
823 GaimAccount *account; | |
824 | |
825 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(dialog->model), &iter, path_str); | |
826 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, | |
827 STATUS_EDITOR_COLUMN_ACCOUNT, &account, | |
828 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &enabled, | |
829 -1); | |
830 | |
831 enabled = !enabled; | |
832 | |
833 if (enabled) | |
834 { | |
835 edit_substatus(dialog, account); | |
836 } | |
837 else | |
838 { | |
839 GaimSavedStatus *saved_status; | |
840 | |
841 /* Remove the substatus */ | |
842 saved_status = gaim_savedstatus_find(dialog->original_title); | |
843 gaim_savedstatus_unset_substatus(saved_status, account); | |
844 gtk_list_store_set(dialog->model, &iter, | |
845 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, enabled, | |
846 STATUS_EDITOR_COLUMN_STATUS_ID, NULL, | |
847 STATUS_EDITOR_COLUMN_STATUS_NAME, NULL, | |
848 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, NULL, | |
849 -1); | |
850 } | |
851 } | |
852 | |
10418 | 853 static void |
854 status_editor_add_columns(StatusEditor *dialog) | |
855 { | |
856 GtkCellRenderer *renderer; | |
857 GtkTreeViewColumn *column; | |
858 | |
12080 | 859 /* Enable Different status column */ |
10418 | 860 renderer = gtk_cell_renderer_toggle_new(); |
861 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog->treeview), | |
12080 | 862 -1, _("Different"), |
10418 | 863 renderer, |
12080 | 864 "active", STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, |
10418 | 865 NULL); |
866 column = gtk_tree_view_get_column(GTK_TREE_VIEW(dialog->treeview), 1); | |
867 g_signal_connect(G_OBJECT(renderer), "toggled", | |
12080 | 868 G_CALLBACK(status_editor_substatus_cb), dialog); |
10418 | 869 |
870 /* Screen Name column */ | |
871 column = gtk_tree_view_column_new(); | |
872 gtk_tree_view_column_set_resizable(column, TRUE); | |
873 gtk_tree_view_column_set_title(column, _("Screen Name")); | |
874 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); | |
875 gtk_tree_view_column_set_resizable(column, TRUE); | |
876 | |
877 /* Icon */ | |
878 renderer = gtk_cell_renderer_pixbuf_new(); | |
879 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
880 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", | |
881 STATUS_EDITOR_COLUMN_ICON); | |
882 | |
883 /* Screen Name */ | |
884 renderer = gtk_cell_renderer_text_new(); | |
885 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
886 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
887 STATUS_EDITOR_COLUMN_SCREENNAME); | |
12080 | 888 |
889 /* Status column */ | |
890 column = gtk_tree_view_column_new(); | |
891 gtk_tree_view_column_set_resizable(column, TRUE); | |
892 gtk_tree_view_column_set_title(column, _("Status")); | |
893 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); | |
894 gtk_tree_view_column_set_resizable(column, TRUE); | |
895 renderer = gtk_cell_renderer_text_new(); | |
896 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
897 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
898 STATUS_EDITOR_COLUMN_STATUS_NAME); | |
899 | |
900 /* Message column */ | |
901 column = gtk_tree_view_column_new(); | |
902 gtk_tree_view_column_set_resizable(column, TRUE); | |
903 gtk_tree_view_column_set_title(column, _("Message")); | |
904 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); | |
905 gtk_tree_view_column_set_resizable(column, TRUE); | |
906 renderer = gtk_cell_renderer_text_new(); | |
907 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
908 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
909 STATUS_EDITOR_COLUMN_STATUS_MESSAGE); | |
910 | |
911 g_signal_connect(G_OBJECT(dialog->treeview), "row-activated", | |
912 G_CALLBACK(edit_substatus_cb), dialog); | |
10418 | 913 } |
914 | |
915 static void | |
12080 | 916 status_editor_set_account(GtkListStore *store, GaimAccount *account, |
917 GtkTreeIter *iter, GaimSavedStatusSub *substatus) | |
10418 | 918 { |
919 GdkPixbuf *pixbuf; | |
920 GdkPixbuf *scale; | |
12080 | 921 const char *id = NULL, *name = NULL, *message = NULL; |
10418 | 922 |
923 scale = NULL; | |
924 | |
10884 | 925 pixbuf = gaim_gtk_create_prpl_icon(account); |
10418 | 926 |
927 if (pixbuf != NULL) | |
928 { | |
929 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); | |
930 | |
11251 | 931 if (gaim_account_is_disconnected(account)) |
10418 | 932 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); |
933 } | |
934 | |
12080 | 935 if (substatus != NULL) |
936 { | |
937 const GaimStatusType *type; | |
938 | |
939 type = gaim_savedstatus_substatus_get_type(substatus); | |
940 id = gaim_status_type_get_id(type); | |
941 name = gaim_status_type_get_name(type); | |
942 if (gaim_status_type_get_attr(type, "message")) | |
943 message = gaim_savedstatus_substatus_get_message(substatus); | |
944 } | |
945 | |
10418 | 946 gtk_list_store_set(store, iter, |
12080 | 947 STATUS_EDITOR_COLUMN_ACCOUNT, account, |
948 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, (substatus != NULL), | |
10418 | 949 STATUS_EDITOR_COLUMN_ICON, scale, |
950 STATUS_EDITOR_COLUMN_SCREENNAME, gaim_account_get_username(account), | |
12080 | 951 STATUS_EDITOR_COLUMN_STATUS_ID, id, |
952 STATUS_EDITOR_COLUMN_STATUS_NAME, name, | |
953 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message, | |
10418 | 954 -1); |
955 | |
956 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf)); | |
957 if (scale != NULL) g_object_unref(G_OBJECT(scale)); | |
958 } | |
959 | |
960 static void | |
12080 | 961 status_editor_add_account(StatusEditor *dialog, GaimAccount *account, |
962 GaimSavedStatusSub *substatus) | |
10418 | 963 { |
964 GtkTreeIter iter; | |
965 | |
966 gtk_list_store_append(dialog->model, &iter); | |
967 | |
12080 | 968 status_editor_set_account(dialog->model, account, &iter, substatus); |
10418 | 969 } |
970 | |
971 static void | |
12080 | 972 status_editor_populate_list(StatusEditor *dialog, GaimSavedStatus *saved_status) |
10418 | 973 { |
12080 | 974 GList *iter; |
975 GaimSavedStatusSub *substatus; | |
10418 | 976 |
977 gtk_list_store_clear(dialog->model); | |
978 | |
12080 | 979 for (iter = gaim_accounts_get_all(); iter != NULL; iter = iter->next) |
980 { | |
981 GaimAccount *account = (GaimAccount *)iter->data; | |
982 | |
983 if (saved_status != NULL) | |
984 substatus = gaim_savedstatus_get_substatus(saved_status, account); | |
985 else | |
986 substatus = NULL; | |
987 | |
988 status_editor_add_account(dialog, account, substatus); | |
989 } | |
10418 | 990 } |
991 | |
992 void | |
12080 | 993 gaim_gtk_status_editor_show(GaimSavedStatus *saved_status) |
10418 | 994 { |
995 StatusEditor *dialog; | |
996 GtkSizeGroup *sg; | |
997 GtkWidget *bbox; | |
998 GtkWidget *button; | |
999 GtkWidget *dbox; | |
11735 | 1000 GtkWidget *expander; |
10418 | 1001 GtkWidget *dropdown; |
1002 GtkWidget *entry; | |
1003 GtkWidget *frame; | |
1004 GtkWidget *hbox; | |
1005 GtkWidget *label; | |
1006 GtkWidget *sw; | |
1007 GtkWidget *text; | |
1008 GtkWidget *toolbar; | |
1009 GtkWidget *vbox; | |
1010 GtkWidget *win; | |
1011 | |
1012 dialog = g_new0(StatusEditor, 1); | |
1013 | |
12080 | 1014 if (saved_status != NULL) |
1015 dialog->original_title = g_strdup(gaim_savedstatus_get_title(saved_status)); | |
10420 | 1016 |
10418 | 1017 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
1018 gtk_window_set_role(GTK_WINDOW(win), "status"); | |
1019 gtk_window_set_title(GTK_WINDOW(win), _("Status")); | |
1020 gtk_window_set_resizable(GTK_WINDOW(win), FALSE); | |
11243 | 1021 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); |
10418 | 1022 |
1023 g_signal_connect(G_OBJECT(win), "delete_event", | |
1024 G_CALLBACK(status_editor_destroy_cb), dialog); | |
1025 | |
1026 /* Setup the vbox */ | |
11243 | 1027 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); |
10418 | 1028 gtk_container_add(GTK_CONTAINER(win), vbox); |
1029 gtk_widget_show(vbox); | |
1030 | |
1031 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
1032 | |
1033 /* Title */ | |
11243 | 1034 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); |
10418 | 1035 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
1036 gtk_widget_show(hbox); | |
1037 | |
1038 label = gtk_label_new_with_mnemonic(_("_Title:")); | |
1039 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
1040 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
1041 gtk_widget_show(label); | |
1042 gtk_size_group_add_widget(sg, label); | |
1043 | |
1044 entry = gtk_entry_new(); | |
10420 | 1045 dialog->title = GTK_ENTRY(entry); |
12080 | 1046 if (dialog->original_title != NULL) |
10420 | 1047 gtk_entry_set_text(GTK_ENTRY(entry), dialog->original_title); |
10418 | 1048 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); |
1049 gtk_widget_show(entry); | |
10420 | 1050 g_signal_connect(G_OBJECT(entry), "changed", |
1051 G_CALLBACK(editor_title_changed_cb), dialog); | |
10418 | 1052 |
1053 /* Status type */ | |
11243 | 1054 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); |
10418 | 1055 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
1056 gtk_widget_show(hbox); | |
1057 | |
1058 label = gtk_label_new_with_mnemonic(_("_Status:")); | |
1059 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
1060 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
1061 gtk_widget_show(label); | |
1062 gtk_size_group_add_widget(sg, label); | |
1063 | |
12080 | 1064 if (saved_status != NULL) |
1065 dropdown = create_status_type_menu(gaim_savedstatus_get_type(saved_status)); | |
10419 | 1066 else |
1067 dropdown = create_status_type_menu(GAIM_STATUS_AWAY); | |
10420 | 1068 dialog->type = GTK_OPTION_MENU(dropdown); |
10418 | 1069 gtk_box_pack_start(GTK_BOX(hbox), dropdown, TRUE, TRUE, 0); |
1070 gtk_widget_show(dropdown); | |
1071 | |
1072 /* Status message */ | |
11243 | 1073 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); |
10418 | 1074 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
1075 gtk_widget_show(hbox); | |
1076 | |
1077 label = gtk_label_new_with_mnemonic(_("_Message:")); | |
1078 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
1079 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
1080 gtk_widget_show(label); | |
1081 gtk_size_group_add_widget(sg, label); | |
1082 | |
1083 frame = gaim_gtk_create_imhtml(TRUE, &text, &toolbar); | |
10420 | 1084 dialog->message = GTK_IMHTML(text); |
10418 | 1085 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); |
1086 gtk_widget_show(frame); | |
1087 | |
12080 | 1088 if ((saved_status != NULL) && (gaim_savedstatus_get_message(saved_status) != NULL)) |
10419 | 1089 gtk_imhtml_append_text(GTK_IMHTML(text), |
12080 | 1090 gaim_savedstatus_get_message(saved_status), 0); |
10419 | 1091 |
12080 | 1092 /* Different status message expander */ |
11735 | 1093 expander = gtk_expander_new_with_mnemonic(_("Use a _different status for some accounts")); |
1094 gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0); | |
1095 gtk_widget_show(expander); | |
10418 | 1096 |
11735 | 1097 /* Setup the box that the expander will cover */ |
11243 | 1098 dbox = gtk_vbox_new(FALSE, GAIM_HIG_CAT_SPACE); |
11735 | 1099 gtk_container_add(GTK_CONTAINER(expander), dbox); |
1100 gtk_widget_show(dbox); | |
10418 | 1101 |
12080 | 1102 /* Different status message treeview */ |
10418 | 1103 sw = gtk_scrolled_window_new(NULL, NULL); |
1104 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
1105 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
1106 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
1107 GTK_SHADOW_IN); | |
1108 gtk_box_pack_start(GTK_BOX(dbox), sw, TRUE, TRUE, 0); | |
1109 gtk_widget_show(sw); | |
1110 | |
1111 /* Create the list model */ | |
1112 dialog->model = gtk_list_store_new(STATUS_EDITOR_NUM_COLUMNS, | |
12080 | 1113 G_TYPE_POINTER, |
10418 | 1114 G_TYPE_BOOLEAN, |
12080 | 1115 GDK_TYPE_PIXBUF, |
1116 G_TYPE_STRING, | |
1117 G_TYPE_STRING, | |
1118 G_TYPE_STRING, | |
1119 G_TYPE_STRING); | |
10418 | 1120 |
1121 /* Create the treeview */ | |
1122 dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
1123 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE); | |
1124 gtk_widget_set_size_request(dialog->treeview, 400, 250); | |
1125 gtk_container_add(GTK_CONTAINER(sw), dialog->treeview); | |
1126 gtk_widget_show(dialog->treeview); | |
1127 | |
1128 /* Add columns */ | |
1129 status_editor_add_columns(dialog); | |
1130 | |
1131 /* Populate list */ | |
12080 | 1132 status_editor_populate_list(dialog, saved_status); |
10418 | 1133 |
1134 /* Button box */ | |
1135 bbox = gtk_hbutton_box_new(); | |
11243 | 1136 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); |
10418 | 1137 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); |
1138 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
1139 gtk_widget_show(bbox); | |
1140 | |
1141 /* Cancel button */ | |
1142 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); | |
1143 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1144 gtk_widget_show(button); | |
1145 | |
1146 g_signal_connect(G_OBJECT(button), "clicked", | |
1147 G_CALLBACK(status_editor_cancel_cb), dialog); | |
1148 | |
12329 | 1149 /* Use button */ |
1150 button = gaim_pixbuf_button_from_stock(_("_Use"), GTK_STOCK_EXECUTE, | |
1151 GAIM_BUTTON_HORIZONTAL); | |
10418 | 1152 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); |
12329 | 1153 gtk_widget_show(button); |
1154 | |
1155 g_signal_connect(G_OBJECT(button), "clicked", | |
1156 G_CALLBACK(status_editor_ok_cb), dialog); | |
1157 | |
1158 /* Save & Use button */ | |
1159 button = gaim_pixbuf_button_from_stock(_("Sa_ve & Use"), GTK_STOCK_OK, | |
1160 GAIM_BUTTON_HORIZONTAL); | |
1161 dialog->saveanduse_button = GTK_BUTTON(button); | |
1162 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1163 if (dialog->original_title == NULL) | |
12080 | 1164 gtk_widget_set_sensitive(button, FALSE); |
10418 | 1165 gtk_widget_show(button); |
1166 | |
1167 g_signal_connect(G_OBJECT(button), "clicked", | |
12329 | 1168 G_CALLBACK(status_editor_ok_cb), dialog); |
1169 | |
1170 /* Save button */ | |
1171 button = gtk_button_new_from_stock(GTK_STOCK_SAVE); | |
1172 dialog->save_button = GTK_BUTTON(button); | |
1173 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1174 if (dialog->original_title == NULL) | |
1175 gtk_widget_set_sensitive(button, FALSE); | |
1176 gtk_widget_show(button); | |
1177 | |
1178 g_signal_connect(G_OBJECT(button), "clicked", | |
1179 G_CALLBACK(status_editor_ok_cb), dialog); | |
10418 | 1180 |
1181 gtk_widget_show(win); | |
1182 } | |
1183 | |
1184 | |
10421 | 1185 /************************************************************************** |
12080 | 1186 * SubStatus editor |
1187 **************************************************************************/ | |
1188 | |
1189 static void | |
1190 substatus_selection_changed_cb(GtkComboBox *box, gpointer user_data) | |
1191 { | |
1192 SubStatusEditor *select = user_data; | |
1193 GtkTreeIter iter; | |
1194 GaimAccount *account; | |
1195 char *id; | |
1196 GaimStatusType *type; | |
1197 | |
1198 if (!gtk_combo_box_get_active_iter(box, &iter)) | |
1199 return; | |
1200 gtk_tree_model_get(GTK_TREE_MODEL(select->model), &iter, | |
1201 SUBSTATUS_COLUMN_ACCOUNT, &account, | |
1202 SUBSTATUS_COLUMN_STATUS_ID, &id, | |
1203 -1); | |
1204 type = gaim_account_get_status_type(account, id); | |
1205 g_free(id); | |
1206 | |
1207 if (gaim_status_type_get_attr(type, "message") == NULL) | |
1208 { | |
1209 gtk_widget_set_sensitive(GTK_WIDGET(select->message), FALSE); | |
1210 gtk_widget_set_sensitive(GTK_WIDGET(select->toolbar), FALSE); | |
1211 } | |
1212 else | |
1213 { | |
1214 gtk_widget_set_sensitive(GTK_WIDGET(select->message), TRUE); | |
1215 gtk_widget_set_sensitive(GTK_WIDGET(select->toolbar), TRUE); | |
1216 } | |
1217 } | |
1218 | |
1219 static gboolean | |
1220 substatus_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
1221 { | |
1222 SubStatusEditor *dialog = user_data; | |
1223 | |
1224 g_free(dialog); | |
1225 | |
1226 return FALSE; | |
1227 } | |
1228 | |
12246 | 1229 static void |
12080 | 1230 substatus_editor_cancel_cb(GtkButton *button, gpointer user_data) |
1231 { | |
1232 SubStatusEditor *dialog = user_data; | |
1233 | |
1234 gtk_widget_destroy(dialog->window); | |
1235 | |
1236 g_free(dialog); | |
1237 } | |
1238 | |
1239 static gboolean | |
1240 status_editor_find_account_in_treemodel(GtkTreeIter *iter, | |
1241 StatusEditor *status_editor, | |
1242 GaimAccount *account) | |
1243 { | |
1244 GtkTreeModel *model; | |
1245 GaimAccount *cur; | |
1246 | |
1247 g_return_val_if_fail(status_editor != NULL, FALSE); | |
1248 g_return_val_if_fail(account != NULL, FALSE); | |
1249 | |
1250 model = GTK_TREE_MODEL(status_editor->model); | |
1251 | |
1252 if (!gtk_tree_model_get_iter_first(model, iter)) | |
1253 return FALSE; | |
1254 | |
1255 gtk_tree_model_get(model, iter, STATUS_EDITOR_COLUMN_ACCOUNT, &cur, -1); | |
1256 if (cur == account) | |
1257 return TRUE; | |
1258 | |
1259 while (gtk_tree_model_iter_next(model, iter)) | |
1260 { | |
1261 gtk_tree_model_get(model, iter, STATUS_EDITOR_COLUMN_ACCOUNT, &cur, -1); | |
1262 if (cur == account) | |
1263 return TRUE; | |
1264 } | |
1265 | |
1266 return FALSE; | |
1267 } | |
1268 | |
12246 | 1269 static void |
12080 | 1270 substatus_editor_ok_cb(GtkButton *button, gpointer user_data) |
1271 { | |
1272 SubStatusEditor *dialog = user_data; | |
1273 StatusEditor *status_editor; | |
1274 GtkTreeIter iter; | |
1275 GaimAccount *account; | |
1276 GaimStatusType *type; | |
1277 char *id = NULL; | |
1278 char *message = NULL; | |
1279 const char *name = NULL; | |
1280 | |
1281 gtk_combo_box_get_active_iter(dialog->box, &iter); | |
1282 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, | |
1283 SUBSTATUS_COLUMN_ACCOUNT, &account, | |
1284 SUBSTATUS_COLUMN_STATUS_ID, &id, | |
1285 -1); | |
1286 type = gaim_account_get_status_type(account, id); | |
1287 if (gaim_status_type_get_attr(type, "message") != NULL) | |
1288 message = gtk_imhtml_get_text(GTK_IMHTML(dialog->message), NULL, NULL); | |
1289 name = gaim_status_type_get_name(type); | |
1290 | |
1291 status_editor = dialog->status_editor; | |
1292 | |
1293 if (status_editor_find_account_in_treemodel(&iter, status_editor, account)) | |
1294 { | |
1295 gtk_list_store_set(status_editor->model, &iter, | |
1296 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, TRUE, | |
1297 STATUS_EDITOR_COLUMN_STATUS_ID, id, | |
1298 STATUS_EDITOR_COLUMN_STATUS_NAME, name, | |
1299 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message, | |
1300 -1); | |
1301 } | |
1302 | |
1303 gtk_widget_destroy(dialog->window); | |
1304 g_free(id); | |
1305 g_free(message); | |
1306 g_free(dialog); | |
1307 } | |
1308 | |
1309 static void | |
1310 edit_substatus(StatusEditor *status_editor, GaimAccount *account) | |
1311 { | |
1312 char *tmp; | |
1313 SubStatusEditor *dialog; | |
1314 GtkSizeGroup *sg; | |
1315 GtkWidget *bbox; | |
1316 GtkWidget *button; | |
1317 GtkWidget *combo; | |
1318 GtkWidget *hbox; | |
1319 GtkWidget *frame; | |
1320 GtkWidget *label; | |
1321 GtkWidget *text; | |
1322 GtkWidget *toolbar; | |
1323 GtkWidget *vbox; | |
1324 GtkWidget *win; | |
1325 GtkTreeIter iter; | |
1326 GtkCellRenderer *rend; | |
1327 const char *id = NULL; | |
1328 const GList *list; | |
1329 gboolean select = FALSE; | |
1330 | |
1331 g_return_if_fail(status_editor != NULL); | |
1332 g_return_if_fail(account != NULL); | |
1333 | |
1334 dialog = g_new0(SubStatusEditor, 1); | |
1335 dialog->status_editor = status_editor; | |
1336 | |
1337 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
1338 gtk_window_set_role(GTK_WINDOW(win), "substatus"); | |
1339 tmp = g_strdup_printf(_("Status for %s"), gaim_account_get_username(account)); | |
1340 gtk_window_set_title(GTK_WINDOW(win), tmp); | |
1341 g_free(tmp); | |
1342 gtk_window_set_resizable(GTK_WINDOW(win), FALSE); | |
1343 gtk_container_set_border_width(GTK_CONTAINER(win), GAIM_HIG_BORDER); | |
1344 | |
1345 g_signal_connect(G_OBJECT(win), "delete_event", | |
1346 G_CALLBACK(substatus_editor_destroy_cb), dialog); | |
1347 | |
1348 /* Setup the vbox */ | |
1349 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BORDER); | |
1350 gtk_container_add(GTK_CONTAINER(win), vbox); | |
1351 gtk_widget_show(vbox); | |
1352 | |
1353 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
1354 | |
1355 /* Status type */ | |
1356 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
1357 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
1358 gtk_widget_show(hbox); | |
1359 | |
1360 label = gtk_label_new_with_mnemonic(_("_Status:")); | |
1361 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
1362 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
1363 gtk_widget_show(label); | |
1364 gtk_size_group_add_widget(sg, label); | |
1365 | |
1366 dialog->model = gtk_list_store_new(SUBSTATUS_NUM_COLUMNS, | |
1367 G_TYPE_POINTER, | |
1368 GDK_TYPE_PIXBUF, | |
1369 G_TYPE_STRING, | |
1370 G_TYPE_STRING); | |
1371 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
1372 dialog->box = GTK_COMBO_BOX(combo); | |
1373 | |
1374 rend = GTK_CELL_RENDERER(gtk_cell_renderer_pixbuf_new()); | |
1375 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), rend, FALSE); | |
1376 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), rend, | |
1377 "pixbuf", SUBSTATUS_COLUMN_ICON, NULL); | |
1378 | |
1379 rend = GTK_CELL_RENDERER(gtk_cell_renderer_text_new()); | |
1380 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), rend, TRUE); | |
1381 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), rend, | |
1382 "text", SUBSTATUS_COLUMN_STATUS_NAME, NULL); | |
1383 | |
1384 g_signal_connect(G_OBJECT(combo), "changed", | |
1385 G_CALLBACK(substatus_selection_changed_cb), dialog); | |
1386 | |
1387 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0); | |
1388 gtk_widget_show(combo); | |
1389 | |
1390 /* Status mesage */ | |
1391 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
1392 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
1393 gtk_widget_show(hbox); | |
1394 | |
1395 label = gtk_label_new_with_mnemonic(_("_Message:")); | |
1396 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
1397 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
1398 gtk_widget_show(label); | |
1399 gtk_size_group_add_widget(sg, label); | |
1400 | |
1401 frame = gaim_gtk_create_imhtml(TRUE, &text, &toolbar); | |
1402 dialog->message = GTK_IMHTML(text); | |
1403 dialog->toolbar = GTK_IMHTMLTOOLBAR(toolbar); | |
1404 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); | |
1405 gtk_widget_show(frame); | |
1406 | |
1407 /* Button box */ | |
1408 bbox = gtk_hbutton_box_new(); | |
1409 gtk_box_set_spacing(GTK_BOX(bbox), GAIM_HIG_BOX_SPACE); | |
1410 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
1411 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
1412 gtk_widget_show(bbox); | |
1413 | |
1414 /* Cancel button */ | |
1415 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); | |
1416 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1417 gtk_widget_show(button); | |
1418 | |
1419 g_signal_connect(G_OBJECT(button), "clicked", | |
1420 G_CALLBACK(substatus_editor_cancel_cb), dialog); | |
1421 | |
1422 /* OK button */ | |
1423 button = gtk_button_new_from_stock(GTK_STOCK_OK); | |
1424 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
1425 gtk_widget_show(button); | |
1426 | |
1427 g_signal_connect(G_OBJECT(button), "clicked", | |
1428 G_CALLBACK(substatus_editor_ok_cb), dialog); | |
1429 | |
1430 /* Seed the input widgets with the current values */ | |
1431 /* TODO: Get the current values from our parent's list store, not the saved_status! */ | |
1432 if (status_editor->original_title != NULL) | |
1433 { | |
1434 GaimSavedStatus *saved_status = NULL; | |
1435 GaimSavedStatusSub *substatus = NULL; | |
1436 | |
1437 saved_status = gaim_savedstatus_find(status_editor->original_title); | |
1438 if (saved_status != NULL) | |
1439 substatus = gaim_savedstatus_get_substatus(saved_status, account); | |
1440 | |
1441 if (substatus != NULL) | |
1442 { | |
1443 gtk_imhtml_append_text(dialog->message, | |
1444 gaim_savedstatus_substatus_get_message(substatus), | |
1445 0); | |
1446 id = gaim_status_type_get_id(gaim_savedstatus_substatus_get_type(substatus)); | |
1447 } | |
1448 } | |
1449 | |
1450 for (list = gaim_account_get_status_types(account); list; list = list->next) | |
1451 { | |
1452 GaimStatusType *status_type; | |
1453 GdkPixbuf *pixbuf, *scale = NULL; | |
1454 const char *id, *name; | |
1455 | |
1456 status_type = list->data; | |
1457 id = gaim_status_type_get_id(status_type); | |
1458 pixbuf = gaim_gtk_create_prpl_icon_with_status(account, status_type); | |
1459 if (pixbuf != NULL) | |
1460 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); | |
1461 name = gaim_status_type_get_name(status_type); | |
1462 | |
1463 gtk_list_store_append(dialog->model, &iter); | |
1464 gtk_list_store_set(dialog->model, &iter, | |
1465 SUBSTATUS_COLUMN_ACCOUNT, account, | |
1466 SUBSTATUS_COLUMN_ICON, scale, | |
1467 SUBSTATUS_COLUMN_STATUS_ID, id, | |
1468 SUBSTATUS_COLUMN_STATUS_NAME, name, | |
1469 -1); | |
1470 if (id && !strcmp(id, gaim_status_type_get_id(status_type))) | |
1471 { | |
1472 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter); | |
1473 select = TRUE; | |
1474 } | |
1475 } | |
1476 | |
1477 if (!select) | |
1478 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); | |
1479 | |
1480 gtk_widget_show(win); | |
1481 } | |
1482 | |
12329 | 1483 |
12195 | 1484 /************************************************************************** |
1485 * Utilities * | |
1486 **************************************************************************/ | |
1487 | |
12246 | 1488 static void |
1489 status_menu_cb(GtkComboBox *widget, void(*callback)(GaimSavedStatus*)) | |
12195 | 1490 { |
12237 | 1491 GtkTreeIter iter; |
1492 gchar *title = NULL; | |
1493 | |
1494 if (!gtk_combo_box_get_active_iter(widget, &iter)) | |
1495 return; | |
1496 | |
1497 gtk_tree_model_get(gtk_combo_box_get_model(widget), &iter, | |
1498 STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
1499 callback(gaim_savedstatus_find(title)); | |
1500 g_free(title); | |
12195 | 1501 } |
1502 | |
1503 GtkWidget *gaim_gtk_status_menu(GaimSavedStatus *current_status, GCallback callback) | |
1504 { | |
1505 GtkWidget *combobox; | |
1506 const GList *saved_statuses; | |
1507 int i; | |
1508 int index = -1; | |
12329 | 1509 |
12199 | 1510 combobox = gtk_combo_box_new_text(); |
12329 | 1511 |
12195 | 1512 for (saved_statuses = gaim_savedstatuses_get_all(), i = 0; |
1513 saved_statuses != NULL; | |
12329 | 1514 saved_statuses = g_list_next(saved_statuses)) |
1515 { | |
12199 | 1516 GaimSavedStatus *status = (GaimSavedStatus*)saved_statuses->data; |
1517 if (!gaim_savedstatus_is_transient(status)) { | |
12329 | 1518 gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), |
12199 | 1519 gaim_savedstatus_get_title(status)); |
1520 if (status == current_status) | |
1521 index = i; | |
1522 i++; | |
1523 } | |
12195 | 1524 } |
12246 | 1525 |
12195 | 1526 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), index); |
1527 g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(status_menu_cb), callback); | |
12329 | 1528 |
12195 | 1529 return combobox; |
1530 } | |
1531 | |
12080 | 1532 |
1533 /************************************************************************** | |
10814
364a2ef907ae
[gaim-migrate @ 12468]
Luke Schierer <lschiere@pidgin.im>
parents:
10732
diff
changeset
|
1534 * GTK+ saved status glue |
10421 | 1535 **************************************************************************/ |
10418 | 1536 |
1537 void * | |
1538 gaim_gtk_status_get_handle() | |
1539 { | |
1540 static int handle; | |
1541 | |
1542 return &handle; | |
1543 } | |
1544 | |
1545 void | |
1546 gaim_gtk_status_init(void) | |
1547 { | |
1548 gaim_prefs_add_none("/gaim/gtk/status"); | |
1549 gaim_prefs_add_none("/gaim/gtk/status/dialog"); | |
1550 gaim_prefs_add_int("/gaim/gtk/status/dialog/width", 550); | |
1551 gaim_prefs_add_int("/gaim/gtk/status/dialog/height", 250); | |
1552 } | |
1553 | |
1554 void | |
1555 gaim_gtk_status_uninit(void) | |
1556 { | |
1557 gaim_gtk_status_window_hide(); | |
1558 } |