| 1 /* |
|
| 2 * gaim |
|
| 3 * |
|
| 4 * Gaim is the legal property of its developers, whose names are too numerous |
|
| 5 * to list here. Please refer to the COPYRIGHT file distributed with this |
|
| 6 * source distribution. |
|
| 7 * |
|
| 8 * This program is free software; you can redistribute it and/or modify |
|
| 9 * it under the terms of the GNU General Public License as published by |
|
| 10 * the Free Software Foundation; either version 2 of the License, or |
|
| 11 * (at your option) any later version. |
|
| 12 * |
|
| 13 * This program is distributed in the hope that it will be useful, |
|
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 16 * GNU General Public License for more details. |
|
| 17 * |
|
| 18 * You should have received a copy of the GNU General Public License |
|
| 19 * along with this program; if not, write to the Free Software |
|
| 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
| 21 * |
|
| 22 */ |
|
| 23 #if 0 |
|
| 24 #include "internal.h" |
|
| 25 #include "gtkgaim.h" |
|
| 26 |
|
| 27 #include "conversation.h" |
|
| 28 #include "debug.h" |
|
| 29 #include "notify.h" |
|
| 30 #include "plugin.h" |
|
| 31 #include "prefs.h" |
|
| 32 #include "prpl.h" |
|
| 33 #include "status.h" |
|
| 34 #include "util.h" |
|
| 35 #include "request.h" |
|
| 36 |
|
| 37 /* XXX CORE/UI: Until we can get rid of the message queue stuff... */ |
|
| 38 #include "away.h" |
|
| 39 #include "gaim.h" |
|
| 40 #include "gtkblist.h" |
|
| 41 #include "gtkdialogs.h" |
|
| 42 #include "gtkimhtml.h" |
|
| 43 #include "gtkimhtmltoolbar.h" |
|
| 44 #include "gtkprefs.h" |
|
| 45 #include "gtkutils.h" |
|
| 46 |
|
| 47 GtkWidget *imaway = NULL; |
|
| 48 GtkWidget *awaymenu = NULL; |
|
| 49 GtkWidget *awayqueue = NULL; |
|
| 50 GtkListStore *awayqueuestore = NULL; |
|
| 51 GtkWidget *awayqueuesw; |
|
| 52 |
|
| 53 GSList *message_queue = NULL; |
|
| 54 GSList *unread_message_queue = NULL; |
|
| 55 |
|
| 56 GSList *away_messages = NULL; |
|
| 57 struct away_message *awaymessage = NULL; |
|
| 58 |
|
| 59 static void dequeue_message(GtkTreeIter *iter) |
|
| 60 { |
|
| 61 gchar *name; |
|
| 62 GSList *templist; |
|
| 63 GaimConversation *cnv; |
|
| 64 gboolean orig_while_away; |
|
| 65 |
|
| 66 orig_while_away = gaim_prefs_get_bool("/core/sound/while_away"); |
|
| 67 if (orig_while_away) |
|
| 68 gaim_prefs_set_bool("/core/sound/while_away", FALSE); |
|
| 69 |
|
| 70 gtk_tree_model_get(GTK_TREE_MODEL(awayqueuestore), iter, 0, &name, -1); |
|
| 71 |
|
| 72 gaim_debug(GAIM_DEBUG_INFO, "away", "Dequeueing messages from %s.\n", |
|
| 73 name); |
|
| 74 |
|
| 75 templist = message_queue; |
|
| 76 |
|
| 77 while (templist) { |
|
| 78 struct queued_message *qm = templist->data; |
|
| 79 if (templist->data) { |
|
| 80 if (!gaim_utf8_strcasecmp(qm->name, name)) { |
|
| 81 GaimAccount *account = NULL; |
|
| 82 |
|
| 83 if (g_list_index(gaim_accounts_get_all(), qm->account) >= 0) |
|
| 84 account = qm->account; |
|
| 85 |
|
| 86 cnv = gaim_find_conversation_with_account(name, account); |
|
| 87 |
|
| 88 if (!cnv) |
|
| 89 cnv = gaim_conversation_new(GAIM_CONV_IM, account, qm->name); |
|
| 90 else |
|
| 91 gaim_conversation_set_account(cnv, account); |
|
| 92 |
|
| 93 gaim_conv_im_write(GAIM_CONV_IM(cnv), NULL, qm->message, |
|
| 94 qm->flags, qm->tm); |
|
| 95 g_free(qm->message); |
|
| 96 g_free(qm); |
|
| 97 templist = message_queue = g_slist_remove(message_queue, qm); |
|
| 98 |
|
| 99 } else { |
|
| 100 templist = templist->next; |
|
| 101 } |
|
| 102 } |
|
| 103 } |
|
| 104 |
|
| 105 g_free(name); |
|
| 106 /* In GTK 2.2, _store_remove actually returns whether iter is valid or not |
|
| 107 * after the remove, but in GTK 2.0 it is a void function. */ |
|
| 108 gtk_list_store_remove(awayqueuestore, iter); |
|
| 109 |
|
| 110 if (orig_while_away) |
|
| 111 gaim_prefs_set_bool("/core/sound/while_away", orig_while_away); |
|
| 112 } |
|
| 113 |
|
| 114 void purge_away_queue(GSList **queue) |
|
| 115 { |
|
| 116 GSList *q = *queue; |
|
| 117 struct queued_message *qm; |
|
| 118 GaimConversation *cnv; |
|
| 119 GaimAccount *account; |
|
| 120 gboolean orig_while_away; |
|
| 121 |
|
| 122 orig_while_away = gaim_prefs_get_bool("/core/sound/while_away"); |
|
| 123 if (orig_while_away) |
|
| 124 gaim_prefs_set_bool("/core/sound/while_away", FALSE); |
|
| 125 |
|
| 126 while (q) { |
|
| 127 qm = q->data; |
|
| 128 |
|
| 129 account = NULL; |
|
| 130 |
|
| 131 if (g_list_index(gaim_accounts_get_all(), qm->account) >= 0) |
|
| 132 account = qm->account; |
|
| 133 |
|
| 134 cnv = gaim_find_conversation_with_account(qm->name, account); |
|
| 135 |
|
| 136 if (!cnv) |
|
| 137 cnv = gaim_conversation_new(GAIM_CONV_IM, account, qm->name); |
|
| 138 else |
|
| 139 gaim_conversation_set_account(cnv, account); |
|
| 140 |
|
| 141 gaim_conv_im_write(GAIM_CONV_IM(cnv), NULL, qm->message, qm->flags, qm->tm); |
|
| 142 |
|
| 143 g_free(qm->message); |
|
| 144 g_free(qm); |
|
| 145 |
|
| 146 q->data = NULL; |
|
| 147 q = q->next; |
|
| 148 } |
|
| 149 |
|
| 150 g_slist_free(*queue); |
|
| 151 *queue = NULL; |
|
| 152 |
|
| 153 if (orig_while_away) |
|
| 154 gaim_prefs_set_bool("/core/sound/while_away", orig_while_away); |
|
| 155 } |
|
| 156 |
|
| 157 gint dequeue_cb(GtkWidget *treeview, GdkEventButton *event, gpointer data) { |
|
| 158 GtkTreeIter iter; |
|
| 159 GtkTreeSelection *select; |
|
| 160 |
|
| 161 if(!(event->type == GDK_2BUTTON_PRESS && event->button == 1)) |
|
| 162 return FALSE; /* Double clicking on the list will dequeue that user's messages. */ |
|
| 163 |
|
| 164 select = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); |
|
| 165 if(gtk_tree_selection_get_selected(select, NULL, &iter)) |
|
| 166 dequeue_message(&iter); |
|
| 167 |
|
| 168 return FALSE; |
|
| 169 } |
|
| 170 |
|
| 171 |
|
| 172 |
|
| 173 void toggle_away_queue() |
|
| 174 { |
|
| 175 if (!awayqueue || !awayqueuesw) |
|
| 176 return; |
|
| 177 |
|
| 178 if (gaim_prefs_get_bool("/gaim/gtk/away/queue_messages")) { |
|
| 179 gtk_widget_show(awayqueue); |
|
| 180 gtk_widget_show(awayqueuesw); |
|
| 181 } else { |
|
| 182 gtk_widget_hide(awayqueue); |
|
| 183 gtk_widget_hide(awayqueuesw); |
|
| 184 purge_away_queue(&message_queue); |
|
| 185 } |
|
| 186 } |
|
| 187 |
|
| 188 void do_im_back(GtkWidget *w, GtkWidget *x) |
|
| 189 { |
|
| 190 if (imaway) { |
|
| 191 GtkWidget *tmp = imaway; |
|
| 192 |
|
| 193 purge_away_queue(&message_queue); |
|
| 194 |
|
| 195 imaway = NULL; |
|
| 196 gtk_widget_destroy(tmp); |
|
| 197 if (w != tmp) |
|
| 198 return; |
|
| 199 } |
|
| 200 |
|
| 201 awaymessage = NULL; |
|
| 202 awayqueue = NULL; |
|
| 203 awayqueuesw = NULL; |
|
| 204 if (awayqueuestore != NULL) |
|
| 205 g_object_unref(G_OBJECT(awayqueuestore)); |
|
| 206 awayqueuestore = NULL; |
|
| 207 serv_set_away_all(NULL); |
|
| 208 } |
|
| 209 |
|
| 210 |
|
| 211 void do_away_message(GtkWidget *w, struct away_message *a) |
|
| 212 { |
|
| 213 GtkWidget *back; |
|
| 214 GtkWidget *edit; |
|
| 215 GtkWidget *awaytext; |
|
| 216 GtkWidget *sw; |
|
| 217 GtkWidget *vbox; |
|
| 218 GtkWidget *hbox; |
|
| 219 GtkTreeViewColumn *column; |
|
| 220 GtkCellRenderer *renderer; |
|
| 221 char *buf; |
|
| 222 |
|
| 223 if (!a) |
|
| 224 return; |
|
| 225 |
|
| 226 if(imaway) |
|
| 227 gtk_widget_destroy(imaway); |
|
| 228 |
|
| 229 GAIM_DIALOG(imaway); |
|
| 230 gtk_window_set_role(GTK_WINDOW(imaway), "imaway"); |
|
| 231 if (strlen(a->name)) |
|
| 232 gtk_window_set_title(GTK_WINDOW(imaway), a->name); |
|
| 233 else |
|
| 234 gtk_window_set_title(GTK_WINDOW(imaway), _("Away!")); |
|
| 235 g_signal_connect(G_OBJECT(imaway), "destroy", |
|
| 236 G_CALLBACK(do_im_back), imaway); |
|
| 237 |
|
| 238 vbox = gtk_vbox_new(FALSE, 5); |
|
| 239 gtk_container_add(GTK_CONTAINER(imaway), vbox); |
|
| 240 gtk_container_set_border_width(GTK_CONTAINER(vbox), 5); |
|
| 241 gtk_widget_show(vbox); |
|
| 242 |
|
| 243 hbox = gtk_hbox_new(FALSE, 5); |
|
| 244 gtk_container_set_border_width(GTK_CONTAINER(hbox), 0); |
|
| 245 gtk_widget_show(hbox); |
|
| 246 |
|
| 247 sw = gtk_scrolled_window_new(NULL, NULL); |
|
| 248 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, |
|
| 249 GTK_POLICY_AUTOMATIC); |
|
| 250 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); |
|
| 251 gtk_widget_set_size_request(sw, 245, 120); |
|
| 252 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); |
|
| 253 gtk_widget_show(sw); |
|
| 254 |
|
| 255 awaytext = gtk_imhtml_new(NULL, NULL); |
|
| 256 gtk_container_add(GTK_CONTAINER(sw), awaytext); |
|
| 257 gaim_setup_imhtml(awaytext); |
|
| 258 gtk_widget_show(awaytext); |
|
| 259 buf = stylize(a->message, BUF_LONG); |
|
| 260 gtk_imhtml_append_text(GTK_IMHTML(awaytext), buf, GTK_IMHTML_NO_TITLE | |
|
| 261 GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_SCROLL); |
|
| 262 g_free(buf); |
|
| 263 gtk_imhtml_append_text(GTK_IMHTML(awaytext), "<BR>", |
|
| 264 GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_COMMENTS | |
|
| 265 GTK_IMHTML_NO_SCROLL); |
|
| 266 |
|
| 267 awayqueuesw = gtk_scrolled_window_new(NULL, NULL); |
|
| 268 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(awayqueuesw), |
|
| 269 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); |
|
| 270 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(awayqueuesw), |
|
| 271 GTK_SHADOW_IN); |
|
| 272 gtk_box_pack_start(GTK_BOX(vbox), awayqueuesw, TRUE, TRUE, 0); |
|
| 273 |
|
| 274 awayqueuestore = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); |
|
| 275 awayqueue = gtk_tree_view_new_with_model(GTK_TREE_MODEL(awayqueuestore)); |
|
| 276 renderer = gtk_cell_renderer_text_new(); |
|
| 277 |
|
| 278 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(awayqueue), FALSE); |
|
| 279 column = gtk_tree_view_column_new_with_attributes (NULL, renderer, |
|
| 280 "text", 0, |
|
| 281 NULL); |
|
| 282 gtk_tree_view_append_column(GTK_TREE_VIEW(awayqueue), column); |
|
| 283 column = gtk_tree_view_column_new_with_attributes(NULL, renderer, |
|
| 284 "text", 1, |
|
| 285 NULL); |
|
| 286 gtk_tree_view_append_column(GTK_TREE_VIEW(awayqueue), column); |
|
| 287 column = gtk_tree_view_column_new_with_attributes(NULL, renderer, |
|
| 288 "text", 2, |
|
| 289 NULL); |
|
| 290 gtk_tree_view_append_column(GTK_TREE_VIEW(awayqueue), column); |
|
| 291 |
|
| 292 gtk_container_add(GTK_CONTAINER(awayqueuesw), awayqueue); |
|
| 293 |
|
| 294 g_signal_connect(G_OBJECT(awayqueue), "button_press_event", G_CALLBACK(dequeue_cb), NULL); |
|
| 295 |
|
| 296 |
|
| 297 if (gaim_prefs_get_bool("/gaim/gtk/away/queue_messages")) { |
|
| 298 gtk_widget_show(awayqueuesw); |
|
| 299 gtk_widget_show(awayqueue); |
|
| 300 } |
|
| 301 |
|
| 302 awaymessage = a; |
|
| 303 |
|
| 304 edit = gaim_pixbuf_button_from_stock(_("Edit This Message"), GTK_STOCK_CONVERT, GAIM_BUTTON_HORIZONTAL); |
|
| 305 gtk_box_pack_start(GTK_BOX(hbox), edit, TRUE, TRUE, 0); |
|
| 306 g_signal_connect(G_OBJECT(edit), "clicked", G_CALLBACK(create_away_mess), awaymessage); |
|
| 307 gtk_widget_show(edit); |
|
| 308 |
|
| 309 back = gaim_pixbuf_button_from_stock(_("I'm Back!"), GTK_STOCK_JUMP_TO, GAIM_BUTTON_HORIZONTAL); |
|
| 310 gtk_box_pack_start(GTK_BOX(hbox), back, TRUE, TRUE, 0); |
|
| 311 g_signal_connect(G_OBJECT(back), "clicked", G_CALLBACK(do_im_back), imaway); |
|
| 312 gtk_window_set_focus(GTK_WINDOW(imaway), back); |
|
| 313 gtk_widget_show(back); |
|
| 314 |
|
| 315 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
|
| 316 |
|
| 317 gtk_widget_show(imaway); |
|
| 318 serv_set_away_all(awaymessage->message); |
|
| 319 } |
|
| 320 |
|
| 321 void do_rem_away_mess(gchar *name) |
|
| 322 { |
|
| 323 struct away_message *a = NULL; |
|
| 324 struct away_message *default_away = NULL; |
|
| 325 const char *default_away_name; |
|
| 326 GSList *l; |
|
| 327 |
|
| 328 /* Lookup the away message based on the title */ |
|
| 329 for (l = away_messages; l != NULL; l = l->next) { |
|
| 330 a = l->data; |
|
| 331 if (!strcmp(a->name, name)) |
|
| 332 break; |
|
| 333 } |
|
| 334 g_free(name); |
|
| 335 |
|
| 336 if (l == NULL || a == NULL) { |
|
| 337 /* Could not find away message! */ |
|
| 338 return; |
|
| 339 } |
|
| 340 |
|
| 341 default_away_name = gaim_prefs_get_string("/core/away/default_message"); |
|
| 342 |
|
| 343 for(l = away_messages; l; l = l->next) { |
|
| 344 if(!strcmp(default_away_name, ((struct away_message *)l->data)->name)) { |
|
| 345 default_away = l->data; |
|
| 346 break; |
|
| 347 } |
|
| 348 } |
|
| 349 |
|
| 350 if(!default_away && away_messages) |
|
| 351 default_away = away_messages->data; |
|
| 352 |
|
| 353 away_messages = g_slist_remove(away_messages, a); |
|
| 354 g_free(a); |
|
| 355 do_away_menu(); |
|
| 356 gaim_status_sync(); |
|
| 357 } |
|
| 358 |
|
| 359 void rem_away_mess(GtkWidget *w, struct away_message *a) |
|
| 360 { |
|
| 361 gchar *text; |
|
| 362 |
|
| 363 text = g_strdup_printf(_("Are you sure you want to remove the away message \"%s\"?"), a->name); |
|
| 364 |
|
| 365 gaim_request_action(NULL, NULL, _("Remove Away Message"), text, |
|
| 366 0, g_strdup(a->name), 2, |
|
| 367 _("Remove"), G_CALLBACK(do_rem_away_mess), |
|
| 368 _("Cancel"), G_CALLBACK(g_free)); |
|
| 369 |
|
| 370 g_free(text); |
|
| 371 } |
|
| 372 |
|
| 373 static void set_gc_away(GObject *obj, GaimConnection *gc) |
|
| 374 { |
|
| 375 struct away_message *awy = g_object_get_data(obj, "away_message"); |
|
| 376 |
|
| 377 if (awy) |
|
| 378 serv_set_away(gc, GAIM_AWAY_CUSTOM, awy->message); |
|
| 379 else |
|
| 380 serv_set_away(gc, GAIM_AWAY_CUSTOM, NULL); |
|
| 381 } |
|
| 382 |
|
| 383 static void set_gc_state(GObject *obj, GaimConnection *gc) |
|
| 384 { |
|
| 385 char *awy = g_object_get_data(obj, "away_state"); |
|
| 386 |
|
| 387 serv_set_away(gc, awy, NULL); |
|
| 388 } |
|
| 389 |
|
| 390 /* XXX This needs to be fixed, NOW! */ |
|
| 391 extern GtkListStore *prefs_away_store; |
|
| 392 extern GtkWidget *prefs_away_menu; |
|
| 393 |
|
| 394 void do_away_menu() |
|
| 395 { |
|
| 396 GtkWidget *menuitem; |
|
| 397 GtkWidget *remmenu; |
|
| 398 GtkWidget *submenu, *submenu2; |
|
| 399 GtkWidget *remitem; |
|
| 400 GtkWidget *image; |
|
| 401 GdkPixbuf *pixbuf, *scale; |
|
| 402 GList *l; |
|
| 403 GSList *awy = away_messages; |
|
| 404 struct away_message *a; |
|
| 405 GList *con; |
|
| 406 GaimConnection *gc = NULL; |
|
| 407 GaimPluginProtocolInfo *prpl_info = NULL; |
|
| 408 |
|
| 409 int count = 0; |
|
| 410 |
|
| 411 if (prefs_away_store != NULL) { |
|
| 412 gtk_list_store_clear(prefs_away_store); |
|
| 413 while (awy) { |
|
| 414 GtkTreeIter iter; |
|
| 415 a = (struct away_message *)awy->data; |
|
| 416 gtk_list_store_append(prefs_away_store, &iter); |
|
| 417 gtk_list_store_set(prefs_away_store, &iter, |
|
| 418 0, a->name, |
|
| 419 1, a, |
|
| 420 -1); |
|
| 421 awy = g_slist_next(awy); |
|
| 422 } |
|
| 423 } |
|
| 424 |
|
| 425 if (awaymenu) { |
|
| 426 l = gtk_container_get_children(GTK_CONTAINER(awaymenu)); |
|
| 427 |
|
| 428 while (l) { |
|
| 429 gtk_container_remove(GTK_CONTAINER(awaymenu), GTK_WIDGET(l->data)); |
|
| 430 l = l->next; |
|
| 431 } |
|
| 432 |
|
| 433 g_list_free(l); |
|
| 434 |
|
| 435 remmenu = gtk_menu_new(); |
|
| 436 |
|
| 437 menuitem = gtk_menu_item_new_with_label(_("New Away Message")); |
|
| 438 gtk_menu_shell_append(GTK_MENU_SHELL(awaymenu), menuitem); |
|
| 439 gtk_widget_show(menuitem); |
|
| 440 g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(create_away_mess), |
|
| 441 NULL); |
|
| 442 |
|
| 443 awy = away_messages; |
|
| 444 while (awy) { |
|
| 445 a = (struct away_message *)awy->data; |
|
| 446 |
|
| 447 remitem = gtk_menu_item_new_with_label(a->name); |
|
| 448 gtk_menu_shell_append(GTK_MENU_SHELL(remmenu), remitem); |
|
| 449 gtk_widget_show(remitem); |
|
| 450 g_signal_connect(G_OBJECT(remitem), "activate", |
|
| 451 G_CALLBACK(rem_away_mess), a); |
|
| 452 |
|
| 453 awy = g_slist_next(awy); |
|
| 454 |
|
| 455 } |
|
| 456 |
|
| 457 menuitem = gtk_menu_item_new_with_label(_("Remove Away Message")); |
|
| 458 gtk_menu_shell_append(GTK_MENU_SHELL(awaymenu), menuitem); |
|
| 459 gtk_widget_show(menuitem); |
|
| 460 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), remmenu); |
|
| 461 gtk_widget_show(remmenu); |
|
| 462 |
|
| 463 gaim_separator(awaymenu); |
|
| 464 |
|
| 465 for (con = gaim_connections_get_all(); con != NULL; con = con->next) { |
|
| 466 gc = con->data; |
|
| 467 |
|
| 468 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 469 |
|
| 470 if (prpl_info->away_states != NULL && prpl_info->set_away != NULL) |
|
| 471 count++; |
|
| 472 } |
|
| 473 |
|
| 474 if (count == 0) { |
|
| 475 } else if (count == 1) { |
|
| 476 GList *msgs, *tmp; |
|
| 477 |
|
| 478 for (con = gaim_connections_get_all(); con != NULL; con = con->next) { |
|
| 479 gc = con->data; |
|
| 480 |
|
| 481 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 482 |
|
| 483 if (prpl_info->away_states && prpl_info->set_away) |
|
| 484 break; |
|
| 485 } |
|
| 486 |
|
| 487 tmp = msgs = prpl_info->away_states(gc); |
|
| 488 |
|
| 489 if ((g_list_length(msgs) == 1) && !strcmp(msgs->data, GAIM_AWAY_CUSTOM)) { |
|
| 490 awy = away_messages; |
|
| 491 |
|
| 492 while (awy) { |
|
| 493 a = (struct away_message *)awy->data; |
|
| 494 |
|
| 495 menuitem = gtk_menu_item_new_with_label(a->name); |
|
| 496 g_object_set_data(G_OBJECT(menuitem), "away_message", a); |
|
| 497 gtk_menu_shell_append(GTK_MENU_SHELL(awaymenu), menuitem); |
|
| 498 gtk_widget_show(menuitem); |
|
| 499 g_signal_connect(G_OBJECT(menuitem), "activate", |
|
| 500 G_CALLBACK(do_away_message), a); |
|
| 501 |
|
| 502 awy = g_slist_next(awy); |
|
| 503 } |
|
| 504 } else |
|
| 505 while (msgs) { |
|
| 506 awy = away_messages; |
|
| 507 |
|
| 508 menuitem = gtk_menu_item_new_with_label(msgs->data); |
|
| 509 g_object_set_data(G_OBJECT(menuitem), "away_state", msgs->data); |
|
| 510 gtk_menu_shell_append(GTK_MENU_SHELL(awaymenu), menuitem); |
|
| 511 gtk_widget_show(menuitem); |
|
| 512 |
|
| 513 if (strcmp(msgs->data, GAIM_AWAY_CUSTOM)) { |
|
| 514 g_signal_connect(G_OBJECT(menuitem), "activate", |
|
| 515 G_CALLBACK(set_gc_state), gc); |
|
| 516 } else { |
|
| 517 submenu = gtk_menu_new(); |
|
| 518 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), |
|
| 519 submenu); |
|
| 520 gtk_widget_show(submenu); |
|
| 521 |
|
| 522 while (awy) { |
|
| 523 a = (struct away_message *)awy->data; |
|
| 524 |
|
| 525 menuitem = gtk_menu_item_new_with_label(a->name); |
|
| 526 g_object_set_data(G_OBJECT(menuitem), "away_message", |
|
| 527 a); |
|
| 528 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), |
|
| 529 menuitem); |
|
| 530 gtk_widget_show(menuitem); |
|
| 531 g_signal_connect(G_OBJECT(menuitem), |
|
| 532 "activate", |
|
| 533 G_CALLBACK |
|
| 534 (do_away_message), a); |
|
| 535 |
|
| 536 awy = g_slist_next(awy); |
|
| 537 } |
|
| 538 } |
|
| 539 msgs = g_list_next(msgs); |
|
| 540 } |
|
| 541 |
|
| 542 g_list_free(tmp); |
|
| 543 } |
|
| 544 else { |
|
| 545 for (con = gaim_connections_get_all(); con != NULL; con = con->next) { |
|
| 546 GaimAccount *account; |
|
| 547 char buf[256]; |
|
| 548 GList *msgs, *tmp; |
|
| 549 gc = con->data; |
|
| 550 |
|
| 551 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 552 |
|
| 553 if (!prpl_info->away_states || !prpl_info->set_away) |
|
| 554 continue; |
|
| 555 |
|
| 556 account = gaim_connection_get_account(gc); |
|
| 557 |
|
| 558 g_snprintf(buf, sizeof(buf), "%s (%s)", |
|
| 559 gaim_account_get_username(account), |
|
| 560 gaim_account_get_protocol_name(account)); |
|
| 561 menuitem = gtk_image_menu_item_new_with_label(buf); |
|
| 562 |
|
| 563 pixbuf = create_prpl_icon(gc->account); |
|
| 564 if (pixbuf) { |
|
| 565 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); |
|
| 566 image = gtk_image_new_from_pixbuf(scale); |
|
| 567 g_object_unref(G_OBJECT(pixbuf)); |
|
| 568 g_object_unref(G_OBJECT(scale)); |
|
| 569 gtk_widget_show(image); |
|
| 570 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), |
|
| 571 image); |
|
| 572 } |
|
| 573 |
|
| 574 gtk_menu_shell_append(GTK_MENU_SHELL(awaymenu), menuitem); |
|
| 575 gtk_widget_show(menuitem); |
|
| 576 |
|
| 577 submenu = gtk_menu_new(); |
|
| 578 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); |
|
| 579 gtk_widget_show(submenu); |
|
| 580 |
|
| 581 tmp = msgs = prpl_info->away_states(gc); |
|
| 582 |
|
| 583 if ((g_list_length(msgs) == 1) && |
|
| 584 (!strcmp(msgs->data, GAIM_AWAY_CUSTOM))) { |
|
| 585 menuitem = gtk_menu_item_new_with_label(_("Back")); |
|
| 586 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); |
|
| 587 gtk_widget_show(menuitem); |
|
| 588 g_signal_connect(G_OBJECT(menuitem), "activate", |
|
| 589 G_CALLBACK(set_gc_away), gc); |
|
| 590 |
|
| 591 gaim_separator(submenu); |
|
| 592 |
|
| 593 awy = away_messages; |
|
| 594 |
|
| 595 while (awy) { |
|
| 596 a = (struct away_message *)awy->data; |
|
| 597 |
|
| 598 menuitem = gtk_menu_item_new_with_label(a->name); |
|
| 599 g_object_set_data(G_OBJECT(menuitem), "away_message", a); |
|
| 600 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); |
|
| 601 gtk_widget_show(menuitem); |
|
| 602 g_signal_connect(G_OBJECT(menuitem), "activate", |
|
| 603 G_CALLBACK(set_gc_away), gc); |
|
| 604 |
|
| 605 awy = g_slist_next(awy); |
|
| 606 } |
|
| 607 } else |
|
| 608 while (msgs) { |
|
| 609 awy = away_messages; |
|
| 610 |
|
| 611 menuitem = gtk_menu_item_new_with_label(msgs->data); |
|
| 612 g_object_set_data(G_OBJECT(menuitem), "away_state", |
|
| 613 msgs->data); |
|
| 614 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); |
|
| 615 gtk_widget_show(menuitem); |
|
| 616 |
|
| 617 if (strcmp(msgs->data, GAIM_AWAY_CUSTOM)) { |
|
| 618 g_signal_connect(G_OBJECT(menuitem), |
|
| 619 "activate", |
|
| 620 G_CALLBACK(set_gc_state), |
|
| 621 gc); |
|
| 622 } else { |
|
| 623 submenu2 = gtk_menu_new(); |
|
| 624 gtk_menu_item_set_submenu(GTK_MENU_ITEM |
|
| 625 (menuitem), submenu2); |
|
| 626 gtk_widget_show(submenu2); |
|
| 627 |
|
| 628 while (awy) { |
|
| 629 a = (struct away_message *)awy->data; |
|
| 630 |
|
| 631 menuitem = |
|
| 632 gtk_menu_item_new_with_label(a-> |
|
| 633 name); |
|
| 634 g_object_set_data(G_OBJECT(menuitem), |
|
| 635 "away_message", a); |
|
| 636 gtk_menu_shell_append(GTK_MENU_SHELL(submenu2), |
|
| 637 menuitem); |
|
| 638 gtk_widget_show(menuitem); |
|
| 639 g_signal_connect(G_OBJECT(menuitem), |
|
| 640 "activate", |
|
| 641 G_CALLBACK |
|
| 642 (set_gc_away), gc); |
|
| 643 |
|
| 644 awy = g_slist_next(awy); |
|
| 645 } |
|
| 646 } |
|
| 647 msgs = g_list_next(msgs); |
|
| 648 } |
|
| 649 |
|
| 650 g_list_free(tmp); |
|
| 651 } |
|
| 652 |
|
| 653 menuitem = gtk_menu_item_new_with_label(_("Set All Away")); |
|
| 654 gtk_menu_shell_append(GTK_MENU_SHELL(awaymenu), menuitem); |
|
| 655 gtk_widget_show(menuitem); |
|
| 656 |
|
| 657 submenu = gtk_menu_new(); |
|
| 658 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu); |
|
| 659 gtk_widget_show(submenu); |
|
| 660 |
|
| 661 awy = away_messages; |
|
| 662 |
|
| 663 while (awy) { |
|
| 664 a = (struct away_message *)awy->data; |
|
| 665 |
|
| 666 menuitem = gtk_menu_item_new_with_label(a->name); |
|
| 667 g_object_set_data(G_OBJECT(menuitem), "away_message", a); |
|
| 668 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), menuitem); |
|
| 669 gtk_widget_show(menuitem); |
|
| 670 g_signal_connect(G_OBJECT(menuitem), "activate", |
|
| 671 G_CALLBACK(do_away_message), a); |
|
| 672 |
|
| 673 awy = g_slist_next(awy); |
|
| 674 } |
|
| 675 } |
|
| 676 } |
|
| 677 |
|
| 678 if (prefs_away_menu) { |
|
| 679 l = gtk_container_get_children(GTK_CONTAINER(prefs_away_menu)); |
|
| 680 while (l) { |
|
| 681 gtk_widget_destroy(GTK_WIDGET(l->data)); |
|
| 682 l = l->next; |
|
| 683 } |
|
| 684 gtk_widget_hide(GTK_WIDGET(prefs_away_menu)); |
|
| 685 default_away_menu_init(GTK_WIDGET(prefs_away_menu)); |
|
| 686 gtk_widget_show(prefs_away_menu); |
|
| 687 } |
|
| 688 } |
|
| 689 |
|
| 690 /*------------------------------------------------------------------------*/ |
|
| 691 /* The dialog for new away messages (from dialogs.c) */ |
|
| 692 /*------------------------------------------------------------------------*/ |
|
| 693 struct create_away { |
|
| 694 GtkWidget *window; |
|
| 695 GtkWidget *toolbar; |
|
| 696 GtkWidget *entry; |
|
| 697 GtkWidget *text; |
|
| 698 struct away_message *mess; |
|
| 699 }; |
|
| 700 |
|
| 701 static void |
|
| 702 away_mess_destroy(GtkWidget *widget, struct create_away *ca) |
|
| 703 { |
|
| 704 gtk_widget_destroy(ca->window); |
|
| 705 g_free(ca); |
|
| 706 } |
|
| 707 |
|
| 708 static void |
|
| 709 away_mess_destroy_ca(GtkWidget *widget, GdkEvent *event, struct create_away *ca) |
|
| 710 { |
|
| 711 away_mess_destroy(NULL, ca); |
|
| 712 } |
|
| 713 |
|
| 714 static gint |
|
| 715 sort_awaymsg_list(gconstpointer a, gconstpointer b) |
|
| 716 { |
|
| 717 struct away_message *msg_a; |
|
| 718 struct away_message *msg_b; |
|
| 719 |
|
| 720 msg_a = (struct away_message *)a; |
|
| 721 msg_b = (struct away_message *)b; |
|
| 722 |
|
| 723 return (strcmp(msg_a->name, msg_b->name)); |
|
| 724 } |
|
| 725 |
|
| 726 static struct |
|
| 727 away_message *save_away_message(struct create_away *ca) |
|
| 728 { |
|
| 729 struct away_message *am; |
|
| 730 gchar *away_message; |
|
| 731 |
|
| 732 if (!ca->mess) |
|
| 733 am = g_new0(struct away_message, 1); |
|
| 734 else { |
|
| 735 am = ca->mess; |
|
| 736 } |
|
| 737 |
|
| 738 g_snprintf(am->name, sizeof(am->name), "%s", gtk_entry_get_text(GTK_ENTRY(ca->entry))); |
|
| 739 away_message = gtk_imhtml_get_markup(GTK_IMHTML(ca->text)); |
|
| 740 |
|
| 741 g_snprintf(am->message, sizeof(am->message), "%s", away_message); |
|
| 742 g_free(away_message); |
|
| 743 |
|
| 744 if (!ca->mess) |
|
| 745 away_messages = g_slist_insert_sorted(away_messages, am, sort_awaymsg_list); |
|
| 746 |
|
| 747 do_away_menu(NULL); |
|
| 748 gaim_status_sync(); |
|
| 749 |
|
| 750 return am; |
|
| 751 } |
|
| 752 |
|
| 753 int |
|
| 754 check_away_mess(struct create_away *ca, int type) |
|
| 755 { |
|
| 756 gchar *msg; |
|
| 757 if ((strlen(gtk_entry_get_text(GTK_ENTRY(ca->entry))) == 0) && (type == 1)) { |
|
| 758 /* We shouldn't allow a blank title */ |
|
| 759 gaim_notify_error(NULL, NULL, |
|
| 760 _("You cannot save an away message with a " |
|
| 761 "blank title"), |
|
| 762 _("Please give the message a title, or choose " |
|
| 763 "\"Use\" to use without saving.")); |
|
| 764 return 0; |
|
| 765 } |
|
| 766 |
|
| 767 msg = gtk_imhtml_get_text(GTK_IMHTML(ca->text), NULL, NULL); |
|
| 768 |
|
| 769 if ((type <= 1) && ((msg == NULL) || (*msg == '\0'))) { |
|
| 770 /* We shouldn't allow a blank message */ |
|
| 771 gaim_notify_error(NULL, NULL, |
|
| 772 _("You cannot create an empty away message"), NULL); |
|
| 773 return 0; |
|
| 774 } |
|
| 775 |
|
| 776 g_free(msg); |
|
| 777 |
|
| 778 return 1; |
|
| 779 } |
|
| 780 |
|
| 781 void |
|
| 782 save_away_mess(GtkWidget *widget, struct create_away *ca) |
|
| 783 { |
|
| 784 if (!check_away_mess(ca, 1)) |
|
| 785 return; |
|
| 786 |
|
| 787 save_away_message(ca); |
|
| 788 |
|
| 789 away_mess_destroy(NULL, ca); |
|
| 790 } |
|
| 791 |
|
| 792 void |
|
| 793 use_away_mess(GtkWidget *widget, struct create_away *ca) |
|
| 794 { |
|
| 795 static struct away_message am; |
|
| 796 gchar *away_message; |
|
| 797 |
|
| 798 if (!check_away_mess(ca, 0)) |
|
| 799 return; |
|
| 800 |
|
| 801 g_snprintf(am.name, sizeof(am.name), "%s", gtk_entry_get_text(GTK_ENTRY(ca->entry))); |
|
| 802 away_message = gtk_imhtml_get_markup(GTK_IMHTML(ca->text)); |
|
| 803 |
|
| 804 g_snprintf(am.message, sizeof(am.message), "%s", away_message); |
|
| 805 g_free(away_message); |
|
| 806 |
|
| 807 do_away_message(NULL, &am); |
|
| 808 |
|
| 809 away_mess_destroy(NULL, ca); |
|
| 810 } |
|
| 811 |
|
| 812 void |
|
| 813 su_away_mess(GtkWidget *widget, struct create_away *ca) |
|
| 814 { |
|
| 815 if (!check_away_mess(ca, 1)) |
|
| 816 return; |
|
| 817 |
|
| 818 do_away_message(NULL, save_away_message(ca)); |
|
| 819 |
|
| 820 away_mess_destroy(NULL, ca); |
|
| 821 } |
|
| 822 |
|
| 823 void |
|
| 824 create_away_mess(GtkWidget *widget, void *dummy) |
|
| 825 { |
|
| 826 GtkWidget *vbox, *hbox; |
|
| 827 GtkWidget *label; |
|
| 828 GtkWidget *sw; |
|
| 829 GtkWidget *button; |
|
| 830 GList *focus_chain = NULL; |
|
| 831 struct create_away *ca = g_new0(struct create_away, 1); |
|
| 832 |
|
| 833 /* Set up window */ |
|
| 834 GAIM_DIALOG(ca->window); |
|
| 835 gtk_widget_set_size_request(ca->window, -1, 250); |
|
| 836 gtk_window_set_role(GTK_WINDOW(ca->window), "away_mess"); |
|
| 837 gtk_window_set_title(GTK_WINDOW(ca->window), _("New away message")); |
|
| 838 g_signal_connect(G_OBJECT(ca->window), "delete_event", |
|
| 839 G_CALLBACK(away_mess_destroy_ca), ca); |
|
| 840 |
|
| 841 hbox = gtk_hbox_new(FALSE, 12); |
|
| 842 gtk_container_set_border_width(GTK_CONTAINER(hbox), 12); |
|
| 843 gtk_container_add(GTK_CONTAINER(ca->window), hbox); |
|
| 844 |
|
| 845 vbox = gtk_vbox_new(FALSE, 12); |
|
| 846 gtk_container_add(GTK_CONTAINER(hbox), vbox); |
|
| 847 |
|
| 848 /* Away message title */ |
|
| 849 hbox = gtk_hbox_new(FALSE, 0); |
|
| 850 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
|
| 851 |
|
| 852 label = gtk_label_new(_("Away title: ")); |
|
| 853 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); |
|
| 854 |
|
| 855 ca->entry = gtk_entry_new(); |
|
| 856 gtk_box_pack_start(GTK_BOX(hbox), ca->entry, TRUE, TRUE, 0); |
|
| 857 gaim_set_accessible_label (ca->entry, label); |
|
| 858 focus_chain = g_list_append(focus_chain, hbox); |
|
| 859 |
|
| 860 /* Toolbar */ |
|
| 861 ca->toolbar = gtk_imhtmltoolbar_new(); |
|
| 862 gtk_box_pack_start(GTK_BOX(vbox), ca->toolbar, FALSE, FALSE, 0); |
|
| 863 |
|
| 864 /* Away message text */ |
|
| 865 sw = gtk_scrolled_window_new(NULL, NULL); |
|
| 866 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), |
|
| 867 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); |
|
| 868 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN); |
|
| 869 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); |
|
| 870 |
|
| 871 ca->text = gtk_imhtml_new(NULL, NULL); |
|
| 872 gtk_imhtml_set_editable(GTK_IMHTML(ca->text), TRUE); |
|
| 873 gtk_imhtml_set_format_functions(GTK_IMHTML(ca->text), GTK_IMHTML_ALL ^ GTK_IMHTML_IMAGE); |
|
| 874 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(ca->text), GTK_WRAP_WORD_CHAR); |
|
| 875 |
|
| 876 gtk_imhtml_smiley_shortcuts(GTK_IMHTML(ca->text), |
|
| 877 gaim_prefs_get_bool("/gaim/gtk/conversations/smiley_shortcuts")); |
|
| 878 gtk_imhtml_html_shortcuts(GTK_IMHTML(ca->text), |
|
| 879 gaim_prefs_get_bool("/gaim/gtk/conversations/html_shortcuts")); |
|
| 880 if (gaim_prefs_get_bool("/gaim/gtk/conversations/spellcheck")) |
|
| 881 gaim_gtk_setup_gtkspell(GTK_TEXT_VIEW(ca->text)); |
|
| 882 gtk_imhtmltoolbar_attach(GTK_IMHTMLTOOLBAR(ca->toolbar), ca->text); |
|
| 883 gtk_imhtmltoolbar_associate_smileys(GTK_IMHTMLTOOLBAR(ca->toolbar), "default"); |
|
| 884 gaim_setup_imhtml(ca->text); |
|
| 885 |
|
| 886 gtk_container_add(GTK_CONTAINER(sw), ca->text); |
|
| 887 focus_chain = g_list_append(focus_chain, sw); |
|
| 888 |
|
| 889 if (dummy) { |
|
| 890 /* If anything is passed here, it is an away_message pointer */ |
|
| 891 struct away_message *amt = (struct away_message *) dummy ; |
|
| 892 gtk_entry_set_text(GTK_ENTRY(ca->entry), amt->name); |
|
| 893 gtk_imhtml_append_text_with_images(GTK_IMHTML(ca->text), amt->message, 0, NULL); |
|
| 894 ca->mess = amt; |
|
| 895 } |
|
| 896 |
|
| 897 hbox = gtk_hbox_new(FALSE, 5); |
|
| 898 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
|
| 899 |
|
| 900 button = gaim_pixbuf_button_from_stock(_("_Save"), GTK_STOCK_SAVE, GAIM_BUTTON_HORIZONTAL); |
|
| 901 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(save_away_mess), ca); |
|
| 902 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); |
|
| 903 |
|
| 904 button = gaim_pixbuf_button_from_stock(_("Sa_ve & Use"), GTK_STOCK_OK, GAIM_BUTTON_HORIZONTAL); |
|
| 905 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(su_away_mess), ca); |
|
| 906 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); |
|
| 907 |
|
| 908 button = gaim_pixbuf_button_from_stock(_("_Use"), GTK_STOCK_EXECUTE, GAIM_BUTTON_HORIZONTAL); |
|
| 909 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(use_away_mess), ca); |
|
| 910 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); |
|
| 911 |
|
| 912 button = gaim_pixbuf_button_from_stock(_("_Cancel"), GTK_STOCK_CANCEL, GAIM_BUTTON_HORIZONTAL); |
|
| 913 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(away_mess_destroy), ca); |
|
| 914 gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); |
|
| 915 focus_chain = g_list_prepend(focus_chain, hbox); |
|
| 916 |
|
| 917 gtk_widget_show_all(ca->window); |
|
| 918 gtk_container_set_focus_chain(GTK_CONTAINER(vbox), focus_chain); |
|
| 919 } |
|
| 920 #endif /* 0 */ |
|