| 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
| 20 */ |
20 */ |
| 21 |
21 |
| 22 #include <glib/gi18n-lib.h> |
22 #include <glib/gi18n-lib.h> |
| 23 |
23 |
| 24 #include <talkatu.h> |
24 #include <gtk/gtk.h> |
| 25 |
25 |
| 26 #include <purple.h> |
26 #include <purple.h> |
| 27 |
27 |
| 28 #include "gtkblist.h" |
|
| 29 #include "gtksavedstatuses.h" |
28 #include "gtksavedstatuses.h" |
| 30 #include "gtkutils.h" |
|
| 31 #include "pidgincore.h" |
|
| 32 #include "pidgindialog.h" |
|
| 33 #include "pidginiconname.h" |
29 #include "pidginiconname.h" |
| 34 |
|
| 35 #include "pidginstatusprimitivechooser.h" |
|
| 36 #include "pidginstatusprimitivestore.h" |
|
| 37 |
|
| 38 /* |
|
| 39 * TODO: Should attach to the account-deleted and account-added signals |
|
| 40 * and update the GtkListStores in any StatusEditor windows that |
|
| 41 * may be open. |
|
| 42 */ |
|
| 43 |
|
| 44 /* |
|
| 45 * These are used for the GtkTreeView when you're scrolling through |
|
| 46 * all your saved statuses. |
|
| 47 */ |
|
| 48 enum |
|
| 49 { |
|
| 50 STATUS_WINDOW_COLUMN_TITLE, |
|
| 51 STATUS_WINDOW_COLUMN_TYPE, |
|
| 52 STATUS_WINDOW_COLUMN_MESSAGE, |
|
| 53 /** A hidden column containing a pointer to the editor for this saved status. */ |
|
| 54 STATUS_WINDOW_COLUMN_WINDOW, |
|
| 55 STATUS_WINDOW_COLUMN_ICON, |
|
| 56 STATUS_WINDOW_NUM_COLUMNS |
|
| 57 }; |
|
| 58 |
|
| 59 enum { |
|
| 60 STATUS_RESPONSE_USE = 1, |
|
| 61 STATUS_RESPONSE_ADD, |
|
| 62 STATUS_RESPONSE_MODIFY, |
|
| 63 STATUS_RESPONSE_DELETE, |
|
| 64 STATUS_RESPONSE_SAVE, |
|
| 65 STATUS_RESPONSE_SAVE_AND_USE, |
|
| 66 }; |
|
| 67 |
|
| 68 /* |
|
| 69 * These are used for the GtkTreeView containing the list of accounts |
|
| 70 * at the bottom of the window when you're editing a particular |
|
| 71 * saved status. |
|
| 72 */ |
|
| 73 enum |
|
| 74 { |
|
| 75 /* A hidden column containing a pointer to the PurpleAccount. */ |
|
| 76 STATUS_EDITOR_COLUMN_ACCOUNT, |
|
| 77 /* A hidden column containing a pointer to the editor for this substatus. */ |
|
| 78 STATUS_EDITOR_COLUMN_WINDOW, |
|
| 79 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, |
|
| 80 STATUS_EDITOR_COLUMN_ICON, |
|
| 81 STATUS_EDITOR_COLUMN_USERNAME, |
|
| 82 /* A hidden column containing the ID of this PurpleStatusType. */ |
|
| 83 STATUS_EDITOR_COLUMN_STATUS_ID, |
|
| 84 STATUS_EDITOR_COLUMN_STATUS_NAME, |
|
| 85 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, |
|
| 86 STATUS_EDITOR_COLUMN_STATUS_ICON, |
|
| 87 STATUS_EDITOR_NUM_COLUMNS |
|
| 88 }; |
|
| 89 |
|
| 90 /* |
|
| 91 * These are used in the GtkComboBox to select the specific PurpleStatusType |
|
| 92 * when setting a (sub)status for a particular saved status. |
|
| 93 */ |
|
| 94 enum |
|
| 95 { |
|
| 96 STATUS_COLUMN_ICON, |
|
| 97 /** A hidden column containing the ID of this PurpleStatusType. */ |
|
| 98 STATUS_COLUMN_STATUS_ID, |
|
| 99 STATUS_COLUMN_STATUS_NAME, |
|
| 100 STATUS_NUM_COLUMNS |
|
| 101 }; |
|
| 102 |
|
| 103 typedef struct |
|
| 104 { |
|
| 105 GtkWidget *window; |
|
| 106 GtkListStore *model; |
|
| 107 GtkWidget *treeview; |
|
| 108 GtkWidget *use_button; |
|
| 109 GtkWidget *modify_button; |
|
| 110 GtkWidget *delete_button; |
|
| 111 } StatusWindow; |
|
| 112 |
|
| 113 typedef struct |
|
| 114 { |
|
| 115 GtkWidget *window; |
|
| 116 GtkListStore *model; |
|
| 117 GtkWidget *treeview; |
|
| 118 GtkWidget *saveanduse_button; |
|
| 119 GtkWidget *save_button; |
|
| 120 |
|
| 121 gchar *original_title; |
|
| 122 GtkEntry *title; |
|
| 123 GtkComboBox *type; |
|
| 124 GtkWidget *message_view; |
|
| 125 GtkTextBuffer *message_buffer; |
|
| 126 } StatusEditor; |
|
| 127 |
|
| 128 typedef struct |
|
| 129 { |
|
| 130 StatusEditor *status_editor; |
|
| 131 PurpleAccount *account; |
|
| 132 |
|
| 133 GtkWidget *window; |
|
| 134 GtkComboBox *box; |
|
| 135 GtkWidget *message_view; |
|
| 136 GtkTextBuffer *message_buffer; |
|
| 137 } SubStatusEditor; |
|
| 138 |
|
| 139 static StatusWindow *status_window = NULL; |
|
| 140 |
|
| 141 |
|
| 142 /************************************************************************** |
|
| 143 * Status window |
|
| 144 **************************************************************************/ |
|
| 145 |
|
| 146 static gboolean |
|
| 147 status_window_find_savedstatus(GtkTreeIter *iter, const char *title) |
|
| 148 { |
|
| 149 GtkTreeModel *model; |
|
| 150 char *cur; |
|
| 151 |
|
| 152 if ((status_window == NULL) || (title == NULL)) |
|
| 153 return FALSE; |
|
| 154 |
|
| 155 model = GTK_TREE_MODEL(status_window->model); |
|
| 156 |
|
| 157 if (!gtk_tree_model_get_iter_first(model, iter)) |
|
| 158 return FALSE; |
|
| 159 |
|
| 160 do { |
|
| 161 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); |
|
| 162 if (purple_strequal(title, cur)) |
|
| 163 { |
|
| 164 g_free(cur); |
|
| 165 return TRUE; |
|
| 166 } |
|
| 167 g_free(cur); |
|
| 168 } while (gtk_tree_model_iter_next(model, iter)); |
|
| 169 |
|
| 170 return FALSE; |
|
| 171 } |
|
| 172 |
|
| 173 static gboolean |
|
| 174 status_window_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) |
|
| 175 { |
|
| 176 StatusWindow *dialog = user_data; |
|
| 177 |
|
| 178 dialog->window = NULL; |
|
| 179 pidgin_status_window_hide(); |
|
| 180 |
|
| 181 return FALSE; |
|
| 182 } |
|
| 183 |
|
| 184 static void |
|
| 185 status_window_use(StatusWindow *dialog) |
|
| 186 { |
|
| 187 GtkTreeSelection *selection; |
|
| 188 GtkTreeIter iter; |
|
| 189 GList *list = NULL; |
|
| 190 int num_selected = 0; |
|
| 191 |
|
| 192 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); |
|
| 193 |
|
| 194 num_selected = gtk_tree_selection_count_selected_rows(selection); |
|
| 195 if (num_selected != 1) |
|
| 196 /* |
|
| 197 * This shouldn't happen because the "Use" button should have |
|
| 198 * been grayed out. Oh well. |
|
| 199 */ |
|
| 200 return; |
|
| 201 |
|
| 202 list = gtk_tree_selection_get_selected_rows(selection, NULL); |
|
| 203 |
|
| 204 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), |
|
| 205 &iter, list->data)) |
|
| 206 { |
|
| 207 gchar *title; |
|
| 208 PurpleSavedStatus *saved_status; |
|
| 209 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, |
|
| 210 STATUS_WINDOW_COLUMN_TITLE, &title, |
|
| 211 -1); |
|
| 212 saved_status = purple_savedstatus_find(title); |
|
| 213 g_free(title); |
|
| 214 purple_savedstatus_activate(saved_status); |
|
| 215 } |
|
| 216 |
|
| 217 g_list_free_full(list, (GDestroyNotify)gtk_tree_path_free); |
|
| 218 } |
|
| 219 |
|
| 220 static void |
|
| 221 status_window_modify_foreach(GtkTreeModel *model, GtkTreePath *path, |
|
| 222 GtkTreeIter *iter, gpointer user_data) |
|
| 223 { |
|
| 224 gchar *title; |
|
| 225 PurpleSavedStatus *saved_status; |
|
| 226 |
|
| 227 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); |
|
| 228 saved_status = purple_savedstatus_find(title); |
|
| 229 g_free(title); |
|
| 230 pidgin_status_editor_show(TRUE, saved_status); |
|
| 231 } |
|
| 232 |
|
| 233 static void |
|
| 234 status_window_modify(StatusWindow *dialog) { |
|
| 235 GtkTreeSelection *selection; |
|
| 236 |
|
| 237 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); |
|
| 238 |
|
| 239 gtk_tree_selection_selected_foreach(selection, |
|
| 240 status_window_modify_foreach, NULL); |
|
| 241 } |
|
| 242 |
|
| 243 static void |
|
| 244 status_window_delete_cancel_cb(gpointer data) |
|
| 245 { |
|
| 246 GList *sel_titles = data; |
|
| 247 g_list_free_full(sel_titles, g_free); |
|
| 248 } |
|
| 249 |
|
| 250 static void |
|
| 251 status_window_delete_confirm_cb(gpointer data) |
|
| 252 { |
|
| 253 GtkTreeIter iter; |
|
| 254 GList *sel_titles = data, *l; |
|
| 255 char *title; |
|
| 256 |
|
| 257 for (l = sel_titles; l != NULL; l = l->next) { |
|
| 258 title = l->data; |
|
| 259 if (purple_savedstatus_find(title) != purple_savedstatus_get_current()) { |
|
| 260 if (status_window_find_savedstatus(&iter, title)) |
|
| 261 gtk_list_store_remove(status_window->model, &iter); |
|
| 262 purple_savedstatus_delete(title); |
|
| 263 } |
|
| 264 g_free(title); |
|
| 265 } |
|
| 266 g_list_free(sel_titles); |
|
| 267 } |
|
| 268 |
|
| 269 static void |
|
| 270 status_window_delete(StatusWindow *dialog) { |
|
| 271 GtkTreeIter iter; |
|
| 272 GtkTreeSelection *selection; |
|
| 273 GList *sel_paths, *l, *sel_titles = NULL; |
|
| 274 GtkTreeModel *model = GTK_TREE_MODEL(dialog->model); |
|
| 275 char *title; |
|
| 276 gpointer handle; |
|
| 277 |
|
| 278 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); |
|
| 279 sel_paths = gtk_tree_selection_get_selected_rows(selection, NULL); |
|
| 280 |
|
| 281 /* This is ugly because we're not allowed to modify the model from within |
|
| 282 * gtk_tree_selection_selected_foreach() and the GtkTreePaths can become invalid |
|
| 283 * when something is removed from the model. The selection can also change while |
|
| 284 * the request dialog is displayed, so we need to capture the selected rows at this time. */ |
|
| 285 |
|
| 286 for (l = sel_paths; l != NULL; l = l->next) { |
|
| 287 if (gtk_tree_model_get_iter(model, &iter, l->data)) { |
|
| 288 gtk_tree_model_get(model, &iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); |
|
| 289 sel_titles = g_list_prepend(sel_titles, title); |
|
| 290 } |
|
| 291 gtk_tree_path_free(l->data); |
|
| 292 } |
|
| 293 g_list_free(sel_paths); |
|
| 294 |
|
| 295 g_return_if_fail(sel_titles != NULL); |
|
| 296 if (!sel_titles->next) { |
|
| 297 title = g_strdup_printf(_("Are you sure you want to delete %s?"), |
|
| 298 (const gchar *)sel_titles->data); |
|
| 299 handle = purple_savedstatus_find(sel_titles->data); |
|
| 300 } else { |
|
| 301 title = g_strdup(_("Are you sure you want to delete the selected saved statuses?")); |
|
| 302 handle = dialog; |
|
| 303 } |
|
| 304 |
|
| 305 purple_request_action(handle, NULL, title, NULL, 0, |
|
| 306 NULL, |
|
| 307 sel_titles, 2, |
|
| 308 _("Delete"), status_window_delete_confirm_cb, |
|
| 309 _("Cancel"), status_window_delete_cancel_cb); |
|
| 310 |
|
| 311 g_free(title); |
|
| 312 } |
|
| 313 |
|
| 314 static void |
|
| 315 status_selected_cb(GtkTreeSelection *sel, gpointer user_data) |
|
| 316 { |
|
| 317 StatusWindow *dialog = user_data; |
|
| 318 GList *sel_paths, *tmp; |
|
| 319 gboolean can_use = TRUE, can_delete = TRUE; |
|
| 320 int num_selected; |
|
| 321 GtkTreeModel *model = GTK_TREE_MODEL(dialog->model); |
|
| 322 |
|
| 323 sel_paths = gtk_tree_selection_get_selected_rows(sel, NULL); |
|
| 324 |
|
| 325 for (tmp = sel_paths, num_selected = 0; tmp; tmp = tmp->next, num_selected++) { |
|
| 326 GtkTreeIter iter; |
|
| 327 char *title; |
|
| 328 |
|
| 329 if (gtk_tree_model_get_iter(model, &iter, tmp->data)) { |
|
| 330 gtk_tree_model_get(model, &iter, |
|
| 331 STATUS_WINDOW_COLUMN_TITLE, &title, -1); |
|
| 332 if (purple_savedstatus_find(title) == purple_savedstatus_get_current()) { |
|
| 333 can_use = can_delete = FALSE; |
|
| 334 } |
|
| 335 |
|
| 336 g_free(title); |
|
| 337 } |
|
| 338 |
|
| 339 gtk_tree_path_free(tmp->data); |
|
| 340 } |
|
| 341 |
|
| 342 gtk_widget_set_sensitive(dialog->use_button, (num_selected == 1) && can_use); |
|
| 343 gtk_widget_set_sensitive(dialog->modify_button, (num_selected > 0)); |
|
| 344 gtk_widget_set_sensitive(dialog->delete_button, num_selected > 0 && can_delete); |
|
| 345 |
|
| 346 g_list_free(sel_paths); |
|
| 347 } |
|
| 348 |
|
| 349 static void |
|
| 350 add_status_to_saved_status_list(GtkListStore *model, PurpleSavedStatus *saved_status) |
|
| 351 { |
|
| 352 GtkTreeIter iter; |
|
| 353 const char *title; |
|
| 354 const char *type; |
|
| 355 const gchar *icon; |
|
| 356 char *message; |
|
| 357 |
|
| 358 if (purple_savedstatus_is_transient(saved_status)) |
|
| 359 return; |
|
| 360 |
|
| 361 title = purple_savedstatus_get_title(saved_status); |
|
| 362 type = purple_primitive_get_name_from_type(purple_savedstatus_get_primitive_type(saved_status)); |
|
| 363 message = purple_markup_strip_html(purple_savedstatus_get_message(saved_status)); |
|
| 364 icon = pidgin_icon_name_from_status_primitive(purple_savedstatus_get_primitive_type(saved_status), NULL); |
|
| 365 |
|
| 366 gtk_list_store_append(model, &iter); |
|
| 367 gtk_list_store_set(model, &iter, |
|
| 368 STATUS_WINDOW_COLUMN_ICON, icon, |
|
| 369 STATUS_WINDOW_COLUMN_TITLE, title, |
|
| 370 STATUS_WINDOW_COLUMN_TYPE, type, |
|
| 371 STATUS_WINDOW_COLUMN_MESSAGE, message, |
|
| 372 -1); |
|
| 373 g_free(message); |
|
| 374 } |
|
| 375 |
|
| 376 static void |
|
| 377 populate_saved_status_list(StatusWindow *dialog) |
|
| 378 { |
|
| 379 GList *saved_statuses; |
|
| 380 |
|
| 381 gtk_list_store_clear(dialog->model); |
|
| 382 |
|
| 383 for (saved_statuses = purple_savedstatuses_get_all(); saved_statuses != NULL; |
|
| 384 saved_statuses = g_list_next(saved_statuses)) |
|
| 385 { |
|
| 386 add_status_to_saved_status_list(dialog->model, saved_statuses->data); |
|
| 387 } |
|
| 388 } |
|
| 389 |
|
| 390 static gboolean |
|
| 391 search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) |
|
| 392 { |
|
| 393 gboolean result; |
|
| 394 char *haystack; |
|
| 395 |
|
| 396 gtk_tree_model_get(model, iter, column, &haystack, -1); |
|
| 397 |
|
| 398 result = (purple_strcasestr(haystack, key) == NULL); |
|
| 399 |
|
| 400 g_free(haystack); |
|
| 401 |
|
| 402 return result; |
|
| 403 } |
|
| 404 |
|
| 405 static void |
|
| 406 savedstatus_activated_cb(GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column, StatusWindow *dialog) |
|
| 407 { |
|
| 408 status_window_use(dialog); |
|
| 409 pidgin_status_window_hide(); |
|
| 410 } |
|
| 411 |
|
| 412 static void |
|
| 413 saved_status_updated_cb(PurpleSavedStatus *status, StatusWindow *sw) |
|
| 414 { |
|
| 415 populate_saved_status_list(sw); |
|
| 416 } |
|
| 417 |
|
| 418 static GtkWidget * |
|
| 419 create_saved_status_list(StatusWindow *dialog) |
|
| 420 { |
|
| 421 GtkWidget *treeview; |
|
| 422 GtkTreeSelection *sel; |
|
| 423 GtkTreeViewColumn *column; |
|
| 424 GtkCellRenderer *renderer; |
|
| 425 |
|
| 426 /* Create the list model */ |
|
| 427 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, |
|
| 428 G_TYPE_STRING, |
|
| 429 G_TYPE_STRING, |
|
| 430 G_TYPE_STRING, |
|
| 431 G_TYPE_POINTER, |
|
| 432 G_TYPE_STRING); |
|
| 433 |
|
| 434 /* Create the treeview */ |
|
| 435 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); |
|
| 436 dialog->treeview = treeview; |
|
| 437 g_signal_connect(G_OBJECT(treeview), "row-activated", |
|
| 438 G_CALLBACK(savedstatus_activated_cb), dialog); |
|
| 439 |
|
| 440 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); |
|
| 441 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); |
|
| 442 g_signal_connect(G_OBJECT(sel), "changed", |
|
| 443 G_CALLBACK(status_selected_cb), dialog); |
|
| 444 |
|
| 445 /* Add columns */ |
|
| 446 column = gtk_tree_view_column_new(); |
|
| 447 gtk_tree_view_column_set_title(column, _("Title")); |
|
| 448 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 449 gtk_tree_view_column_set_min_width(column, 100); |
|
| 450 gtk_tree_view_column_set_sort_column_id(column, |
|
| 451 STATUS_WINDOW_COLUMN_TITLE); |
|
| 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_TITLE); |
|
| 457 g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
|
| 458 |
|
| 459 column = gtk_tree_view_column_new(); |
|
| 460 gtk_tree_view_column_set_title(column, _("Type")); |
|
| 461 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 462 gtk_tree_view_column_set_sort_column_id(column, |
|
| 463 STATUS_WINDOW_COLUMN_TYPE); |
|
| 464 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); |
|
| 465 renderer = gtk_cell_renderer_pixbuf_new(); |
|
| 466 gtk_tree_view_column_pack_start(column, renderer, TRUE); |
|
| 467 gtk_tree_view_column_add_attribute(column, renderer, "icon-name", |
|
| 468 STATUS_WINDOW_COLUMN_ICON); |
|
| 469 renderer = gtk_cell_renderer_text_new(); |
|
| 470 gtk_tree_view_column_pack_start(column, renderer, TRUE); |
|
| 471 gtk_tree_view_column_add_attribute(column, renderer, "text", |
|
| 472 STATUS_WINDOW_COLUMN_TYPE); |
|
| 473 |
|
| 474 column = gtk_tree_view_column_new(); |
|
| 475 gtk_tree_view_column_set_title(column, _("Message")); |
|
| 476 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 477 gtk_tree_view_column_set_sort_column_id(column, |
|
| 478 STATUS_WINDOW_COLUMN_MESSAGE); |
|
| 479 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); |
|
| 480 renderer = gtk_cell_renderer_text_new(); |
|
| 481 gtk_tree_view_column_pack_start(column, renderer, TRUE); |
|
| 482 gtk_tree_view_column_add_attribute(column, renderer, "text", |
|
| 483 STATUS_WINDOW_COLUMN_MESSAGE); |
|
| 484 g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
|
| 485 |
|
| 486 /* Enable CTRL+F searching */ |
|
| 487 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), STATUS_WINDOW_COLUMN_TITLE); |
|
| 488 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), search_func, NULL, NULL); |
|
| 489 |
|
| 490 /* Sort the title column by default */ |
|
| 491 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->model), |
|
| 492 STATUS_WINDOW_COLUMN_TITLE, |
|
| 493 GTK_SORT_ASCENDING); |
|
| 494 |
|
| 495 /* Populate list */ |
|
| 496 populate_saved_status_list(dialog); |
|
| 497 |
|
| 498 gtk_widget_show_all(treeview); |
|
| 499 |
|
| 500 return pidgin_make_scrollable(treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1); |
|
| 501 } |
|
| 502 |
|
| 503 static void |
|
| 504 response_cb(GtkDialog *dialog, gint response_id, gpointer data) { |
|
| 505 StatusWindow *window = data; |
|
| 506 |
|
| 507 switch(response_id) { |
|
| 508 case STATUS_RESPONSE_USE: |
|
| 509 status_window_use(window); |
|
| 510 break; |
|
| 511 case STATUS_RESPONSE_ADD: |
|
| 512 pidgin_status_editor_show(FALSE, NULL); |
|
| 513 break; |
|
| 514 case STATUS_RESPONSE_MODIFY: |
|
| 515 status_window_modify(window); |
|
| 516 break; |
|
| 517 case STATUS_RESPONSE_DELETE: |
|
| 518 status_window_delete(window); |
|
| 519 break; |
|
| 520 case GTK_RESPONSE_CLOSE: |
|
| 521 pidgin_status_window_hide(); |
|
| 522 break; |
|
| 523 default: |
|
| 524 break; |
|
| 525 } |
|
| 526 } |
|
| 527 |
|
| 528 static void |
|
| 529 current_status_changed(PurpleSavedStatus *old, PurpleSavedStatus *new_status, |
|
| 530 StatusWindow *dialog) |
|
| 531 { |
|
| 532 status_selected_cb(gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)), dialog); |
|
| 533 } |
|
| 534 |
|
| 535 void |
|
| 536 pidgin_status_window_show(void) |
|
| 537 { |
|
| 538 StatusWindow *dialog; |
|
| 539 GtkWidget *list; |
|
| 540 GtkWidget *vbox; |
|
| 541 GtkWidget *win; |
|
| 542 |
|
| 543 if (status_window != NULL) |
|
| 544 { |
|
| 545 gtk_window_present(GTK_WINDOW(status_window->window)); |
|
| 546 return; |
|
| 547 } |
|
| 548 |
|
| 549 status_window = dialog = g_new0(StatusWindow, 1); |
|
| 550 |
|
| 551 dialog->window = win = pidgin_dialog_new(_("Saved Statuses"), 12, "statuses", TRUE); |
|
| 552 gtk_window_set_default_size(GTK_WINDOW(win), 550, 250); |
|
| 553 |
|
| 554 g_signal_connect(win, "delete_event", G_CALLBACK(status_window_destroy_cb), |
|
| 555 dialog); |
|
| 556 g_signal_connect(win, "response", G_CALLBACK(response_cb), dialog); |
|
| 557 |
|
| 558 /* Setup the vbox */ |
|
| 559 vbox = gtk_dialog_get_content_area(GTK_DIALOG(win)); |
|
| 560 gtk_box_set_spacing(GTK_BOX(vbox), 12); |
|
| 561 |
|
| 562 /* List of saved status states */ |
|
| 563 list = create_saved_status_list(dialog); |
|
| 564 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); |
|
| 565 |
|
| 566 /* Add our buttons */ |
|
| 567 dialog->use_button = gtk_dialog_add_button(GTK_DIALOG(win), _("_Use"), |
|
| 568 STATUS_RESPONSE_USE); |
|
| 569 gtk_widget_set_sensitive(dialog->use_button, FALSE); |
|
| 570 |
|
| 571 gtk_dialog_add_button(GTK_DIALOG(win), _("_Add"), STATUS_RESPONSE_ADD); |
|
| 572 |
|
| 573 dialog->modify_button = gtk_dialog_add_button(GTK_DIALOG(win), |
|
| 574 _("_Modify"), |
|
| 575 STATUS_RESPONSE_MODIFY); |
|
| 576 gtk_widget_set_sensitive(dialog->modify_button, FALSE); |
|
| 577 |
|
| 578 dialog->delete_button = gtk_dialog_add_button(GTK_DIALOG(win), _("Delete"), |
|
| 579 STATUS_RESPONSE_DELETE); |
|
| 580 gtk_widget_set_sensitive(dialog->delete_button, FALSE); |
|
| 581 |
|
| 582 gtk_dialog_add_button(GTK_DIALOG(win), _("Close"), GTK_RESPONSE_CLOSE); |
|
| 583 |
|
| 584 purple_signal_connect(purple_savedstatuses_get_handle(), |
|
| 585 "savedstatus-changed", status_window, |
|
| 586 G_CALLBACK(current_status_changed), dialog); |
|
| 587 purple_signal_connect(purple_savedstatuses_get_handle(), |
|
| 588 "savedstatus-added", status_window, |
|
| 589 G_CALLBACK(saved_status_updated_cb), dialog); |
|
| 590 purple_signal_connect(purple_savedstatuses_get_handle(), |
|
| 591 "savedstatus-deleted", status_window, |
|
| 592 G_CALLBACK(saved_status_updated_cb), dialog); |
|
| 593 purple_signal_connect(purple_savedstatuses_get_handle(), |
|
| 594 "savedstatus-modified", status_window, |
|
| 595 G_CALLBACK(saved_status_updated_cb), dialog); |
|
| 596 |
|
| 597 gtk_widget_show_all(win); |
|
| 598 } |
|
| 599 |
|
| 600 void |
|
| 601 pidgin_status_window_hide(void) |
|
| 602 { |
|
| 603 if (status_window == NULL) |
|
| 604 return; |
|
| 605 |
|
| 606 if (status_window->window != NULL) |
|
| 607 gtk_widget_destroy(status_window->window); |
|
| 608 |
|
| 609 purple_request_close_with_handle(status_window); |
|
| 610 purple_notify_close_with_handle(status_window); |
|
| 611 purple_signals_disconnect_by_handle(status_window); |
|
| 612 g_object_unref(G_OBJECT(status_window->model)); |
|
| 613 g_free(status_window); |
|
| 614 status_window = NULL; |
|
| 615 } |
|
| 616 |
|
| 617 |
|
| 618 /************************************************************************** |
|
| 619 * Status editor |
|
| 620 **************************************************************************/ |
|
| 621 |
|
| 622 static void substatus_editor_cancel(SubStatusEditor *dialog); |
|
| 623 |
|
| 624 static void |
|
| 625 status_editor_remove_dialog(StatusEditor *dialog) |
|
| 626 { |
|
| 627 GtkTreeModel *model; |
|
| 628 GtkTreeIter iter; |
|
| 629 |
|
| 630 /* Remove the reference to this dialog from our parent's list store */ |
|
| 631 if (status_window_find_savedstatus(&iter, dialog->original_title)) |
|
| 632 { |
|
| 633 gtk_list_store_set(status_window->model, &iter, |
|
| 634 STATUS_WINDOW_COLUMN_WINDOW, NULL, |
|
| 635 -1); |
|
| 636 } |
|
| 637 |
|
| 638 /* Close any substatus editors that may be open */ |
|
| 639 model = GTK_TREE_MODEL(dialog->model); |
|
| 640 if (gtk_tree_model_get_iter_first(model, &iter)) |
|
| 641 { |
|
| 642 do { |
|
| 643 SubStatusEditor *substatus_dialog; |
|
| 644 |
|
| 645 gtk_tree_model_get(model, &iter, |
|
| 646 STATUS_EDITOR_COLUMN_WINDOW, &substatus_dialog, |
|
| 647 -1); |
|
| 648 if (substatus_dialog != NULL) |
|
| 649 { |
|
| 650 gtk_list_store_set(dialog->model, &iter, |
|
| 651 STATUS_EDITOR_COLUMN_WINDOW, NULL, |
|
| 652 -1); |
|
| 653 substatus_editor_cancel(substatus_dialog); |
|
| 654 } |
|
| 655 } while (gtk_tree_model_iter_next(model, &iter)); |
|
| 656 } |
|
| 657 } |
|
| 658 |
|
| 659 |
|
| 660 static void |
|
| 661 status_editor_destroy_cb(GtkWidget *widget, gpointer user_data) |
|
| 662 { |
|
| 663 StatusEditor *dialog = user_data; |
|
| 664 |
|
| 665 status_editor_remove_dialog(dialog); |
|
| 666 g_free(dialog->original_title); |
|
| 667 g_object_unref(G_OBJECT(dialog->model)); |
|
| 668 g_free(dialog); |
|
| 669 } |
|
| 670 |
|
| 671 static void |
|
| 672 status_editor_ok(StatusEditor *dialog, gboolean use, gboolean save) { |
|
| 673 const char *title; |
|
| 674 PurpleStatusPrimitive type; |
|
| 675 char *message, *unformatted; |
|
| 676 PurpleSavedStatus *saved_status = NULL; |
|
| 677 GtkTreeModel *model; |
|
| 678 GtkTreeIter iter; |
|
| 679 |
|
| 680 title = gtk_entry_get_text(dialog->title); |
|
| 681 |
|
| 682 /* |
|
| 683 * If we're saving this status, and the title is already taken |
|
| 684 * then show an error dialog and don't do anything. |
|
| 685 */ |
|
| 686 if ((save) && (purple_savedstatus_find(title) != NULL) && |
|
| 687 ((dialog->original_title == NULL) || (!purple_strequal(title, dialog->original_title)))) |
|
| 688 { |
|
| 689 purple_notify_error(status_window, NULL, _("Title already in use. You must " |
|
| 690 "choose a unique title."), NULL, NULL); |
|
| 691 return; |
|
| 692 } |
|
| 693 |
|
| 694 type = gtk_combo_box_get_active(dialog->type) + (PURPLE_STATUS_UNSET + 1); |
|
| 695 message = talkatu_markup_get_html(dialog->message_buffer, NULL); |
|
| 696 unformatted = purple_markup_strip_html(message); |
|
| 697 |
|
| 698 /* |
|
| 699 * If we're editing an old status, then lookup the old status. |
|
| 700 * Note: It is possible that it has been deleted or renamed |
|
| 701 * or something, and no longer exists. |
|
| 702 */ |
|
| 703 if (dialog->original_title != NULL) |
|
| 704 { |
|
| 705 GtkTreeIter iter; |
|
| 706 |
|
| 707 saved_status = purple_savedstatus_find(dialog->original_title); |
|
| 708 |
|
| 709 if (status_window_find_savedstatus(&iter, dialog->original_title)) |
|
| 710 gtk_list_store_remove(status_window->model, &iter); |
|
| 711 } |
|
| 712 |
|
| 713 if(saved_status == NULL) { |
|
| 714 /* This is a new status */ |
|
| 715 if(save) { |
|
| 716 saved_status = purple_savedstatus_new(title, type); |
|
| 717 } else { |
|
| 718 saved_status = purple_savedstatus_new(NULL, type); |
|
| 719 } |
|
| 720 } else { |
|
| 721 /* Modify the old status */ |
|
| 722 if(!purple_strequal(title, dialog->original_title)) { |
|
| 723 purple_savedstatus_set_title(saved_status, title); |
|
| 724 } |
|
| 725 purple_savedstatus_set_primitive_type(saved_status, type); |
|
| 726 } |
|
| 727 |
|
| 728 if (*unformatted == '\0') |
|
| 729 purple_savedstatus_set_message(saved_status, NULL); |
|
| 730 else |
|
| 731 purple_savedstatus_set_message(saved_status, message); |
|
| 732 |
|
| 733 /* Set any substatuses */ |
|
| 734 model = GTK_TREE_MODEL(dialog->model); |
|
| 735 if (gtk_tree_model_get_iter_first(model, &iter)) |
|
| 736 { |
|
| 737 do { |
|
| 738 PurpleAccount *account; |
|
| 739 gboolean enabled; |
|
| 740 char *id; |
|
| 741 char *message; |
|
| 742 PurpleStatusType *type; |
|
| 743 |
|
| 744 gtk_tree_model_get(model, &iter, |
|
| 745 STATUS_EDITOR_COLUMN_ACCOUNT, &account, |
|
| 746 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &enabled, |
|
| 747 STATUS_EDITOR_COLUMN_STATUS_ID, &id, |
|
| 748 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, &message, |
|
| 749 -1); |
|
| 750 if (enabled) |
|
| 751 { |
|
| 752 type = purple_account_get_status_type(account, id); |
|
| 753 purple_savedstatus_set_substatus(saved_status, account, type, message); |
|
| 754 } |
|
| 755 else |
|
| 756 { |
|
| 757 purple_savedstatus_unset_substatus(saved_status, account); |
|
| 758 } |
|
| 759 g_free(id); |
|
| 760 g_free(message); |
|
| 761 } while (gtk_tree_model_iter_next(model, &iter)); |
|
| 762 } |
|
| 763 |
|
| 764 g_free(message); |
|
| 765 g_free(unformatted); |
|
| 766 |
|
| 767 /* If they clicked on "Save and Use" or "Use," then activate the status */ |
|
| 768 if(use) { |
|
| 769 purple_savedstatus_activate(saved_status); |
|
| 770 } |
|
| 771 |
|
| 772 gtk_widget_destroy(dialog->window); |
|
| 773 } |
|
| 774 |
|
| 775 |
|
| 776 static void |
|
| 777 status_editor_response_cb(GtkDialog *dialog, gint response, gpointer data) { |
|
| 778 StatusEditor *window = data; |
|
| 779 |
|
| 780 switch(response) { |
|
| 781 case GTK_RESPONSE_CLOSE: |
|
| 782 gtk_widget_destroy(window->window); |
|
| 783 break; |
|
| 784 case STATUS_RESPONSE_USE: |
|
| 785 status_editor_ok(window, TRUE, FALSE); |
|
| 786 break; |
|
| 787 case STATUS_RESPONSE_SAVE_AND_USE: |
|
| 788 status_editor_ok(window, TRUE, TRUE); |
|
| 789 break; |
|
| 790 case STATUS_RESPONSE_SAVE: |
|
| 791 status_editor_ok(window, FALSE, TRUE); |
|
| 792 break; |
|
| 793 default: |
|
| 794 break; |
|
| 795 } |
|
| 796 } |
|
| 797 |
|
| 798 static void |
|
| 799 editor_title_changed_cb(GtkWidget *widget, gpointer user_data) |
|
| 800 { |
|
| 801 StatusEditor *dialog = user_data; |
|
| 802 const gchar *text; |
|
| 803 |
|
| 804 text = gtk_entry_get_text(dialog->title); |
|
| 805 |
|
| 806 gtk_widget_set_sensitive(GTK_WIDGET(dialog->saveanduse_button), (*text != '\0')); |
|
| 807 gtk_widget_set_sensitive(GTK_WIDGET(dialog->save_button), (*text != '\0')); |
|
| 808 } |
|
| 809 |
|
| 810 static void edit_substatus(StatusEditor *status_editor, PurpleAccount *account); |
|
| 811 |
|
| 812 static void |
|
| 813 edit_substatus_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data) |
|
| 814 { |
|
| 815 StatusEditor *dialog = user_data; |
|
| 816 GtkTreeIter iter; |
|
| 817 PurpleAccount *account; |
|
| 818 |
|
| 819 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); |
|
| 820 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, |
|
| 821 STATUS_EDITOR_COLUMN_ACCOUNT, &account, |
|
| 822 -1); |
|
| 823 |
|
| 824 edit_substatus(dialog, account); |
|
| 825 } |
|
| 826 |
|
| 827 static void |
|
| 828 status_editor_substatus_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data) |
|
| 829 { |
|
| 830 StatusEditor *dialog = (StatusEditor *)data; |
|
| 831 GtkTreeIter iter; |
|
| 832 gboolean enabled; |
|
| 833 PurpleAccount *account; |
|
| 834 |
|
| 835 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(dialog->model), &iter, path_str); |
|
| 836 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, |
|
| 837 STATUS_EDITOR_COLUMN_ACCOUNT, &account, |
|
| 838 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &enabled, |
|
| 839 -1); |
|
| 840 |
|
| 841 enabled = !enabled; |
|
| 842 |
|
| 843 if (enabled) |
|
| 844 { |
|
| 845 edit_substatus(dialog, account); |
|
| 846 } |
|
| 847 else |
|
| 848 { |
|
| 849 /* Remove the substatus */ |
|
| 850 gtk_list_store_set(dialog->model, &iter, |
|
| 851 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, enabled, |
|
| 852 STATUS_EDITOR_COLUMN_STATUS_ID, NULL, |
|
| 853 STATUS_EDITOR_COLUMN_STATUS_NAME, NULL, |
|
| 854 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, NULL, |
|
| 855 STATUS_EDITOR_COLUMN_STATUS_ICON, NULL, |
|
| 856 -1); |
|
| 857 } |
|
| 858 } |
|
| 859 |
|
| 860 static void |
|
| 861 status_editor_add_columns(StatusEditor *dialog) |
|
| 862 { |
|
| 863 GtkCellRenderer *renderer; |
|
| 864 GtkTreeViewColumn *column; |
|
| 865 |
|
| 866 /* Enable Different status column */ |
|
| 867 renderer = gtk_cell_renderer_toggle_new(); |
|
| 868 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog->treeview), |
|
| 869 -1, _("Different"), |
|
| 870 renderer, |
|
| 871 "active", STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, |
|
| 872 NULL); |
|
| 873 g_signal_connect(G_OBJECT(renderer), "toggled", |
|
| 874 G_CALLBACK(status_editor_substatus_cb), dialog); |
|
| 875 |
|
| 876 /* Username column */ |
|
| 877 column = gtk_tree_view_column_new(); |
|
| 878 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 879 gtk_tree_view_column_set_title(column, _("Username")); |
|
| 880 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); |
|
| 881 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 882 |
|
| 883 /* Icon */ |
|
| 884 renderer = gtk_cell_renderer_pixbuf_new(); |
|
| 885 gtk_tree_view_column_pack_start(column, renderer, FALSE); |
|
| 886 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", |
|
| 887 STATUS_EDITOR_COLUMN_ICON); |
|
| 888 |
|
| 889 /* Username */ |
|
| 890 renderer = gtk_cell_renderer_text_new(); |
|
| 891 gtk_tree_view_column_pack_start(column, renderer, TRUE); |
|
| 892 gtk_tree_view_column_add_attribute(column, renderer, "text", |
|
| 893 STATUS_EDITOR_COLUMN_USERNAME); |
|
| 894 |
|
| 895 /* Status column */ |
|
| 896 column = gtk_tree_view_column_new(); |
|
| 897 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 898 gtk_tree_view_column_set_title(column, _("Status")); |
|
| 899 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); |
|
| 900 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 901 renderer = gtk_cell_renderer_pixbuf_new(); |
|
| 902 gtk_tree_view_column_pack_start(column, renderer, FALSE); |
|
| 903 gtk_tree_view_column_add_attribute(column, renderer, "stock-id", |
|
| 904 STATUS_EDITOR_COLUMN_STATUS_ICON); |
|
| 905 renderer = gtk_cell_renderer_text_new(); |
|
| 906 gtk_tree_view_column_pack_start(column, renderer, TRUE); |
|
| 907 gtk_tree_view_column_add_attribute(column, renderer, "text", |
|
| 908 STATUS_EDITOR_COLUMN_STATUS_NAME); |
|
| 909 |
|
| 910 /* Message column */ |
|
| 911 column = gtk_tree_view_column_new(); |
|
| 912 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 913 gtk_tree_view_column_set_title(column, _("Message")); |
|
| 914 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); |
|
| 915 gtk_tree_view_column_set_resizable(column, TRUE); |
|
| 916 renderer = gtk_cell_renderer_text_new(); |
|
| 917 gtk_tree_view_column_pack_start(column, renderer, TRUE); |
|
| 918 gtk_tree_view_column_add_attribute(column, renderer, "text", |
|
| 919 STATUS_EDITOR_COLUMN_STATUS_MESSAGE); |
|
| 920 |
|
| 921 g_signal_connect(G_OBJECT(dialog->treeview), "row-activated", |
|
| 922 G_CALLBACK(edit_substatus_cb), dialog); |
|
| 923 } |
|
| 924 |
|
| 925 static void |
|
| 926 status_editor_set_account(GtkListStore *store, PurpleAccount *account, |
|
| 927 GtkTreeIter *iter, PurpleSavedStatusSub *substatus) |
|
| 928 { |
|
| 929 GdkPixbuf *pixbuf; |
|
| 930 const char *id = NULL, *name = NULL, *message = NULL; |
|
| 931 PurpleStatusPrimitive prim = PURPLE_STATUS_UNSET; |
|
| 932 |
|
| 933 pixbuf = pidgin_create_protocol_icon(account, PIDGIN_PROTOCOL_ICON_MEDIUM); |
|
| 934 if ((pixbuf != NULL) && !purple_account_is_connected(account)) |
|
| 935 { |
|
| 936 gdk_pixbuf_saturate_and_pixelate(pixbuf, pixbuf, 0.0, FALSE); |
|
| 937 } |
|
| 938 |
|
| 939 if (substatus != NULL) |
|
| 940 { |
|
| 941 const PurpleStatusType *type; |
|
| 942 |
|
| 943 type = purple_savedstatus_substatus_get_status_type(substatus); |
|
| 944 id = purple_status_type_get_id(type); |
|
| 945 name = purple_status_type_get_name(type); |
|
| 946 prim = purple_status_type_get_primitive(type); |
|
| 947 if (purple_status_type_get_attr(type, "message")) |
|
| 948 message = purple_savedstatus_substatus_get_message(substatus); |
|
| 949 } |
|
| 950 |
|
| 951 gtk_list_store_set(store, iter, |
|
| 952 STATUS_EDITOR_COLUMN_ACCOUNT, account, |
|
| 953 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, (substatus != NULL), |
|
| 954 STATUS_EDITOR_COLUMN_ICON, pixbuf, |
|
| 955 STATUS_EDITOR_COLUMN_USERNAME, purple_account_get_username(account), |
|
| 956 STATUS_EDITOR_COLUMN_STATUS_ID, id, |
|
| 957 STATUS_EDITOR_COLUMN_STATUS_NAME, name, |
|
| 958 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message, |
|
| 959 STATUS_EDITOR_COLUMN_STATUS_ICON, pidgin_icon_name_from_status_primitive(prim, NULL), |
|
| 960 -1); |
|
| 961 |
|
| 962 if (pixbuf != NULL) |
|
| 963 g_object_unref(G_OBJECT(pixbuf)); |
|
| 964 } |
|
| 965 |
|
| 966 static void |
|
| 967 status_editor_add_account(StatusEditor *dialog, PurpleAccount *account, |
|
| 968 PurpleSavedStatusSub *substatus) |
|
| 969 { |
|
| 970 GtkTreeIter iter; |
|
| 971 |
|
| 972 gtk_list_store_append(dialog->model, &iter); |
|
| 973 |
|
| 974 status_editor_set_account(dialog->model, account, &iter, substatus); |
|
| 975 } |
|
| 976 |
|
| 977 static void |
|
| 978 status_editor_populate_list(StatusEditor *dialog, PurpleSavedStatus *saved_status) |
|
| 979 { |
|
| 980 GList *iter; |
|
| 981 PurpleAccountManager *manager = NULL; |
|
| 982 PurpleSavedStatusSub *substatus; |
|
| 983 |
|
| 984 gtk_list_store_clear(dialog->model); |
|
| 985 |
|
| 986 manager = purple_account_manager_get_default(); |
|
| 987 iter = purple_account_manager_get_all(manager); |
|
| 988 |
|
| 989 for(; iter != NULL; iter = iter->next) { |
|
| 990 PurpleAccount *account = (PurpleAccount *)iter->data; |
|
| 991 |
|
| 992 if (saved_status != NULL) { |
|
| 993 substatus = purple_savedstatus_get_substatus(saved_status, account); |
|
| 994 } else { |
|
| 995 substatus = NULL; |
|
| 996 } |
|
| 997 |
|
| 998 status_editor_add_account(dialog, account, substatus); |
|
| 999 } |
|
| 1000 } |
|
| 1001 |
|
| 1002 void |
|
| 1003 pidgin_status_editor_show(gboolean edit, PurpleSavedStatus *saved_status) |
|
| 1004 { |
|
| 1005 GtkTreeIter iter; |
|
| 1006 StatusEditor *dialog; |
|
| 1007 GtkSizeGroup *sg; |
|
| 1008 GtkWidget *dbox; |
|
| 1009 GtkWidget *expander; |
|
| 1010 GtkWidget *dropdown; |
|
| 1011 GtkWidget *entry; |
|
| 1012 GtkWidget *editor; |
|
| 1013 GtkWidget *hbox; |
|
| 1014 GtkWidget *vbox; |
|
| 1015 GtkWidget *win; |
|
| 1016 GtkListStore *store; |
|
| 1017 PurpleStatusPrimitive primitive = PURPLE_STATUS_AWAY; |
|
| 1018 |
|
| 1019 if (edit) |
|
| 1020 { |
|
| 1021 g_return_if_fail(saved_status != NULL); |
|
| 1022 g_return_if_fail(!purple_savedstatus_is_transient(saved_status)); |
|
| 1023 } |
|
| 1024 |
|
| 1025 /* Find a possible window for this saved status and present it */ |
|
| 1026 if (edit && status_window_find_savedstatus(&iter, purple_savedstatus_get_title(saved_status))) |
|
| 1027 { |
|
| 1028 gtk_tree_model_get(GTK_TREE_MODEL(status_window->model), &iter, |
|
| 1029 STATUS_WINDOW_COLUMN_WINDOW, &dialog, |
|
| 1030 -1); |
|
| 1031 if (dialog != NULL) |
|
| 1032 { |
|
| 1033 gtk_window_present(GTK_WINDOW(dialog->window)); |
|
| 1034 return; |
|
| 1035 } |
|
| 1036 } |
|
| 1037 |
|
| 1038 dialog = g_new0(StatusEditor, 1); |
|
| 1039 if (edit && status_window_find_savedstatus(&iter, purple_savedstatus_get_title(saved_status))) |
|
| 1040 { |
|
| 1041 gtk_list_store_set(status_window->model, &iter, |
|
| 1042 STATUS_WINDOW_COLUMN_WINDOW, dialog, |
|
| 1043 -1); |
|
| 1044 } |
|
| 1045 |
|
| 1046 if (edit) |
|
| 1047 dialog->original_title = g_strdup(purple_savedstatus_get_title(saved_status)); |
|
| 1048 |
|
| 1049 dialog->window = win = pidgin_dialog_new(_("Status"), 12, "status", TRUE); |
|
| 1050 |
|
| 1051 g_signal_connect(win, "destroy", G_CALLBACK(status_editor_destroy_cb), |
|
| 1052 dialog); |
|
| 1053 g_signal_connect(win, "response", G_CALLBACK(status_editor_response_cb), |
|
| 1054 dialog); |
|
| 1055 |
|
| 1056 /* Setup the vbox */ |
|
| 1057 vbox = gtk_dialog_get_content_area(GTK_DIALOG(win)); |
|
| 1058 gtk_box_set_spacing(GTK_BOX(vbox), 12); |
|
| 1059 |
|
| 1060 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
|
| 1061 |
|
| 1062 /* Title */ |
|
| 1063 entry = gtk_entry_new(); |
|
| 1064 dialog->title = GTK_ENTRY(entry); |
|
| 1065 if ((saved_status != NULL) |
|
| 1066 && !purple_savedstatus_is_transient(saved_status) |
|
| 1067 && (purple_savedstatus_get_title(saved_status) != NULL)) |
|
| 1068 gtk_entry_set_text(GTK_ENTRY(entry), purple_savedstatus_get_title(saved_status)); |
|
| 1069 g_signal_connect(G_OBJECT(entry), "changed", |
|
| 1070 G_CALLBACK(editor_title_changed_cb), dialog); |
|
| 1071 pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Title:"), sg, entry, TRUE, NULL); |
|
| 1072 |
|
| 1073 /* Status type */ |
|
| 1074 if (saved_status != NULL) { |
|
| 1075 primitive = purple_savedstatus_get_primitive_type(saved_status); |
|
| 1076 } |
|
| 1077 |
|
| 1078 store = pidgin_status_primitive_store_new(); |
|
| 1079 dropdown = pidgin_status_primitive_chooser_new(); |
|
| 1080 dialog->type = GTK_COMBO_BOX(dropdown); |
|
| 1081 gtk_combo_box_set_model(GTK_COMBO_BOX(dropdown), GTK_TREE_MODEL(store)); |
|
| 1082 gtk_combo_box_set_active_id(GTK_COMBO_BOX(dropdown), |
|
| 1083 purple_primitive_get_id_from_type(primitive)); |
|
| 1084 pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Status:"), sg, dropdown, TRUE, NULL); |
|
| 1085 |
|
| 1086 /* Status message */ |
|
| 1087 editor = talkatu_editor_new(); |
|
| 1088 |
|
| 1089 dialog->message_view = talkatu_editor_get_input(TALKATU_EDITOR(editor)); |
|
| 1090 hbox = pidgin_add_widget_to_vbox(GTK_BOX(vbox), _("_Message:"), sg, editor, TRUE, NULL); |
|
| 1091 |
|
| 1092 dialog->message_buffer = talkatu_html_buffer_new(); |
|
| 1093 gtk_text_view_set_buffer(GTK_TEXT_VIEW(dialog->message_view), dialog->message_buffer); |
|
| 1094 |
|
| 1095 gtk_container_child_set(GTK_CONTAINER(vbox), hbox, "expand", TRUE, "fill", TRUE, NULL); |
|
| 1096 |
|
| 1097 if ((saved_status != NULL) && (purple_savedstatus_get_message(saved_status) != NULL)) { |
|
| 1098 talkatu_markup_set_html( |
|
| 1099 TALKATU_BUFFER(dialog->message_buffer), |
|
| 1100 purple_savedstatus_get_message(saved_status), |
|
| 1101 -1 |
|
| 1102 ); |
|
| 1103 } |
|
| 1104 |
|
| 1105 /* Different status message expander */ |
|
| 1106 expander = gtk_expander_new_with_mnemonic(_("Use a _different status for some accounts")); |
|
| 1107 gtk_box_pack_start(GTK_BOX(vbox), expander, FALSE, FALSE, 0); |
|
| 1108 |
|
| 1109 /* Setup the box that the expander will cover */ |
|
| 1110 dbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 18); |
|
| 1111 gtk_container_add(GTK_CONTAINER(expander), dbox); |
|
| 1112 |
|
| 1113 /* Create the list model */ |
|
| 1114 dialog->model = gtk_list_store_new(STATUS_EDITOR_NUM_COLUMNS, |
|
| 1115 G_TYPE_POINTER, |
|
| 1116 G_TYPE_POINTER, |
|
| 1117 G_TYPE_BOOLEAN, |
|
| 1118 GDK_TYPE_PIXBUF, |
|
| 1119 G_TYPE_STRING, |
|
| 1120 G_TYPE_STRING, |
|
| 1121 G_TYPE_STRING, |
|
| 1122 G_TYPE_STRING, |
|
| 1123 G_TYPE_STRING); |
|
| 1124 |
|
| 1125 /* Create the treeview */ |
|
| 1126 dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); |
|
| 1127 gtk_widget_set_size_request(dialog->treeview, -1, 150); |
|
| 1128 gtk_box_pack_start(GTK_BOX(dbox), |
|
| 1129 pidgin_make_scrollable(dialog->treeview, GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1), |
|
| 1130 TRUE, TRUE, 0); |
|
| 1131 |
|
| 1132 /* Add columns */ |
|
| 1133 status_editor_add_columns(dialog); |
|
| 1134 |
|
| 1135 /* Populate list */ |
|
| 1136 status_editor_populate_list(dialog, saved_status); |
|
| 1137 |
|
| 1138 /* Expand the treeview if we have substatuses */ |
|
| 1139 gtk_expander_set_expanded(GTK_EXPANDER(expander), |
|
| 1140 (saved_status != NULL) && purple_savedstatus_has_substatuses(saved_status)); |
|
| 1141 |
|
| 1142 /* Buttons */ |
|
| 1143 gtk_dialog_add_button(GTK_DIALOG(win), _("Cancel"), GTK_RESPONSE_CLOSE); |
|
| 1144 gtk_dialog_add_button(GTK_DIALOG(win), _("_Use"), STATUS_RESPONSE_USE); |
|
| 1145 |
|
| 1146 dialog->saveanduse_button = gtk_dialog_add_button(GTK_DIALOG(win), |
|
| 1147 _("Sa_ve and Use"), |
|
| 1148 STATUS_RESPONSE_SAVE_AND_USE); |
|
| 1149 if(dialog->original_title == NULL) { |
|
| 1150 gtk_widget_set_sensitive(dialog->saveanduse_button, FALSE); |
|
| 1151 } |
|
| 1152 |
|
| 1153 dialog->save_button = gtk_dialog_add_button(GTK_DIALOG(win), _("Save"), |
|
| 1154 STATUS_RESPONSE_SAVE); |
|
| 1155 if(dialog->original_title == NULL) { |
|
| 1156 gtk_widget_set_sensitive(dialog->save_button, FALSE); |
|
| 1157 } |
|
| 1158 |
|
| 1159 gtk_widget_show_all(win); |
|
| 1160 g_object_unref(sg); |
|
| 1161 } |
|
| 1162 |
|
| 1163 |
|
| 1164 /************************************************************************** |
|
| 1165 * SubStatus editor |
|
| 1166 **************************************************************************/ |
|
| 1167 |
|
| 1168 static void |
|
| 1169 substatus_selection_changed_cb(GtkComboBox *box, gpointer user_data) |
|
| 1170 { |
|
| 1171 SubStatusEditor *select = user_data; |
|
| 1172 PurpleStatusType *type; |
|
| 1173 PurpleStatusPrimitive primitive; |
|
| 1174 const gchar *id; |
|
| 1175 |
|
| 1176 id = gtk_combo_box_get_active_id(box); |
|
| 1177 if(id == NULL) { |
|
| 1178 return; |
|
| 1179 } |
|
| 1180 |
|
| 1181 primitive = purple_primitive_get_type_from_id(id); |
|
| 1182 if(primitive == PURPLE_STATUS_UNSET) { |
|
| 1183 return; |
|
| 1184 } |
|
| 1185 |
|
| 1186 type = purple_account_get_status_type_with_primitive(select->account, |
|
| 1187 primitive); |
|
| 1188 |
|
| 1189 if(purple_status_type_get_attr(type, "message") == NULL) { |
|
| 1190 gtk_widget_set_sensitive(select->message_view, FALSE); |
|
| 1191 } else { |
|
| 1192 gtk_widget_set_sensitive(select->message_view, TRUE); |
|
| 1193 } |
|
| 1194 } |
|
| 1195 |
|
| 1196 static gboolean |
|
| 1197 status_editor_find_account_in_treemodel(GtkTreeIter *iter, |
|
| 1198 StatusEditor *status_editor, |
|
| 1199 PurpleAccount *account) |
|
| 1200 { |
|
| 1201 GtkTreeModel *model; |
|
| 1202 PurpleAccount *cur; |
|
| 1203 |
|
| 1204 g_return_val_if_fail(status_editor != NULL, FALSE); |
|
| 1205 g_return_val_if_fail(account != NULL, FALSE); |
|
| 1206 |
|
| 1207 model = GTK_TREE_MODEL(status_editor->model); |
|
| 1208 |
|
| 1209 if (!gtk_tree_model_get_iter_first(model, iter)) |
|
| 1210 return FALSE; |
|
| 1211 |
|
| 1212 do { |
|
| 1213 gtk_tree_model_get(model, iter, STATUS_EDITOR_COLUMN_ACCOUNT, &cur, -1); |
|
| 1214 if (cur == account) |
|
| 1215 return TRUE; |
|
| 1216 } while (gtk_tree_model_iter_next(model, iter)); |
|
| 1217 |
|
| 1218 return FALSE; |
|
| 1219 } |
|
| 1220 |
|
| 1221 static void |
|
| 1222 substatus_editor_remove_dialog(SubStatusEditor *dialog) |
|
| 1223 { |
|
| 1224 GtkTreeIter iter; |
|
| 1225 |
|
| 1226 if (status_editor_find_account_in_treemodel(&iter, dialog->status_editor, dialog->account)) |
|
| 1227 { |
|
| 1228 /* Remove the reference to this dialog from our parent's list store */ |
|
| 1229 gtk_list_store_set(dialog->status_editor->model, &iter, |
|
| 1230 STATUS_EDITOR_COLUMN_WINDOW, NULL, |
|
| 1231 -1); |
|
| 1232 } |
|
| 1233 } |
|
| 1234 |
|
| 1235 static void |
|
| 1236 substatus_editor_destroy_cb(GtkWidget *widget, gpointer user_data) |
|
| 1237 { |
|
| 1238 SubStatusEditor *dialog = user_data; |
|
| 1239 |
|
| 1240 substatus_editor_remove_dialog(dialog); |
|
| 1241 g_free(dialog); |
|
| 1242 } |
|
| 1243 |
|
| 1244 static void |
|
| 1245 substatus_editor_cancel(SubStatusEditor *dialog) |
|
| 1246 { |
|
| 1247 gtk_widget_destroy(dialog->window); |
|
| 1248 } |
|
| 1249 |
|
| 1250 |
|
| 1251 static void |
|
| 1252 substatus_editor_ok(SubStatusEditor *dialog) |
|
| 1253 { |
|
| 1254 StatusEditor *status_editor; |
|
| 1255 GtkTreeIter iter; |
|
| 1256 PurpleStatusType *type; |
|
| 1257 PurpleStatusPrimitive primitive; |
|
| 1258 const char *id = NULL; |
|
| 1259 char *message = NULL; |
|
| 1260 const gchar *name = NULL, *icon_name = NULL; |
|
| 1261 |
|
| 1262 id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(dialog->box)); |
|
| 1263 if(id == NULL) { |
|
| 1264 gtk_widget_destroy(dialog->window); |
|
| 1265 return; |
|
| 1266 } |
|
| 1267 |
|
| 1268 primitive = purple_primitive_get_type_from_id(id); |
|
| 1269 if(primitive == PURPLE_STATUS_UNSET) { |
|
| 1270 gtk_widget_destroy(dialog->window); |
|
| 1271 return; |
|
| 1272 } |
|
| 1273 |
|
| 1274 type = purple_account_get_status_type_with_primitive(dialog->account, |
|
| 1275 primitive); |
|
| 1276 if (purple_status_type_get_attr(type, "message") != NULL) { |
|
| 1277 message = talkatu_markup_get_html(dialog->message_buffer, NULL); |
|
| 1278 } |
|
| 1279 name = purple_status_type_get_name(type); |
|
| 1280 icon_name = pidgin_icon_name_from_status_primitive(primitive, NULL); |
|
| 1281 |
|
| 1282 status_editor = dialog->status_editor; |
|
| 1283 |
|
| 1284 if (status_editor_find_account_in_treemodel(&iter, status_editor, dialog->account)) |
|
| 1285 { |
|
| 1286 gtk_list_store_set(status_editor->model, &iter, |
|
| 1287 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, TRUE, |
|
| 1288 STATUS_EDITOR_COLUMN_STATUS_ID, id, |
|
| 1289 STATUS_EDITOR_COLUMN_STATUS_NAME, name, |
|
| 1290 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, message, |
|
| 1291 STATUS_EDITOR_COLUMN_WINDOW, NULL, |
|
| 1292 STATUS_EDITOR_COLUMN_STATUS_ICON, icon_name, |
|
| 1293 -1); |
|
| 1294 } |
|
| 1295 |
|
| 1296 gtk_widget_destroy(dialog->window); |
|
| 1297 g_free(message); |
|
| 1298 } |
|
| 1299 |
|
| 1300 static void |
|
| 1301 substatus_editor_response_cb(GtkDialog *dialog, gint response_id, |
|
| 1302 gpointer data) |
|
| 1303 { |
|
| 1304 SubStatusEditor *editor = data; |
|
| 1305 |
|
| 1306 switch(response_id) { |
|
| 1307 case GTK_RESPONSE_CANCEL: |
|
| 1308 substatus_editor_cancel(editor); |
|
| 1309 break; |
|
| 1310 case GTK_RESPONSE_OK: |
|
| 1311 substatus_editor_ok(editor); |
|
| 1312 break; |
|
| 1313 default: |
|
| 1314 break; |
|
| 1315 } |
|
| 1316 } |
|
| 1317 |
|
| 1318 static void |
|
| 1319 edit_substatus(StatusEditor *status_editor, PurpleAccount *account) |
|
| 1320 { |
|
| 1321 char *tmp; |
|
| 1322 SubStatusEditor *dialog; |
|
| 1323 GtkSizeGroup *sg; |
|
| 1324 GtkWidget *combo; |
|
| 1325 GtkWidget *hbox; |
|
| 1326 GtkWidget *editor; |
|
| 1327 GtkWidget *label; |
|
| 1328 GtkWidget *vbox; |
|
| 1329 GtkWidget *win; |
|
| 1330 GtkTreeIter iter; |
|
| 1331 char *status_id = NULL; |
|
| 1332 char *message = NULL; |
|
| 1333 gboolean parent_dialog_has_substatus = FALSE; |
|
| 1334 GtkListStore *store; |
|
| 1335 PurpleStatusPrimitive primitive = PURPLE_STATUS_AWAY; |
|
| 1336 |
|
| 1337 g_return_if_fail(status_editor != NULL); |
|
| 1338 g_return_if_fail(account != NULL); |
|
| 1339 |
|
| 1340 status_editor_find_account_in_treemodel(&iter, status_editor, account); |
|
| 1341 gtk_tree_model_get(GTK_TREE_MODEL(status_editor->model), &iter, |
|
| 1342 STATUS_EDITOR_COLUMN_WINDOW, &dialog, |
|
| 1343 -1); |
|
| 1344 if (dialog != NULL) |
|
| 1345 { |
|
| 1346 gtk_window_present(GTK_WINDOW(dialog->window)); |
|
| 1347 return; |
|
| 1348 } |
|
| 1349 |
|
| 1350 dialog = g_new0(SubStatusEditor, 1); |
|
| 1351 gtk_list_store_set(status_editor->model, &iter, |
|
| 1352 STATUS_EDITOR_COLUMN_WINDOW, dialog, |
|
| 1353 -1); |
|
| 1354 dialog->status_editor = status_editor; |
|
| 1355 dialog->account = account; |
|
| 1356 |
|
| 1357 tmp = g_strdup_printf(_("Status for %s"), purple_account_get_username(account)); |
|
| 1358 dialog->window = win = pidgin_dialog_new(tmp, 12, "substatus", TRUE); |
|
| 1359 g_free(tmp); |
|
| 1360 |
|
| 1361 g_signal_connect(G_OBJECT(win), "destroy", |
|
| 1362 G_CALLBACK(substatus_editor_destroy_cb), dialog); |
|
| 1363 g_signal_connect(win, "response", G_CALLBACK(substatus_editor_response_cb), |
|
| 1364 dialog); |
|
| 1365 |
|
| 1366 /* Setup the vbox */ |
|
| 1367 vbox = gtk_dialog_get_content_area(GTK_DIALOG(win)); |
|
| 1368 gtk_box_set_spacing(GTK_BOX(vbox), 12); |
|
| 1369 |
|
| 1370 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); |
|
| 1371 |
|
| 1372 /* Status type */ |
|
| 1373 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); |
|
| 1374 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
|
| 1375 |
|
| 1376 label = gtk_label_new_with_mnemonic(_("_Status:")); |
|
| 1377 gtk_label_set_xalign(GTK_LABEL(label), 0); |
|
| 1378 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
|
| 1379 gtk_size_group_add_widget(sg, label); |
|
| 1380 |
|
| 1381 store = pidgin_status_primitive_store_new(); |
|
| 1382 pidgin_status_primitive_store_set_account(PIDGIN_STATUS_PRIMITIVE_STORE(store), |
|
| 1383 account); |
|
| 1384 combo = pidgin_status_primitive_chooser_new(); |
|
| 1385 gtk_combo_box_set_model(GTK_COMBO_BOX(combo), GTK_TREE_MODEL(store)); |
|
| 1386 dialog->box = GTK_COMBO_BOX(combo); |
|
| 1387 |
|
| 1388 g_signal_connect(G_OBJECT(combo), "changed", |
|
| 1389 G_CALLBACK(substatus_selection_changed_cb), dialog); |
|
| 1390 |
|
| 1391 gtk_box_pack_start(GTK_BOX(hbox), combo, FALSE, FALSE, 0); |
|
| 1392 |
|
| 1393 /* Status message */ |
|
| 1394 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6); |
|
| 1395 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); |
|
| 1396 |
|
| 1397 label = gtk_label_new_with_mnemonic(_("_Message:")); |
|
| 1398 gtk_label_set_xalign(GTK_LABEL(label), 0); |
|
| 1399 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
|
| 1400 gtk_size_group_add_widget(sg, label); |
|
| 1401 |
|
| 1402 editor = talkatu_editor_new(); |
|
| 1403 gtk_box_pack_start(GTK_BOX(hbox), editor, TRUE, TRUE, 0); |
|
| 1404 |
|
| 1405 dialog->message_view = talkatu_editor_get_input(TALKATU_EDITOR(editor)); |
|
| 1406 dialog->message_buffer = talkatu_html_buffer_new(); |
|
| 1407 gtk_text_view_set_buffer(GTK_TEXT_VIEW(dialog->message_view), dialog->message_buffer); |
|
| 1408 |
|
| 1409 /* Add the buttons */ |
|
| 1410 gtk_dialog_add_button(GTK_DIALOG(win), _("Cancel"), GTK_RESPONSE_CANCEL); |
|
| 1411 gtk_dialog_add_button(GTK_DIALOG(win), _("Okay"), GTK_RESPONSE_OK); |
|
| 1412 |
|
| 1413 /* Seed the input widgets with the current values */ |
|
| 1414 |
|
| 1415 /* Only look at the saved status if we can't find it in the parent status dialog's substatuses model */ |
|
| 1416 gtk_tree_model_get(GTK_TREE_MODEL(status_editor->model), &iter, |
|
| 1417 STATUS_EDITOR_COLUMN_ENABLE_SUBSTATUS, &parent_dialog_has_substatus, -1); |
|
| 1418 if (parent_dialog_has_substatus) { |
|
| 1419 gtk_tree_model_get(GTK_TREE_MODEL(status_editor->model), &iter, |
|
| 1420 STATUS_EDITOR_COLUMN_STATUS_ID, &status_id, |
|
| 1421 STATUS_EDITOR_COLUMN_STATUS_MESSAGE, &message, -1); |
|
| 1422 } else if (status_editor->original_title != NULL) { |
|
| 1423 PurpleSavedStatus *saved_status = NULL; |
|
| 1424 PurpleSavedStatusSub *substatus = NULL; |
|
| 1425 |
|
| 1426 if ((saved_status = purple_savedstatus_find(status_editor->original_title)) != NULL) { |
|
| 1427 if ((substatus = purple_savedstatus_get_substatus(saved_status, account)) != NULL) { |
|
| 1428 message = (char *)purple_savedstatus_substatus_get_message(substatus); |
|
| 1429 status_id = (char *)purple_status_type_get_id( |
|
| 1430 purple_savedstatus_substatus_get_status_type(substatus)); |
|
| 1431 } |
|
| 1432 } |
|
| 1433 } |
|
| 1434 /* TODO: Else get the generic status type from our parent */ |
|
| 1435 |
|
| 1436 if(status_id != NULL) { |
|
| 1437 PurpleStatus *status = purple_account_get_status(account, status_id); |
|
| 1438 PurpleStatusType *type = purple_status_get_status_type(status); |
|
| 1439 |
|
| 1440 primitive = purple_status_type_get_primitive(type); |
|
| 1441 } |
|
| 1442 |
|
| 1443 gtk_combo_box_set_active_id(GTK_COMBO_BOX(combo), |
|
| 1444 purple_primitive_get_id_from_type(primitive)); |
|
| 1445 |
|
| 1446 if (message) { |
|
| 1447 talkatu_markup_set_html(TALKATU_BUFFER(dialog->message_buffer), message, -1); |
|
| 1448 } |
|
| 1449 |
|
| 1450 if (parent_dialog_has_substatus) { |
|
| 1451 /* These two were gotten from the parent tree model, so they need to be freed */ |
|
| 1452 g_free(status_id); |
|
| 1453 g_free(message); |
|
| 1454 } |
|
| 1455 |
|
| 1456 gtk_widget_show_all(win); |
|
| 1457 g_object_unref(sg); |
|
| 1458 } |
|
| 1459 |
|
| 1460 |
|
| 1461 /************************************************************************** |
|
| 1462 * Utilities * |
|
| 1463 **************************************************************************/ |
|
| 1464 |
30 |
| 1465 enum { |
31 enum { |
| 1466 SS_MENU_ENTRY_TYPE_PRIMITIVE, |
32 SS_MENU_ENTRY_TYPE_PRIMITIVE, |
| 1467 SS_MENU_ENTRY_TYPE_SAVEDSTATUS |
33 SS_MENU_ENTRY_TYPE_SAVEDSTATUS |
| 1468 }; |
34 }; |