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