Mercurial > pidgin
annotate src/gtksavedstatuses.c @ 11202:ff4884029708
[gaim-migrate @ 13330]
Some compile warning fixes. It's very possible the perl warnings
were caused by some of my changes to the core last week
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Mon, 08 Aug 2005 02:21:57 +0000 |
| parents | 5cda52915a1f |
| children | a511b77a368b |
| 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" | |
| 35 #include "gtkgaim.h" | |
| 36 #include "gtkgaim-disclosure.h" | |
| 37 #include "gtkimhtml.h" | |
| 38 #include "gtkimhtmltoolbar.h" | |
| 39 #include "gtksavedstatuses.h" | |
| 40 #include "gtkstock.h" | |
| 41 #include "gtkutils.h" | |
| 42 | |
| 43 enum | |
| 44 { | |
| 10421 | 45 STATUS_WINDOW_COLUMN_TITLE, |
| 46 STATUS_WINDOW_COLUMN_TYPE, | |
| 47 STATUS_WINDOW_COLUMN_MESSAGE, | |
| 48 STATUS_WINDOW_NUM_COLUMNS | |
| 49 }; | |
| 50 | |
| 51 enum | |
| 52 { | |
| 10418 | 53 STATUS_EDITOR_COLUMN_CUSTOM_STATUS, |
| 54 STATUS_EDITOR_COLUMN_ICON, | |
| 55 STATUS_EDITOR_COLUMN_SCREENNAME, | |
| 56 STATUS_EDITOR_NUM_COLUMNS | |
| 57 }; | |
| 58 | |
| 10421 | 59 typedef struct |
| 10418 | 60 { |
| 10421 | 61 GtkWidget *window; |
| 62 GtkListStore *model; | |
| 63 GtkWidget *treeview; | |
| 64 GtkWidget *modify_button; | |
| 65 GtkWidget *delete_button; | |
| 66 } StatusWindow; | |
| 10418 | 67 |
| 68 typedef struct | |
| 69 { | |
| 70 GtkWidget *window; | |
| 71 GtkListStore *model; | |
| 72 GtkWidget *treeview; | |
| 10420 | 73 GtkWidget *save_button; |
| 74 | |
| 75 gchar *original_title; | |
| 76 GtkEntry *title; | |
| 77 GtkOptionMenu *type; | |
| 78 GtkIMHtml *message; | |
| 10418 | 79 } StatusEditor; |
| 80 | |
| 81 static StatusWindow *status_window = NULL; | |
| 82 | |
| 10421 | 83 |
| 84 /************************************************************************** | |
| 85 * Status window | |
| 86 **************************************************************************/ | |
| 87 | |
| 88 static gboolean | |
| 89 status_window_find_savedstatus(GtkTreeIter *iter, const char *title) | |
| 90 { | |
| 91 GtkTreeModel *model = GTK_TREE_MODEL(status_window->model); | |
| 10439 | 92 char *cur; |
| 10421 | 93 |
| 94 if (!gtk_tree_model_get_iter_first(model, iter)) | |
| 95 return FALSE; | |
| 96 | |
| 97 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
| 98 if (!strcmp(title, cur)) | |
| 10439 | 99 { |
| 100 g_free(cur); | |
| 10421 | 101 return TRUE; |
| 10439 | 102 } |
| 103 g_free(cur); | |
| 10421 | 104 |
| 105 while (gtk_tree_model_iter_next(model, iter)) | |
| 106 { | |
| 107 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &cur, -1); | |
| 108 if (!strcmp(title, cur)) | |
| 10439 | 109 { |
| 110 g_free(cur); | |
| 10421 | 111 return TRUE; |
| 10439 | 112 } |
| 113 g_free(cur); | |
| 10421 | 114 } |
| 115 | |
| 116 return FALSE; | |
| 117 } | |
| 118 | |
| 119 static gboolean | |
| 120 status_window_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
| 121 { | |
| 122 StatusWindow *dialog = user_data; | |
| 123 | |
| 124 dialog->window = NULL; | |
| 125 gaim_gtk_status_window_hide(); | |
| 126 | |
| 127 return FALSE; | |
| 128 } | |
| 129 | |
| 130 static void | |
| 131 status_window_add_cb(GtkButton *button, gpointer user_data) | |
| 132 { | |
| 133 gaim_gtk_status_editor_show(NULL); | |
| 134 } | |
| 135 | |
| 136 static void | |
| 137 status_window_modify_foreach(GtkTreeModel *model, GtkTreePath *path, | |
| 138 GtkTreeIter *iter, gpointer user_data) | |
| 139 { | |
| 10439 | 140 char *title; |
| 10421 | 141 GaimSavedStatus *status; |
| 142 | |
| 143 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
| 144 | |
| 145 status = gaim_savedstatus_find(title); | |
| 10439 | 146 g_free(title); |
| 10421 | 147 gaim_gtk_status_editor_show(status); |
| 148 } | |
| 149 | |
| 150 static void | |
| 151 status_window_modify_cb(GtkButton *button, gpointer user_data) | |
| 152 { | |
| 153 StatusWindow *dialog = user_data; | |
| 154 GtkTreeSelection *selection; | |
| 155 | |
| 156 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
| 157 | |
| 158 gtk_tree_selection_selected_foreach(selection, status_window_modify_foreach, user_data); | |
| 159 } | |
| 160 | |
| 161 static void | |
| 162 status_window_delete_confirm_cb(char *title) | |
| 163 { | |
| 164 GtkTreeIter iter; | |
| 165 | |
| 166 if (status_window_find_savedstatus(&iter, title)) | |
| 167 gtk_list_store_remove(status_window->model, &iter); | |
| 168 | |
| 169 gaim_savedstatus_delete(title); | |
| 170 | |
| 171 g_free(title); | |
| 172 } | |
| 173 | |
| 174 static void | |
| 175 status_window_delete_foreach(GtkTreeModel *model, GtkTreePath *path, | |
| 176 GtkTreeIter *iter, gpointer user_data) | |
| 177 { | |
| 10439 | 178 char *title; |
| 10435 | 179 char *title_escaped, *buf; |
| 10421 | 180 |
| 181 gtk_tree_model_get(model, iter, STATUS_WINDOW_COLUMN_TITLE, &title, -1); | |
| 182 | |
|
10732
c4cb90065e1d
[gaim-migrate @ 12334]
Luke Schierer <lschiere@pidgin.im>
parents:
10591
diff
changeset
|
183 title_escaped = g_markup_escape_text(title, -1); |
| 10435 | 184 buf = g_strdup_printf(_("Are you sure you want to delete %s?"), title_escaped); |
| 185 free(title_escaped); | |
| 10439 | 186 gaim_request_action(NULL, NULL, buf, NULL, 0, title, 2, |
| 10421 | 187 _("Delete"), status_window_delete_confirm_cb, |
| 188 _("Cancel"), g_free); | |
| 189 g_free(buf); | |
| 190 } | |
| 191 | |
| 192 static void | |
| 193 status_window_delete_cb(GtkButton *button, gpointer user_data) | |
| 194 { | |
| 195 StatusWindow *dialog = user_data; | |
| 196 GtkTreeSelection *selection; | |
| 197 | |
| 198 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
| 199 | |
| 200 gtk_tree_selection_selected_foreach(selection, status_window_delete_foreach, user_data); | |
| 201 } | |
| 202 | |
| 203 static void | |
| 204 status_window_close_cb(GtkButton *button, gpointer user_data) | |
| 205 { | |
| 206 gaim_gtk_status_window_hide(); | |
| 207 } | |
| 208 | |
| 209 static void | |
| 210 status_selected_cb(GtkTreeSelection *sel, gpointer user_data) | |
| 211 { | |
| 212 StatusWindow *dialog = user_data; | |
| 213 gboolean selected = FALSE; | |
| 214 | |
| 215 #if GTK_CHECK_VERSION(2,2,0) | |
| 216 selected = (gtk_tree_selection_count_selected_rows(sel) > 0); | |
| 217 #else | |
| 218 gtk_tree_selection_selected_foreach(sel, get_selected_helper, &selected); | |
| 219 #endif | |
| 220 | |
| 221 gtk_widget_set_sensitive(dialog->modify_button, selected); | |
| 222 gtk_widget_set_sensitive(dialog->delete_button, selected); | |
| 223 } | |
| 224 | |
| 225 static void | |
| 226 add_status_to_saved_status_list(GtkListStore *model, GaimSavedStatus *saved_status) | |
| 227 { | |
| 228 GtkTreeIter iter; | |
| 229 const char *title; | |
| 230 const char *type; | |
| 231 char *message; | |
| 232 | |
| 233 title = gaim_savedstatus_get_title(saved_status); | |
| 234 type = gaim_primitive_get_name_from_type(gaim_savedstatus_get_type(saved_status)); | |
| 235 message = gaim_markup_strip_html(gaim_savedstatus_get_message(saved_status)); | |
| 236 | |
| 237 gtk_list_store_append(model, &iter); | |
| 238 gtk_list_store_set(model, &iter, | |
| 239 STATUS_WINDOW_COLUMN_TITLE, title, | |
| 240 STATUS_WINDOW_COLUMN_TYPE, type, | |
| 241 STATUS_WINDOW_COLUMN_MESSAGE, message, | |
| 242 -1); | |
| 243 free(message); | |
| 244 } | |
| 245 | |
| 246 static void | |
| 247 populate_saved_status_list(StatusWindow *dialog) | |
| 248 { | |
| 249 const GList *saved_statuses; | |
| 250 | |
| 251 gtk_list_store_clear(dialog->model); | |
| 252 | |
| 253 for (saved_statuses = gaim_savedstatuses_get_all(); saved_statuses != NULL; | |
| 254 saved_statuses = g_list_next(saved_statuses)) | |
| 255 { | |
| 256 add_status_to_saved_status_list(dialog->model, saved_statuses->data); | |
| 257 } | |
| 258 } | |
| 259 | |
| 10435 | 260 static gboolean |
| 261 search_func(GtkTreeModel *model, gint column, const gchar *key, GtkTreeIter *iter, gpointer search_data) | |
| 262 { | |
| 10439 | 263 gboolean result; |
| 264 char *haystack; | |
| 10435 | 265 |
| 266 gtk_tree_model_get(model, iter, column, &haystack, -1); | |
| 267 | |
| 10439 | 268 result = (gaim_strcasestr(haystack, key) == NULL); |
| 269 | |
| 270 g_free(haystack); | |
| 271 | |
| 272 return result; | |
| 10435 | 273 } |
| 274 | |
| 10421 | 275 static GtkWidget * |
| 276 create_saved_status_list(StatusWindow *dialog) | |
| 277 { | |
| 278 GtkWidget *sw; | |
| 279 GtkWidget *treeview; | |
| 280 GtkTreeSelection *sel; | |
| 281 GtkTreeViewColumn *column; | |
| 282 GtkCellRenderer *renderer; | |
| 283 | |
| 284 /* Create the scrolled window */ | |
| 285 sw = gtk_scrolled_window_new(0, 0); | |
| 286 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
| 287 GTK_POLICY_AUTOMATIC, | |
| 288 GTK_POLICY_ALWAYS); | |
| 289 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
| 290 GTK_SHADOW_IN); | |
| 291 gtk_widget_show(sw); | |
| 292 | |
| 293 /* Create the list model */ | |
| 294 dialog->model = gtk_list_store_new(STATUS_WINDOW_NUM_COLUMNS, | |
| 295 G_TYPE_STRING, | |
| 296 G_TYPE_STRING, | |
| 297 G_TYPE_STRING); | |
| 298 | |
| 299 /* Create the treeview */ | |
| 300 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
| 301 dialog->treeview = treeview; | |
| 302 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
| 303 | |
| 304 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
| 305 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
| 306 g_signal_connect(G_OBJECT(sel), "changed", | |
| 307 G_CALLBACK(status_selected_cb), dialog); | |
| 308 | |
| 309 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
| 310 gtk_widget_show(treeview); | |
| 311 | |
| 312 /* Add columns */ | |
| 313 column = gtk_tree_view_column_new(); | |
| 314 gtk_tree_view_column_set_title(column, _("Title")); | |
| 315 gtk_tree_view_column_set_resizable(column, TRUE); | |
| 316 gtk_tree_view_column_set_sort_column_id(column, | |
| 317 STATUS_WINDOW_COLUMN_TITLE); | |
| 318 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
| 319 renderer = gtk_cell_renderer_text_new(); | |
| 320 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
| 321 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
| 322 STATUS_WINDOW_COLUMN_TITLE); | |
| 323 | |
| 324 column = gtk_tree_view_column_new(); | |
| 325 gtk_tree_view_column_set_title(column, _("Type")); | |
| 326 gtk_tree_view_column_set_resizable(column, TRUE); | |
| 327 gtk_tree_view_column_set_sort_column_id(column, | |
| 328 STATUS_WINDOW_COLUMN_TYPE); | |
| 329 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
| 330 renderer = gtk_cell_renderer_text_new(); | |
| 331 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
| 332 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
| 333 STATUS_WINDOW_COLUMN_TYPE); | |
| 334 | |
| 335 column = gtk_tree_view_column_new(); | |
| 336 gtk_tree_view_column_set_title(column, _("Message")); | |
| 337 gtk_tree_view_column_set_resizable(column, TRUE); | |
| 338 gtk_tree_view_column_set_sort_column_id(column, | |
| 339 STATUS_WINDOW_COLUMN_MESSAGE); | |
| 340 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
| 341 renderer = gtk_cell_renderer_text_new(); | |
| 342 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
| 343 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
| 344 STATUS_WINDOW_COLUMN_MESSAGE); | |
| 10435 | 345 #if GTK_CHECK_VERSION(2,6,0) |
| 10502 | 346 g_object_set(renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); |
| 10435 | 347 #endif |
| 348 | |
| 349 /* Enable CTRL+F searching */ | |
| 350 gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), STATUS_WINDOW_COLUMN_TITLE); | |
| 351 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), search_func, NULL, NULL); | |
| 10421 | 352 |
| 10422 | 353 /* Sort the title column by default */ |
| 354 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->model), | |
| 355 STATUS_WINDOW_COLUMN_TITLE, | |
| 356 GTK_SORT_ASCENDING); | |
| 357 | |
| 10421 | 358 /* Populate list */ |
| 359 populate_saved_status_list(dialog); | |
| 360 | |
| 361 return sw; | |
| 362 } | |
| 363 | |
| 364 static gboolean | |
| 365 configure_cb(GtkWidget *widget, GdkEventConfigure *event, StatusWindow *dialog) | |
| 366 { | |
| 367 if (GTK_WIDGET_VISIBLE(widget)) { | |
| 368 gaim_prefs_set_int("/gaim/gtk/status/dialog/width", event->width); | |
| 369 gaim_prefs_set_int("/gaim/gtk/status/dialog/height", event->height); | |
| 370 } | |
| 371 | |
| 372 return FALSE; | |
| 373 } | |
| 374 | |
| 375 void | |
| 376 gaim_gtk_status_window_show(void) | |
| 377 { | |
| 378 StatusWindow *dialog; | |
| 379 GtkWidget *bbox; | |
| 380 GtkWidget *button; | |
| 381 GtkWidget *list; | |
| 382 GtkWidget *vbox; | |
| 383 GtkWidget *win; | |
| 384 int width, height; | |
| 385 | |
| 386 if (status_window != NULL) { | |
| 387 gtk_window_present(GTK_WINDOW(status_window->window)); | |
| 388 return; | |
| 389 } | |
| 390 | |
| 391 status_window = dialog = g_new0(StatusWindow, 1); | |
| 392 | |
| 393 width = gaim_prefs_get_int("/gaim/gtk/status/dialog/width"); | |
| 394 height = gaim_prefs_get_int("/gaim/gtk/status/dialog/height"); | |
| 395 | |
| 396 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
| 397 gtk_window_set_default_size(GTK_WINDOW(win), width, height); | |
| 398 gtk_window_set_role(GTK_WINDOW(win), "statuses"); | |
| 399 gtk_window_set_title(GTK_WINDOW(win), _("Saved Statuses")); | |
| 400 gtk_container_set_border_width(GTK_CONTAINER(win), 12); | |
| 401 | |
| 402 g_signal_connect(G_OBJECT(win), "delete_event", | |
| 403 G_CALLBACK(status_window_destroy_cb), dialog); | |
| 404 g_signal_connect(G_OBJECT(win), "configure_event", | |
| 405 G_CALLBACK(configure_cb), dialog); | |
| 406 | |
| 407 /* Setup the vbox */ | |
| 408 vbox = gtk_vbox_new(FALSE, 12); | |
| 409 gtk_container_add(GTK_CONTAINER(win), vbox); | |
| 410 gtk_widget_show(vbox); | |
| 411 | |
| 412 /* List of saved status states */ | |
| 413 list = create_saved_status_list(dialog); | |
| 414 gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); | |
| 415 | |
| 416 /* Button box. */ | |
| 417 bbox = gtk_hbutton_box_new(); | |
| 418 gtk_box_set_spacing(GTK_BOX(bbox), 6); | |
| 419 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
| 420 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
| 421 gtk_widget_show(bbox); | |
| 422 | |
| 423 /* Add button */ | |
| 424 button = gtk_button_new_from_stock(GTK_STOCK_ADD); | |
| 425 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
| 426 gtk_widget_show(button); | |
| 427 | |
| 428 g_signal_connect(G_OBJECT(button), "clicked", | |
| 429 G_CALLBACK(status_window_add_cb), dialog); | |
| 430 | |
| 431 /* Modify button */ | |
| 432 button = gtk_button_new_from_stock(GAIM_STOCK_MODIFY); | |
| 433 dialog->modify_button = button; | |
| 434 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
| 435 gtk_widget_set_sensitive(button, FALSE); | |
| 436 gtk_widget_show(button); | |
| 437 | |
| 438 g_signal_connect(G_OBJECT(button), "clicked", | |
| 439 G_CALLBACK(status_window_modify_cb), dialog); | |
| 440 | |
| 441 /* Delete button */ | |
| 442 button = gtk_button_new_from_stock(GTK_STOCK_DELETE); | |
| 443 dialog->delete_button = button; | |
| 444 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
| 445 gtk_widget_set_sensitive(button, FALSE); | |
| 446 gtk_widget_show(button); | |
| 447 | |
| 448 g_signal_connect(G_OBJECT(button), "clicked", | |
| 449 G_CALLBACK(status_window_delete_cb), dialog); | |
| 450 | |
| 451 /* Close button */ | |
| 452 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
| 453 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
| 454 gtk_widget_show(button); | |
| 455 | |
| 456 g_signal_connect(G_OBJECT(button), "clicked", | |
| 457 G_CALLBACK(status_window_close_cb), dialog); | |
| 458 | |
| 459 gtk_widget_show(win); | |
| 460 } | |
| 461 | |
| 462 void | |
| 463 gaim_gtk_status_window_hide(void) | |
| 464 { | |
| 465 if (status_window == NULL) | |
| 466 return; | |
| 467 | |
| 468 if (status_window->window != NULL) | |
| 469 gtk_widget_destroy(status_window->window); | |
| 470 | |
| 471 g_free(status_window); | |
| 472 status_window = NULL; | |
| 473 } | |
| 474 | |
| 475 | |
| 476 /************************************************************************** | |
| 477 * Status editor | |
| 478 **************************************************************************/ | |
| 10420 | 479 |
| 10418 | 480 static gboolean |
| 481 status_editor_destroy_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) | |
| 482 { | |
| 10574 | 483 StatusEditor *dialog = user_data; |
| 10418 | 484 |
| 10574 | 485 g_free(dialog->original_title); |
| 10418 | 486 g_free(dialog); |
| 487 | |
| 488 return FALSE; | |
| 489 } | |
| 490 | |
| 491 static void | |
| 492 status_editor_cancel_cb(GtkButton *button, gpointer user_data) | |
| 493 { | |
| 10574 | 494 StatusEditor *dialog = user_data; |
| 10418 | 495 |
| 496 gtk_widget_destroy(dialog->window); | |
| 497 | |
| 10574 | 498 g_free(dialog->original_title); |
| 10418 | 499 g_free(dialog); |
| 500 } | |
| 501 | |
| 502 static void | |
| 503 status_editor_save_cb(GtkButton *button, gpointer user_data) | |
| 504 { | |
| 10420 | 505 StatusEditor *dialog = user_data; |
| 506 const char *title; | |
| 507 GaimStatusPrimitive type; | |
| 508 char *message, *unformatted; | |
| 509 GaimSavedStatus *status; | |
| 510 | |
| 511 title = gtk_entry_get_text(dialog->title); | |
| 512 | |
| 513 /* | |
| 514 * If the title is already taken then show an error dialog and | |
| 515 * don't do anything. | |
| 516 */ | |
| 517 if ((gaim_savedstatus_find(title) != NULL) && | |
| 518 ((dialog->original_title == NULL) || (strcmp(title, dialog->original_title)))) | |
| 519 { | |
| 520 gaim_notify_error(NULL, NULL, _("Title already in use. You must " | |
| 521 "choose a unique title."), NULL); | |
| 522 return; | |
| 523 } | |
| 524 | |
| 525 type = gtk_option_menu_get_history(dialog->type); | |
| 526 message = gtk_imhtml_get_markup(dialog->message); | |
| 527 unformatted = gaim_markup_strip_html(message); | |
| 528 | |
| 529 /* | |
| 530 * If we're editing an existing status, remove the old one to | |
| 531 * make way for the modified one. | |
| 532 */ | |
| 533 if (dialog->original_title != NULL) | |
| 534 { | |
| 535 GtkTreeIter iter; | |
| 536 | |
| 537 gaim_savedstatus_delete(dialog->original_title); | |
| 538 | |
| 539 if (status_window_find_savedstatus(&iter, dialog->original_title)) | |
| 540 { | |
| 541 gtk_list_store_remove(status_window->model, &iter); | |
| 542 } | |
| 543 } | |
| 544 | |
| 545 status = gaim_savedstatus_new(title, type); | |
| 546 if (*unformatted != '\0') | |
| 547 gaim_savedstatus_set_message(status, message); | |
| 548 g_free(message); | |
| 549 g_free(unformatted); | |
| 550 | |
| 551 gtk_widget_destroy(dialog->window); | |
| 10574 | 552 g_free(dialog->original_title); |
| 10420 | 553 g_free(dialog); |
| 554 | |
| 555 add_status_to_saved_status_list(status_window->model, status); | |
| 556 } | |
| 557 | |
| 558 static void | |
| 559 status_editor_custom_status_cb(GtkCellRendererToggle *renderer, gchar *path_str, gpointer data) | |
| 560 { | |
| 561 /* StatusEditor *dialog = (StatusEditor *)data; */ | |
| 562 | |
| 563 /* TODO: Need to allow user to set a custom status for the highlighted account, somehow */ | |
| 564 } | |
| 565 | |
| 566 static void | |
| 567 editor_title_changed_cb(GtkWidget *widget, gpointer user_data) | |
| 568 { | |
| 569 StatusEditor *dialog = user_data; | |
| 570 const gchar *text; | |
| 571 | |
| 572 text = gtk_entry_get_text(dialog->title); | |
| 573 | |
| 574 gtk_widget_set_sensitive(dialog->save_button, (*text != '\0')); | |
| 10418 | 575 } |
| 576 | |
| 577 static GtkWidget * | |
| 10419 | 578 create_status_type_menu(GaimStatusPrimitive type) |
| 10418 | 579 { |
| 10419 | 580 int i; |
| 10418 | 581 GtkWidget *dropdown; |
| 582 GtkWidget *menu; | |
| 583 GtkWidget *item; | |
| 584 | |
| 585 dropdown = gtk_option_menu_new(); | |
| 586 menu = gtk_menu_new(); | |
| 587 | |
| 10419 | 588 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) |
| 589 { | |
| 590 item = gtk_menu_item_new_with_label(gaim_primitive_get_name_from_type(i)); | |
| 591 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
| 592 gtk_widget_show(item); | |
| 593 } | |
| 10418 | 594 |
| 10419 | 595 gtk_menu_set_active(GTK_MENU(menu), type); |
| 10418 | 596 gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu); |
| 597 gtk_widget_show(menu); | |
| 598 | |
| 599 return dropdown; | |
| 600 } | |
| 601 | |
| 602 static void | |
| 603 status_editor_add_columns(StatusEditor *dialog) | |
| 604 { | |
| 605 GtkCellRenderer *renderer; | |
| 606 GtkTreeViewColumn *column; | |
| 607 | |
| 608 /* Custom status column */ | |
| 609 renderer = gtk_cell_renderer_toggle_new(); | |
| 610 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(dialog->treeview), | |
| 611 -1, _("Custom status"), | |
| 612 renderer, | |
| 613 "active", STATUS_EDITOR_COLUMN_CUSTOM_STATUS, | |
| 614 NULL); | |
| 615 column = gtk_tree_view_get_column(GTK_TREE_VIEW(dialog->treeview), 1); | |
| 616 g_signal_connect(G_OBJECT(renderer), "toggled", | |
| 617 G_CALLBACK(status_editor_custom_status_cb), dialog); | |
| 618 | |
| 619 /* Screen Name column */ | |
| 620 column = gtk_tree_view_column_new(); | |
| 621 gtk_tree_view_column_set_resizable(column, TRUE); | |
| 622 gtk_tree_view_column_set_title(column, _("Screen Name")); | |
| 623 gtk_tree_view_insert_column(GTK_TREE_VIEW(dialog->treeview), column, -1); | |
| 624 gtk_tree_view_column_set_resizable(column, TRUE); | |
| 625 | |
| 626 /* Icon */ | |
| 627 renderer = gtk_cell_renderer_pixbuf_new(); | |
| 628 gtk_tree_view_column_pack_start(column, renderer, FALSE); | |
| 629 gtk_tree_view_column_add_attribute(column, renderer, "pixbuf", | |
| 630 STATUS_EDITOR_COLUMN_ICON); | |
| 631 | |
| 632 /* Screen Name */ | |
| 633 renderer = gtk_cell_renderer_text_new(); | |
| 634 gtk_tree_view_column_pack_start(column, renderer, TRUE); | |
| 635 gtk_tree_view_column_add_attribute(column, renderer, "text", | |
| 636 STATUS_EDITOR_COLUMN_SCREENNAME); | |
| 637 } | |
| 638 | |
| 639 static void | |
| 640 status_editor_set_account(GtkListStore *store, GaimAccount *account, GtkTreeIter *iter) | |
| 641 { | |
| 642 GdkPixbuf *pixbuf; | |
| 643 GdkPixbuf *scale; | |
| 644 | |
| 645 scale = NULL; | |
| 646 | |
| 10884 | 647 pixbuf = gaim_gtk_create_prpl_icon(account); |
| 10418 | 648 |
| 649 if (pixbuf != NULL) | |
| 650 { | |
| 651 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); | |
| 652 | |
| 653 if (!gaim_account_is_connected(account)) | |
| 654 gdk_pixbuf_saturate_and_pixelate(scale, scale, 0.0, FALSE); | |
| 655 } | |
| 656 | |
| 657 gtk_list_store_set(store, iter, | |
| 658 STATUS_EDITOR_COLUMN_ICON, scale, | |
| 659 STATUS_EDITOR_COLUMN_SCREENNAME, gaim_account_get_username(account), | |
| 660 -1); | |
| 661 | |
| 662 if (pixbuf != NULL) g_object_unref(G_OBJECT(pixbuf)); | |
| 663 if (scale != NULL) g_object_unref(G_OBJECT(scale)); | |
| 664 } | |
| 665 | |
| 666 static void | |
| 667 status_editor_add_account(StatusEditor *dialog, GaimAccount *account) | |
| 668 { | |
| 669 GtkTreeIter iter; | |
| 670 | |
| 671 gtk_list_store_append(dialog->model, &iter); | |
| 672 | |
| 673 status_editor_set_account(dialog->model, account, &iter); | |
| 674 } | |
| 675 | |
| 676 static void | |
| 677 status_editor_populate_list(StatusEditor *dialog) | |
| 678 { | |
| 679 GList *l; | |
| 680 | |
| 681 gtk_list_store_clear(dialog->model); | |
| 682 | |
| 683 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) | |
| 684 status_editor_add_account(dialog, (GaimAccount *)l->data); | |
| 685 } | |
| 686 | |
| 687 void | |
| 10419 | 688 gaim_gtk_status_editor_show(GaimSavedStatus *status) |
| 10418 | 689 { |
| 690 StatusEditor *dialog; | |
| 691 GtkSizeGroup *sg; | |
| 692 GtkWidget *bbox; | |
| 693 GtkWidget *button; | |
| 694 GtkWidget *dbox; | |
| 695 GtkWidget *disclosure; | |
| 696 GtkWidget *dropdown; | |
| 697 GtkWidget *entry; | |
| 698 GtkWidget *frame; | |
| 699 GtkWidget *hbox; | |
| 700 GtkWidget *label; | |
| 701 GtkWidget *sw; | |
| 702 GtkWidget *text; | |
| 703 GtkWidget *toolbar; | |
| 704 GtkWidget *vbox; | |
| 705 GtkWidget *win; | |
| 706 | |
| 707 dialog = g_new0(StatusEditor, 1); | |
| 708 | |
| 10420 | 709 if (status != NULL) |
| 710 dialog->original_title = g_strdup(gaim_savedstatus_get_title(status)); | |
| 711 | |
| 10418 | 712 dialog->window = win = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
| 713 gtk_window_set_role(GTK_WINDOW(win), "status"); | |
| 714 gtk_window_set_title(GTK_WINDOW(win), _("Status")); | |
| 715 gtk_window_set_resizable(GTK_WINDOW(win), FALSE); | |
| 716 gtk_container_set_border_width(GTK_CONTAINER(win), 12); | |
| 717 | |
| 718 g_signal_connect(G_OBJECT(win), "delete_event", | |
| 719 G_CALLBACK(status_editor_destroy_cb), dialog); | |
| 720 | |
| 721 /* Setup the vbox */ | |
| 722 vbox = gtk_vbox_new(FALSE, 12); | |
| 723 gtk_container_add(GTK_CONTAINER(win), vbox); | |
| 724 gtk_widget_show(vbox); | |
| 725 | |
| 726 sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
| 727 | |
| 728 /* Title */ | |
| 729 hbox = gtk_hbox_new(FALSE, 6); | |
| 730 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
| 731 gtk_widget_show(hbox); | |
| 732 | |
| 733 label = gtk_label_new_with_mnemonic(_("_Title:")); | |
| 734 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 735 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
| 736 gtk_widget_show(label); | |
| 737 gtk_size_group_add_widget(sg, label); | |
| 738 | |
| 739 entry = gtk_entry_new(); | |
| 10420 | 740 dialog->title = GTK_ENTRY(entry); |
| 10419 | 741 if (status != NULL) |
| 10420 | 742 gtk_entry_set_text(GTK_ENTRY(entry), dialog->original_title); |
| 10419 | 743 else |
| 744 gtk_entry_set_text(GTK_ENTRY(entry), _("Out of the office")); | |
| 10418 | 745 gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0); |
| 746 gtk_widget_show(entry); | |
| 10420 | 747 g_signal_connect(G_OBJECT(entry), "changed", |
| 748 G_CALLBACK(editor_title_changed_cb), dialog); | |
| 10418 | 749 |
| 750 /* Status type */ | |
| 751 hbox = gtk_hbox_new(FALSE, 6); | |
| 752 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
| 753 gtk_widget_show(hbox); | |
| 754 | |
| 755 label = gtk_label_new_with_mnemonic(_("_Status:")); | |
| 756 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 757 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
| 758 gtk_widget_show(label); | |
| 759 gtk_size_group_add_widget(sg, label); | |
| 760 | |
| 10419 | 761 if (status != NULL) |
| 762 dropdown = create_status_type_menu(gaim_savedstatus_get_type(status)); | |
| 763 else | |
| 764 dropdown = create_status_type_menu(GAIM_STATUS_AWAY); | |
| 10420 | 765 dialog->type = GTK_OPTION_MENU(dropdown); |
| 10418 | 766 gtk_box_pack_start(GTK_BOX(hbox), dropdown, TRUE, TRUE, 0); |
| 767 gtk_widget_show(dropdown); | |
| 768 | |
| 769 /* Status message */ | |
| 770 hbox = gtk_hbox_new(FALSE, 6); | |
| 771 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
| 772 gtk_widget_show(hbox); | |
| 773 | |
| 774 label = gtk_label_new_with_mnemonic(_("_Message:")); | |
| 775 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
| 776 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
| 777 gtk_widget_show(label); | |
| 778 gtk_size_group_add_widget(sg, label); | |
| 779 | |
| 780 frame = gaim_gtk_create_imhtml(TRUE, &text, &toolbar); | |
| 10420 | 781 dialog->message = GTK_IMHTML(text); |
| 10418 | 782 gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); |
| 783 gtk_widget_show(frame); | |
| 784 | |
| 10574 | 785 if ((status != NULL) && (gaim_savedstatus_get_message(status) != NULL)) |
| 10419 | 786 gtk_imhtml_append_text(GTK_IMHTML(text), |
| 787 gaim_savedstatus_get_message(status), 0); | |
| 788 | |
| 10418 | 789 /* Custom status message disclosure */ |
| 790 disclosure = gaim_disclosure_new(_("Use a different status for some accounts"), | |
| 791 _("Use a different status for some accounts")); | |
| 792 gtk_box_pack_start(GTK_BOX(vbox), disclosure, FALSE, FALSE, 0); | |
| 793 gtk_widget_show(disclosure); | |
| 794 | |
| 795 /* Setup the box that the disclosure will cover */ | |
| 796 dbox = gtk_vbox_new(FALSE, 18); | |
| 797 gtk_box_pack_start(GTK_BOX(vbox), dbox, FALSE, FALSE, 0); | |
| 798 gaim_disclosure_set_container(GAIM_DISCLOSURE(disclosure), dbox); | |
| 799 | |
| 800 /* Custom status message treeview */ | |
| 801 sw = gtk_scrolled_window_new(NULL, NULL); | |
| 802 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
| 803 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); | |
| 804 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
| 805 GTK_SHADOW_IN); | |
| 806 gtk_box_pack_start(GTK_BOX(dbox), sw, TRUE, TRUE, 0); | |
| 807 gtk_widget_show(sw); | |
| 808 | |
| 809 /* Create the list model */ | |
| 810 dialog->model = gtk_list_store_new(STATUS_EDITOR_NUM_COLUMNS, | |
| 811 G_TYPE_BOOLEAN, | |
| 812 GDK_TYPE_PIXBUF, G_TYPE_STRING); | |
| 813 | |
| 814 /* Create the treeview */ | |
| 815 dialog->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
| 816 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(dialog->treeview), TRUE); | |
| 817 gtk_widget_set_size_request(dialog->treeview, 400, 250); | |
| 818 gtk_container_add(GTK_CONTAINER(sw), dialog->treeview); | |
| 819 gtk_widget_show(dialog->treeview); | |
| 820 | |
| 821 /* Add columns */ | |
| 822 status_editor_add_columns(dialog); | |
| 823 | |
| 824 /* Populate list */ | |
| 825 status_editor_populate_list(dialog); | |
| 826 | |
| 827 /* Button box */ | |
| 828 bbox = gtk_hbutton_box_new(); | |
| 829 gtk_box_set_spacing(GTK_BOX(bbox), 6); | |
| 830 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
| 831 gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); | |
| 832 gtk_widget_show(bbox); | |
| 833 | |
| 834 /* Cancel button */ | |
| 835 button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); | |
| 836 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); | |
| 837 gtk_widget_show(button); | |
| 838 | |
| 839 g_signal_connect(G_OBJECT(button), "clicked", | |
| 840 G_CALLBACK(status_editor_cancel_cb), dialog); | |
| 841 | |
| 842 /* Save button */ | |
| 843 button = gtk_button_new_from_stock(GTK_STOCK_SAVE); | |
| 10420 | 844 dialog->save_button = button; |
| 10418 | 845 gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); |
| 846 gtk_widget_show(button); | |
| 847 | |
| 848 g_signal_connect(G_OBJECT(button), "clicked", | |
| 849 G_CALLBACK(status_editor_save_cb), dialog); | |
| 850 | |
| 851 gtk_widget_show(win); | |
| 852 } | |
| 853 | |
| 854 | |
| 10421 | 855 /************************************************************************** |
|
10814
364a2ef907ae
[gaim-migrate @ 12468]
Luke Schierer <lschiere@pidgin.im>
parents:
10732
diff
changeset
|
856 * GTK+ saved status glue |
| 10421 | 857 **************************************************************************/ |
| 10418 | 858 |
| 859 void * | |
| 860 gaim_gtk_status_get_handle() | |
| 861 { | |
| 862 static int handle; | |
| 863 | |
| 864 return &handle; | |
| 865 } | |
| 866 | |
| 867 void | |
| 868 gaim_gtk_status_init(void) | |
| 869 { | |
| 870 gaim_prefs_add_none("/gaim/gtk/status"); | |
| 871 gaim_prefs_add_none("/gaim/gtk/status/dialog"); | |
| 872 gaim_prefs_add_int("/gaim/gtk/status/dialog/width", 550); | |
| 873 gaim_prefs_add_int("/gaim/gtk/status/dialog/height", 250); | |
| 874 } | |
| 875 | |
| 876 void | |
| 877 gaim_gtk_status_uninit(void) | |
| 878 { | |
| 879 gaim_gtk_status_window_hide(); | |
| 880 } |
