Mercurial > pidgin.yaz
comparison pidgin/gtkconv.c @ 32779:d72f2f13b60f
merge of 'c8c73eea7431e6f940916315ace40a41c8da3faa'
and 'fec428131bde0ae8247941bd6a3d996c984c9189'
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Fri, 21 Oct 2011 14:36:18 +0000 |
parents | 2ec94166be43 |
children | 75104780b1a3 |
comparison
equal
deleted
inserted
replaced
32778:14787acaf9d7 | 32779:d72f2f13b60f |
---|---|
50 #include "imgstore.h" | 50 #include "imgstore.h" |
51 #include "log.h" | 51 #include "log.h" |
52 #include "notify.h" | 52 #include "notify.h" |
53 #include "prpl.h" | 53 #include "prpl.h" |
54 #include "request.h" | 54 #include "request.h" |
55 #include "theme-loader.h" | |
56 #include "theme-manager.h" | |
55 #include "util.h" | 57 #include "util.h" |
56 #include "version.h" | 58 #include "version.h" |
57 | 59 |
58 #include "gtkdnd-hints.h" | 60 #include "gtkdnd-hints.h" |
59 #include "gtkblist.h" | 61 #include "gtkblist.h" |
60 #include "gtkconv.h" | 62 #include "gtkconv.h" |
61 #include "gtkconvwin.h" | 63 #include "gtkconvwin.h" |
64 #include "gtkconv-theme.h" | |
65 #include "gtkconv-theme-loader.h" | |
62 #include "gtkdialogs.h" | 66 #include "gtkdialogs.h" |
63 #include "gtkimhtml.h" | 67 #include "gtkimhtml.h" |
64 #include "gtkimhtmltoolbar.h" | 68 #include "gtkimhtmltoolbar.h" |
65 #include "gtklog.h" | 69 #include "gtklog.h" |
66 #include "gtkmenutray.h" | 70 #include "gtkmenutray.h" |
67 #include "gtkpounce.h" | 71 #include "gtkpounce.h" |
68 #include "gtkprefs.h" | 72 #include "gtkprefs.h" |
69 #include "gtkprivacy.h" | 73 #include "gtkprivacy.h" |
70 #include "gtkthemes.h" | 74 #include "gtkthemes.h" |
71 #include "gtkutils.h" | 75 #include "gtkutils.h" |
76 #include "gtkwebview.h" | |
72 #include "pidginstock.h" | 77 #include "pidginstock.h" |
73 #include "pidgintooltip.h" | 78 #include "pidgintooltip.h" |
79 #include "smileyparser.h" | |
74 | 80 |
75 #include "gtknickcolors.h" | 81 #include "gtknickcolors.h" |
82 | |
83 /** | |
84 * A GTK+ Instant Message pane. | |
85 */ | |
86 struct _PidginImPane | |
87 { | |
88 GtkWidget *block; | |
89 GtkWidget *send_file; | |
90 GtkWidget *sep1; | |
91 GtkWidget *sep2; | |
92 GtkWidget *check; | |
93 GtkWidget *progress; | |
94 guint32 typing_timer; | |
95 | |
96 /* Buddy icon stuff */ | |
97 GtkWidget *icon_container; | |
98 GtkWidget *icon; | |
99 gboolean show_icon; | |
100 gboolean animate; | |
101 GdkPixbufAnimation *anim; | |
102 GdkPixbufAnimationIter *iter; | |
103 guint32 icon_timer; | |
104 }; | |
105 | |
106 /** | |
107 * GTK+ Chat panes. | |
108 */ | |
109 struct _PidginChatPane | |
110 { | |
111 GtkWidget *count; | |
112 GtkWidget *list; | |
113 GtkWidget *topic_text; | |
114 }; | |
76 | 115 |
77 #define CLOSE_CONV_TIMEOUT_SECS (10 * 60) | 116 #define CLOSE_CONV_TIMEOUT_SECS (10 * 60) |
78 | 117 |
79 #define AUTO_RESPONSE "<AUTO-REPLY> : " | 118 #define AUTO_RESPONSE "<AUTO-REPLY> : " |
80 | 119 |
174 static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y); | 213 static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y); |
175 | 214 |
176 static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) | 215 static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) |
177 { | 216 { |
178 static GdkColor col; | 217 static GdkColor col; |
179 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml); | 218 GtkStyle *style = gtk_widget_get_style(gtkconv->webview); |
180 float scale; | 219 float scale; |
181 | 220 |
182 col = nick_colors[g_str_hash(name) % nbr_nick_colors]; | 221 col = nick_colors[g_str_hash(name) % nbr_nick_colors]; |
183 scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) * | 222 scale = ((1-(LUMINANCE(style->base[GTK_STATE_NORMAL]) / LUMINANCE(style->white))) * |
184 (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green))); | 223 (LUMINANCE(style->white)/MAX(MAX(col.red, col.blue), col.green))); |
194 } | 233 } |
195 | 234 |
196 static PurpleBlistNode * | 235 static PurpleBlistNode * |
197 get_conversation_blist_node(PurpleConversation *conv) | 236 get_conversation_blist_node(PurpleConversation *conv) |
198 { | 237 { |
238 PurpleAccount *account = purple_conversation_get_account(conv); | |
199 PurpleBlistNode *node = NULL; | 239 PurpleBlistNode *node = NULL; |
200 | 240 |
201 switch (purple_conversation_get_type(conv)) { | 241 switch (purple_conversation_get_type(conv)) { |
202 case PURPLE_CONV_TYPE_IM: | 242 case PURPLE_CONV_TYPE_IM: |
203 node = PURPLE_BLIST_NODE(purple_find_buddy(conv->account, conv->name)); | 243 node = PURPLE_BLIST_NODE(purple_find_buddy(account, purple_conversation_get_name(conv))); |
204 node = node ? node->parent : NULL; | 244 node = node ? node->parent : NULL; |
205 break; | 245 break; |
206 case PURPLE_CONV_TYPE_CHAT: | 246 case PURPLE_CONV_TYPE_CHAT: |
207 node = PURPLE_BLIST_NODE(purple_blist_find_chat(conv->account, conv->name)); | 247 node = PURPLE_BLIST_NODE(purple_blist_find_chat(account, purple_conversation_get_name(conv))); |
208 break; | 248 break; |
209 default: | 249 default: |
210 break; | 250 break; |
211 } | 251 } |
212 return node; | 252 return node; |
274 | 314 |
275 static void | 315 static void |
276 default_formatize(PidginConversation *c) | 316 default_formatize(PidginConversation *c) |
277 { | 317 { |
278 PurpleConversation *conv = c->active_conv; | 318 PurpleConversation *conv = c->active_conv; |
279 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features); | 319 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), purple_conversation_get_features(conv)); |
280 } | 320 } |
281 | 321 |
282 static void | 322 static void |
283 conversation_entry_clear(PidginConversation *gtkconv) | 323 conversation_entry_clear(PidginConversation *gtkconv) |
284 { | 324 { |
354 } else { | 394 } else { |
355 str = g_string_append(str, "(none)"); | 395 str = g_string_append(str, "(none)"); |
356 } | 396 } |
357 | 397 |
358 tmp = g_string_free(str, FALSE); | 398 tmp = g_string_free(str, FALSE); |
399 } else if (!g_ascii_strcasecmp(args[0], "unsafe")) { | |
400 if (purple_debug_is_unsafe()) { | |
401 purple_debug_set_unsafe(FALSE); | |
402 purple_conversation_write(conv, NULL, _("Unsafe debugging is now disabled."), | |
403 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
404 } else { | |
405 purple_debug_set_unsafe(TRUE); | |
406 purple_conversation_write(conv, NULL, _("Unsafe debugging is now enabled."), | |
407 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
408 } | |
409 | |
410 return PURPLE_CMD_RET_OK; | |
411 } else if (!g_ascii_strcasecmp(args[0], "verbose")) { | |
412 if (purple_debug_is_verbose()) { | |
413 purple_debug_set_verbose(FALSE); | |
414 purple_conversation_write(conv, NULL, _("Verbose debugging is now disabled."), | |
415 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
416 } else { | |
417 purple_debug_set_verbose(TRUE); | |
418 purple_conversation_write(conv, NULL, _("Verbose debugging is now enabled."), | |
419 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_SYSTEM, time(NULL)); | |
420 } | |
421 | |
422 return PURPLE_CMD_RET_OK; | |
359 } else { | 423 } else { |
360 purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version"), | 424 purple_conversation_write(conv, NULL, _("Supported debug options are: plugins version unsafe verbose"), |
361 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL)); | 425 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL)); |
362 return PURPLE_CMD_RET_OK; | 426 return PURPLE_CMD_RET_OK; |
363 } | 427 } |
364 | 428 |
365 markup = g_markup_escape_text(tmp, -1); | 429 markup = g_markup_escape_text(tmp, -1); |
377 void *data) | 441 void *data) |
378 { | 442 { |
379 PidginConversation *gtkconv = NULL; | 443 PidginConversation *gtkconv = NULL; |
380 | 444 |
381 gtkconv = PIDGIN_CONVERSATION(conv); | 445 gtkconv = PIDGIN_CONVERSATION(conv); |
382 if (gtkconv) | 446 |
383 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); | 447 if (PIDGIN_CONVERSATION(conv)) |
448 webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(gtkconv->webview), "", ""); | |
384 } | 449 } |
385 | 450 |
386 static PurpleCmdRet | 451 static PurpleCmdRet |
387 clear_command_cb(PurpleConversation *conv, | 452 clear_command_cb(PurpleConversation *conv, |
388 const char *cmd, char **args, char **error, void *data) | 453 const char *cmd, char **args, char **error, void *data) |
497 { | 562 { |
498 PurplePluginProtocolInfo *prpl_info = NULL; | 563 PurplePluginProtocolInfo *prpl_info = NULL; |
499 PurpleConnection *gc; | 564 PurpleConnection *gc; |
500 | 565 |
501 if ((gc = purple_conversation_get_gc(conv))) | 566 if ((gc = purple_conversation_get_gc(conv))) |
502 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 567 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
503 | 568 |
504 if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) { | 569 if ((prpl_info != NULL) && (prpl_info->options & OPT_PROTO_SLASH_COMMANDS_NATIVE)) { |
505 char *spaceslash; | 570 char *spaceslash; |
506 | 571 |
507 /* If the first word in the entered text has a '/' in it, then the user | 572 /* If the first word in the entered text has a '/' in it, then the user |
576 buf = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry)); | 641 buf = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry)); |
577 clean = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); | 642 clean = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); |
578 | 643 |
579 gtk_widget_grab_focus(gtkconv->entry); | 644 gtk_widget_grab_focus(gtkconv->entry); |
580 | 645 |
581 if (strlen(clean) == 0) { | 646 if (!*clean) { |
582 g_free(buf); | 647 g_free(buf); |
583 g_free(clean); | 648 g_free(clean); |
584 return; | 649 return; |
585 } | 650 } |
586 | 651 |
589 /* XXX: is there a better way to tell if the message has images? */ | 654 /* XXX: is there a better way to tell if the message has images? */ |
590 if (GTK_IMHTML(gtkconv->entry)->im_images != NULL) | 655 if (GTK_IMHTML(gtkconv->entry)->im_images != NULL) |
591 flags |= PURPLE_MESSAGE_IMAGES; | 656 flags |= PURPLE_MESSAGE_IMAGES; |
592 | 657 |
593 gc = purple_account_get_connection(account); | 658 gc = purple_account_get_connection(account); |
594 if (gc && (conv->features & PURPLE_CONNECTION_NO_NEWLINES)) { | 659 if (gc && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_NO_NEWLINES)) { |
595 char **bufs; | 660 char **bufs; |
596 int i; | 661 int i; |
597 | 662 |
598 bufs = gtk_imhtml_get_markup_lines(GTK_IMHTML(gtkconv->entry)); | 663 bufs = gtk_imhtml_get_markup_lines(GTK_IMHTML(gtkconv->entry)); |
599 for (i = 0; bufs[i]; i++) { | 664 for (i = 0; bufs[i]; i++) { |
986 } | 1051 } |
987 | 1052 |
988 static void | 1053 static void |
989 savelog_writefile_cb(void *user_data, const char *filename) | 1054 savelog_writefile_cb(void *user_data, const char *filename) |
990 { | 1055 { |
1056 /* TODO WEBKIT: I don't know how to support this using webkit yet. */ | |
1057 #if 0 | |
991 PurpleConversation *conv = (PurpleConversation *)user_data; | 1058 PurpleConversation *conv = (PurpleConversation *)user_data; |
992 FILE *fp; | 1059 FILE *fp; |
993 const char *name; | 1060 const char *name; |
994 char **lines; | 1061 char **lines; |
995 gchar *text; | 1062 gchar *text; |
1012 g_free(text); | 1079 g_free(text); |
1013 g_strfreev(lines); | 1080 g_strfreev(lines); |
1014 | 1081 |
1015 fprintf(fp, "\n</body>\n</html>\n"); | 1082 fprintf(fp, "\n</body>\n</html>\n"); |
1016 fclose(fp); | 1083 fclose(fp); |
1084 #endif /* if 0 */ | |
1017 } | 1085 } |
1018 | 1086 |
1019 /* | 1087 /* |
1020 * It would be kinda cool if this gave the option of saving a | 1088 * It would be kinda cool if this gave the option of saving a |
1021 * plaintext v. HTML file. | 1089 * plaintext v. HTML file. |
1023 static void | 1091 static void |
1024 menu_save_as_cb(gpointer data, guint action, GtkWidget *widget) | 1092 menu_save_as_cb(gpointer data, guint action, GtkWidget *widget) |
1025 { | 1093 { |
1026 PidginWindow *win = data; | 1094 PidginWindow *win = data; |
1027 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); | 1095 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); |
1028 PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name); | 1096 PurpleAccount *account = purple_conversation_get_account(conv); |
1097 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); | |
1029 const char *name; | 1098 const char *name; |
1030 gchar *buf; | 1099 gchar *buf; |
1031 gchar *c; | 1100 gchar *c; |
1032 | 1101 |
1033 if (buddy != NULL) | 1102 if (buddy != NULL) |
1034 name = purple_buddy_get_contact_alias(buddy); | 1103 name = purple_buddy_get_contact_alias(buddy); |
1035 else | 1104 else |
1036 name = purple_normalize(conv->account, conv->name); | 1105 name = purple_normalize(account, purple_conversation_get_name(conv)); |
1037 | 1106 |
1038 buf = g_strdup_printf("%s.html", name); | 1107 buf = g_strdup_printf("%s.html", name); |
1039 for (c = buf ; *c ; c++) | 1108 for (c = buf ; *c ; c++) |
1040 { | 1109 { |
1041 if (*c == '/' || *c == '\\') | 1110 if (*c == '/' || *c == '\\') |
1354 /* Enable logging first so the message below can be logged. */ | 1423 /* Enable logging first so the message below can be logged. */ |
1355 purple_conversation_set_logging(conv, TRUE); | 1424 purple_conversation_set_logging(conv, TRUE); |
1356 | 1425 |
1357 purple_conversation_write(conv, NULL, | 1426 purple_conversation_write(conv, NULL, |
1358 _("Logging started. Future messages in this conversation will be logged."), | 1427 _("Logging started. Future messages in this conversation will be logged."), |
1359 conv->logs ? (PURPLE_MESSAGE_SYSTEM) : | 1428 PURPLE_MESSAGE_SYSTEM, |
1360 (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG), | |
1361 time(NULL)); | 1429 time(NULL)); |
1362 } | 1430 } |
1363 else | 1431 else |
1364 { | 1432 { |
1365 purple_conversation_write(conv, NULL, | 1433 purple_conversation_write(conv, NULL, |
1366 _("Logging stopped. Future messages in this conversation will not be logged."), | 1434 _("Logging stopped. Future messages in this conversation will not be logged."), |
1367 conv->logs ? (PURPLE_MESSAGE_SYSTEM) : | 1435 PURPLE_MESSAGE_SYSTEM, |
1368 (PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG), | |
1369 time(NULL)); | 1436 time(NULL)); |
1370 | 1437 |
1371 /* Disable the logging second, so that the above message can be logged. */ | 1438 /* Disable the logging second, so that the above message can be logged. */ |
1372 purple_conversation_set_logging(conv, FALSE); | 1439 purple_conversation_set_logging(conv, FALSE); |
1373 } | 1440 } |
1374 | 1441 |
1375 /* Save the setting IFF it's different than the pref. */ | 1442 /* Save the setting IFF it's different than the pref. */ |
1376 switch (conv->type) | 1443 switch (purple_conversation_get_type(conv)) |
1377 { | 1444 { |
1378 case PURPLE_CONV_TYPE_IM: | 1445 case PURPLE_CONV_TYPE_IM: |
1379 if (logging == purple_prefs_get_bool("/purple/logging/log_ims")) | 1446 if (logging == purple_prefs_get_bool("/purple/logging/log_ims")) |
1380 purple_blist_node_remove_setting(node, "enable-logging"); | 1447 purple_blist_node_remove_setting(node, "enable-logging"); |
1381 else | 1448 else |
1443 g_return_if_fail(account != NULL); | 1510 g_return_if_fail(account != NULL); |
1444 | 1511 |
1445 gc = purple_account_get_connection(account); | 1512 gc = purple_account_get_connection(account); |
1446 g_return_if_fail(gc != NULL); | 1513 g_return_if_fail(gc != NULL); |
1447 | 1514 |
1448 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 1515 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
1449 | 1516 |
1450 if (prpl_info && prpl_info->get_cb_real_name) | 1517 if (prpl_info && prpl_info->get_cb_real_name) |
1451 real_who = prpl_info->get_cb_real_name(gc, | 1518 real_who = prpl_info->get_cb_real_name(gc, |
1452 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | 1519 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); |
1453 | 1520 |
1499 PurpleConnection *gc = purple_conversation_get_gc(conv); | 1566 PurpleConnection *gc = purple_conversation_get_gc(conv); |
1500 gchar *real_who = NULL; | 1567 gchar *real_who = NULL; |
1501 | 1568 |
1502 g_return_if_fail(gc != NULL); | 1569 g_return_if_fail(gc != NULL); |
1503 | 1570 |
1504 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 1571 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
1505 | 1572 |
1506 if (prpl_info && prpl_info->get_cb_real_name) | 1573 if (prpl_info && prpl_info->get_cb_real_name) |
1507 real_who = prpl_info->get_cb_real_name(gc, | 1574 real_who = prpl_info->get_cb_real_name(gc, |
1508 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | 1575 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); |
1509 | 1576 |
1517 char *who; | 1584 char *who; |
1518 | 1585 |
1519 who = g_object_get_data(G_OBJECT(w), "user_data"); | 1586 who = g_object_get_data(G_OBJECT(w), "user_data"); |
1520 | 1587 |
1521 chat_do_info(gtkconv, who); | 1588 chat_do_info(gtkconv, who); |
1522 } | |
1523 | |
1524 static void | |
1525 menu_chat_get_away_cb(GtkWidget *w, PidginConversation *gtkconv) | |
1526 { | |
1527 PurpleConversation *conv = gtkconv->active_conv; | |
1528 PurplePluginProtocolInfo *prpl_info = NULL; | |
1529 PurpleConnection *gc; | |
1530 char *who; | |
1531 | |
1532 gc = purple_conversation_get_gc(conv); | |
1533 who = g_object_get_data(G_OBJECT(w), "user_data"); | |
1534 | |
1535 if (gc != NULL) { | |
1536 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | |
1537 | |
1538 /* | |
1539 * May want to expand this to work similarly to menu_info_cb? | |
1540 */ | |
1541 | |
1542 if (prpl_info->get_cb_away != NULL) | |
1543 { | |
1544 prpl_info->get_cb_away(gc, | |
1545 purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)), who); | |
1546 } | |
1547 } | |
1548 } | 1589 } |
1549 | 1590 |
1550 static void | 1591 static void |
1551 menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv) | 1592 menu_chat_add_remove_cb(GtkWidget *w, PidginConversation *gtkconv) |
1552 { | 1593 { |
1568 } | 1609 } |
1569 | 1610 |
1570 static GtkTextMark * | 1611 static GtkTextMark * |
1571 get_mark_for_user(PidginConversation *gtkconv, const char *who) | 1612 get_mark_for_user(PidginConversation *gtkconv, const char *who) |
1572 { | 1613 { |
1573 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)); | 1614 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->webview)); |
1574 char *tmp = g_strconcat("user:", who, NULL); | 1615 char *tmp = g_strconcat("user:", who, NULL); |
1575 GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp); | 1616 GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp); |
1576 | 1617 |
1577 g_free(tmp); | 1618 g_free(tmp); |
1578 return mark; | 1619 return mark; |
1579 } | 1620 } |
1580 | 1621 |
1581 static void | 1622 static void |
1582 menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv) | 1623 menu_last_said_cb(GtkWidget *w, PidginConversation *gtkconv) |
1583 { | 1624 { |
1625 /* TODO WEBKIT: This doesn't work yet, of course... */ | |
1626 #if 0 | |
1584 GtkTextMark *mark; | 1627 GtkTextMark *mark; |
1585 const char *who; | 1628 const char *who; |
1586 | 1629 |
1587 who = g_object_get_data(G_OBJECT(w), "user_data"); | 1630 who = g_object_get_data(G_OBJECT(w), "user_data"); |
1588 mark = get_mark_for_user(gtkconv, who); | 1631 mark = get_mark_for_user(gtkconv, who); |
1589 | 1632 |
1590 if (mark != NULL) | 1633 if (mark != NULL) |
1591 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); | 1634 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); |
1592 else | 1635 else |
1593 g_return_if_reached(); | 1636 g_return_if_reached(); |
1637 #endif /* if 0 */ | |
1594 } | 1638 } |
1595 | 1639 |
1596 static GtkWidget * | 1640 static GtkWidget * |
1597 create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc) | 1641 create_chat_menu(PurpleConversation *conv, const char *who, PurpleConnection *gc) |
1598 { | 1642 { |
1599 static GtkWidget *menu = NULL; | 1643 static GtkWidget *menu = NULL; |
1600 PurplePluginProtocolInfo *prpl_info = NULL; | 1644 PurplePluginProtocolInfo *prpl_info = NULL; |
1601 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); | 1645 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); |
1646 PurpleAccount *account = purple_conversation_get_account(conv); | |
1602 gboolean is_me = FALSE; | 1647 gboolean is_me = FALSE; |
1603 GtkWidget *button; | 1648 GtkWidget *button; |
1604 PurpleBuddy *buddy = NULL; | 1649 PurpleBuddy *buddy = NULL; |
1605 | 1650 |
1606 if (gc != NULL) | 1651 if (gc != NULL) |
1607 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 1652 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
1608 | 1653 |
1609 /* | 1654 /* |
1610 * If a menu already exists, destroy it before creating a new one, | 1655 * If a menu already exists, destroy it before creating a new one, |
1611 * thus freeing-up the memory it occupied. | 1656 * thus freeing-up the memory it occupied. |
1612 */ | 1657 */ |
1613 if (menu) | 1658 if (menu) |
1614 gtk_widget_destroy(menu); | 1659 gtk_widget_destroy(menu); |
1615 | 1660 |
1616 if (!strcmp(chat->nick, purple_normalize(conv->account, who))) | 1661 if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, who))) |
1617 is_me = TRUE; | 1662 is_me = TRUE; |
1618 | 1663 |
1619 menu = gtk_menu_new(); | 1664 menu = gtk_menu_new(); |
1620 | 1665 |
1621 if (!is_me) { | 1666 if (!is_me) { |
1676 gtk_widget_set_sensitive(button, FALSE); | 1721 gtk_widget_set_sensitive(button, FALSE); |
1677 else | 1722 else |
1678 g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); | 1723 g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); |
1679 } | 1724 } |
1680 | 1725 |
1681 if (prpl_info && prpl_info->get_cb_away) { | |
1682 button = pidgin_new_item_from_stock(menu, _("Get Away Message"), PIDGIN_STOCK_AWAY, | |
1683 G_CALLBACK(menu_chat_get_away_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); | |
1684 | |
1685 if (gc == NULL) | |
1686 gtk_widget_set_sensitive(button, FALSE); | |
1687 else | |
1688 g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); | |
1689 } | |
1690 | |
1691 if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { | 1726 if (!is_me && prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) { |
1692 if ((buddy = purple_find_buddy(conv->account, who)) != NULL) | 1727 if ((buddy = purple_find_buddy(account, who)) != NULL) |
1693 button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE, | 1728 button = pidgin_new_item_from_stock(menu, _("Remove"), GTK_STOCK_REMOVE, |
1694 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); | 1729 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); |
1695 else | 1730 else |
1696 button = pidgin_new_item_from_stock(menu, _("Add"), GTK_STOCK_ADD, | 1731 button = pidgin_new_item_from_stock(menu, _("Add"), GTK_STOCK_ADD, |
1697 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); | 1732 G_CALLBACK(menu_chat_add_remove_cb), PIDGIN_CONVERSATION(conv), 0, 0, NULL); |
1708 if (!get_mark_for_user(PIDGIN_CONVERSATION(conv), who)) | 1743 if (!get_mark_for_user(PIDGIN_CONVERSATION(conv), who)) |
1709 gtk_widget_set_sensitive(button, FALSE); | 1744 gtk_widget_set_sensitive(button, FALSE); |
1710 | 1745 |
1711 if (buddy != NULL) | 1746 if (buddy != NULL) |
1712 { | 1747 { |
1713 if (purple_account_is_connected(conv->account)) | 1748 if (purple_account_is_connected(account)) |
1714 pidgin_append_blist_node_proto_menu(menu, conv->account->gc, | 1749 pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), |
1715 (PurpleBlistNode *)buddy); | 1750 (PurpleBlistNode *)buddy); |
1716 pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy); | 1751 pidgin_append_blist_node_extended_menu(menu, (PurpleBlistNode *)buddy); |
1717 gtk_widget_show_all(menu); | 1752 gtk_widget_show_all(menu); |
1718 } | 1753 } |
1719 | 1754 |
1735 gchar *who; | 1770 gchar *who; |
1736 | 1771 |
1737 gtkconv = PIDGIN_CONVERSATION(conv); | 1772 gtkconv = PIDGIN_CONVERSATION(conv); |
1738 gtkchat = gtkconv->u.chat; | 1773 gtkchat = gtkconv->u.chat; |
1739 account = purple_conversation_get_account(conv); | 1774 account = purple_conversation_get_account(conv); |
1740 gc = account->gc; | 1775 gc = purple_account_get_connection(account); |
1741 | 1776 |
1742 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 1777 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
1743 | 1778 |
1744 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); | 1779 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list)); |
1745 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) | 1780 if(!gtk_tree_selection_get_selected(sel, NULL, &iter)) |
1771 gchar *who; | 1806 gchar *who; |
1772 int x, y; | 1807 int x, y; |
1773 | 1808 |
1774 gtkchat = gtkconv->u.chat; | 1809 gtkchat = gtkconv->u.chat; |
1775 account = purple_conversation_get_account(conv); | 1810 account = purple_conversation_get_account(conv); |
1776 gc = account->gc; | 1811 gc = purple_account_get_connection(account); |
1777 | 1812 |
1778 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 1813 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
1779 | 1814 |
1780 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), | 1815 gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list), |
1781 event->x, event->y, &path, &column, &x, &y); | 1816 event->x, event->y, &path, &column, &x, &y); |
1803 | 1838 |
1804 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { | 1839 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { |
1805 chat_do_im(gtkconv, who); | 1840 chat_do_im(gtkconv, who); |
1806 } else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { | 1841 } else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { |
1807 /* Move to user's anchor */ | 1842 /* Move to user's anchor */ |
1843 /* TODO WEBKIT: This isn't implemented yet. */ | |
1844 #if 0 | |
1808 GtkTextMark *mark = get_mark_for_user(gtkconv, who); | 1845 GtkTextMark *mark = get_mark_for_user(gtkconv, who); |
1809 | 1846 |
1810 if(mark != NULL) | 1847 if(mark != NULL) |
1811 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); | 1848 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); |
1849 #endif /* if 0 */ | |
1812 } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { | 1850 } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { |
1813 GtkWidget *menu = create_chat_menu (conv, who, gc); | 1851 GtkWidget *menu = create_chat_menu (conv, who, gc); |
1814 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | 1852 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
1815 event->button, event->time); | 1853 event->button, event->time); |
1816 } | 1854 } |
1883 GtkWidget *next = NULL; | 1921 GtkWidget *next = NULL; |
1884 struct { | 1922 struct { |
1885 GtkWidget *from; | 1923 GtkWidget *from; |
1886 GtkWidget *to; | 1924 GtkWidget *to; |
1887 } transitions[] = { | 1925 } transitions[] = { |
1888 {gtkconv->entry, gtkconv->imhtml}, | 1926 {gtkconv->entry, gtkconv->webview}, |
1889 {gtkconv->imhtml, chat ? gtkconv->u.chat->list : gtkconv->entry}, | 1927 {gtkconv->webview, chat ? gtkconv->u.chat->list : gtkconv->entry}, |
1890 {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry}, | 1928 {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry}, |
1891 {NULL, NULL} | 1929 {NULL, NULL} |
1892 }, *ptr; | 1930 }, *ptr; |
1893 | 1931 |
1894 for (ptr = transitions; !next && ptr->from; ptr++) { | 1932 for (ptr = transitions; !next && ptr->from; ptr++) { |
2140 return plugin_return ? TRUE : tab_complete(conv); | 2178 return plugin_return ? TRUE : tab_complete(conv); |
2141 } | 2179 } |
2142 break; | 2180 break; |
2143 | 2181 |
2144 case GDK_Page_Up: | 2182 case GDK_Page_Up: |
2145 case GDK_KP_Page_Up: | 2183 case GDK_KP_Page_Up: |
2184 /* TODO WEBKIT: Write this. */ | |
2185 #if 0 | |
2146 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); | 2186 gtk_imhtml_page_up(GTK_IMHTML(gtkconv->imhtml)); |
2187 #endif /* if 0 */ | |
2147 return TRUE; | 2188 return TRUE; |
2148 break; | 2189 break; |
2149 | 2190 |
2150 case GDK_Page_Down: | 2191 case GDK_Page_Down: |
2151 case GDK_KP_Page_Down: | 2192 case GDK_KP_Page_Down: |
2193 /* TODO WEBKIT: Write this. */ | |
2194 #if 0 | |
2152 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); | 2195 gtk_imhtml_page_down(GTK_IMHTML(gtkconv->imhtml)); |
2196 #endif /* if 0 */ | |
2153 return TRUE; | 2197 return TRUE; |
2154 break; | 2198 break; |
2155 | 2199 |
2156 } | 2200 } |
2157 } | 2201 } |
2234 { | 2278 { |
2235 PidginConversation *gtkconv; | 2279 PidginConversation *gtkconv; |
2236 PurpleConversation *old_conv; | 2280 PurpleConversation *old_conv; |
2237 GtkIMHtml *entry; | 2281 GtkIMHtml *entry; |
2238 const char *protocol_name; | 2282 const char *protocol_name; |
2283 PurpleConnectionFlags features; | |
2239 | 2284 |
2240 g_return_if_fail(conv != NULL); | 2285 g_return_if_fail(conv != NULL); |
2241 | 2286 |
2242 gtkconv = PIDGIN_CONVERSATION(conv); | 2287 gtkconv = PIDGIN_CONVERSATION(conv); |
2243 old_conv = gtkconv->active_conv; | 2288 old_conv = gtkconv->active_conv; |
2255 | 2300 |
2256 purple_conversation_set_logging(conv, | 2301 purple_conversation_set_logging(conv, |
2257 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging))); | 2302 gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(gtkconv->win->menu.logging))); |
2258 | 2303 |
2259 entry = GTK_IMHTML(gtkconv->entry); | 2304 entry = GTK_IMHTML(gtkconv->entry); |
2260 protocol_name = purple_account_get_protocol_name(conv->account); | 2305 protocol_name = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
2261 gtk_imhtml_set_protocol_name(entry, protocol_name); | 2306 gtk_imhtml_set_protocol_name(entry, protocol_name); |
2262 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); | 2307 /* TODO WEBKIT: gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), protocol_name); */ |
2263 | 2308 |
2264 if (!(conv->features & PURPLE_CONNECTION_HTML)) | 2309 features = purple_conversation_get_features(conv); |
2310 if (!(features & PURPLE_CONNECTION_HTML)) | |
2265 gtk_imhtml_clear_formatting(GTK_IMHTML(gtkconv->entry)); | 2311 gtk_imhtml_clear_formatting(GTK_IMHTML(gtkconv->entry)); |
2266 else if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO && | 2312 else if (features & PURPLE_CONNECTION_FORMATTING_WBFO && |
2267 !(old_conv->features & PURPLE_CONNECTION_FORMATTING_WBFO)) | 2313 !(purple_conversation_get_features(old_conv) & PURPLE_CONNECTION_FORMATTING_WBFO)) |
2268 { | 2314 { |
2269 /* The old conversation allowed formatting on parts of the | 2315 /* The old conversation allowed formatting on parts of the |
2270 * buffer, but the new one only allows it on the whole | 2316 * buffer, but the new one only allows it on the whole |
2271 * buffer. This code saves the formatting from the current | 2317 * buffer. This code saves the formatting from the current |
2272 * position of the cursor, clears the formatting, then | 2318 * position of the cursor, clears the formatting, then |
2302 if (underline != underline2) | 2348 if (underline != underline2) |
2303 gtk_imhtml_toggle_underline(entry); | 2349 gtk_imhtml_toggle_underline(entry); |
2304 | 2350 |
2305 gtk_imhtml_toggle_fontface(entry, fontface); | 2351 gtk_imhtml_toggle_fontface(entry, fontface); |
2306 | 2352 |
2307 if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE)) | 2353 if (!(features & PURPLE_CONNECTION_NO_FONTSIZE)) |
2308 gtk_imhtml_font_set_size(entry, fontsize); | 2354 gtk_imhtml_font_set_size(entry, fontsize); |
2309 | 2355 |
2310 gtk_imhtml_toggle_forecolor(entry, forecolor); | 2356 gtk_imhtml_toggle_forecolor(entry, forecolor); |
2311 | 2357 |
2312 if (!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR)) | 2358 if (!(features & PURPLE_CONNECTION_NO_BGCOLOR)) |
2313 { | 2359 { |
2314 gtk_imhtml_toggle_backcolor(entry, backcolor); | 2360 gtk_imhtml_toggle_backcolor(entry, backcolor); |
2315 gtk_imhtml_toggle_background(entry, background); | 2361 gtk_imhtml_toggle_background(entry, background); |
2316 } | 2362 } |
2317 | 2363 |
2325 /* This is done in default_formatize, which is called from clear_formatting_cb, | 2371 /* This is done in default_formatize, which is called from clear_formatting_cb, |
2326 * which is (obviously) a clear_formatting signal handler. However, if we're | 2372 * which is (obviously) a clear_formatting signal handler. However, if we're |
2327 * here, we didn't call gtk_imhtml_clear_formatting() (because we want to | 2373 * here, we didn't call gtk_imhtml_clear_formatting() (because we want to |
2328 * preserve the formatting exactly as it is), so we have to do this now. */ | 2374 * preserve the formatting exactly as it is), so we have to do this now. */ |
2329 gtk_imhtml_set_whole_buffer_formatting_only(entry, | 2375 gtk_imhtml_set_whole_buffer_formatting_only(entry, |
2330 (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO)); | 2376 (features & PURPLE_CONNECTION_FORMATTING_WBFO)); |
2331 } | 2377 } |
2332 | 2378 |
2333 purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv); | 2379 purple_signal_emit(pidgin_conversations_get_handle(), "conversation-switched", conv); |
2334 | 2380 |
2335 gray_stuff_out(gtkconv); | 2381 gray_stuff_out(gtkconv); |
2555 return; | 2601 return; |
2556 | 2602 |
2557 status = infopane_status = pidgin_conv_get_icon_stock(conv); | 2603 status = infopane_status = pidgin_conv_get_icon_stock(conv); |
2558 | 2604 |
2559 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 2605 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
2560 PurpleBuddy *b = purple_find_buddy(conv->account, conv->name); | 2606 PurpleBuddy *b = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
2561 if (b) | 2607 if (b) |
2562 emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b); | 2608 emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b); |
2563 } | 2609 } |
2564 | 2610 |
2565 g_return_if_fail(status != NULL); | 2611 g_return_if_fail(status != NULL); |
2576 CONV_EMBLEM_COLUMN, emblem, -1); | 2622 CONV_EMBLEM_COLUMN, emblem, -1); |
2577 if (emblem) | 2623 if (emblem) |
2578 g_object_unref(emblem); | 2624 g_object_unref(emblem); |
2579 | 2625 |
2580 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) { | 2626 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_protocol_icons")) { |
2581 emblem = pidgin_create_prpl_icon(gtkconv->active_conv->account, PIDGIN_PRPL_ICON_SMALL); | 2627 emblem = pidgin_create_prpl_icon(purple_conversation_get_account(gtkconv->active_conv), PIDGIN_PRPL_ICON_SMALL); |
2582 } else { | 2628 } else { |
2583 emblem = NULL; | 2629 emblem = NULL; |
2584 } | 2630 } |
2585 | 2631 |
2586 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), | 2632 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), |
2632 int size; | 2678 int size; |
2633 | 2679 |
2634 gtkconv = PIDGIN_CONVERSATION(conv); | 2680 gtkconv = PIDGIN_CONVERSATION(conv); |
2635 account = purple_conversation_get_account(conv); | 2681 account = purple_conversation_get_account(conv); |
2636 | 2682 |
2637 if (!(account && account->gc)) { | 2683 if (!(account && purple_account_get_connection(account))) { |
2638 gtkconv->u.im->icon_timer = 0; | 2684 gtkconv->u.im->icon_timer = 0; |
2639 return FALSE; | 2685 return FALSE; |
2640 } | 2686 } |
2641 | 2687 |
2642 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); | 2688 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); |
2839 | 2885 |
2840 g_return_if_fail(conv != NULL); | 2886 g_return_if_fail(conv != NULL); |
2841 | 2887 |
2842 ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv))); | 2888 ext = purple_buddy_icon_get_extension(purple_conv_im_get_icon(PURPLE_CONV_IM(conv))); |
2843 | 2889 |
2844 buf = g_strdup_printf("%s.%s", purple_normalize(conv->account, conv->name), ext); | 2890 buf = g_strdup_printf("%s.%s", purple_normalize(purple_conversation_get_account(conv), purple_conversation_get_name(conv)), ext); |
2845 | 2891 |
2846 purple_request_file(gtkconv, _("Save Icon"), buf, TRUE, | 2892 purple_request_file(gtkconv, _("Save Icon"), buf, TRUE, |
2847 G_CALLBACK(saveicon_writefile_cb), NULL, | 2893 G_CALLBACK(saveicon_writefile_cb), NULL, |
2848 conv->account, NULL, conv, | 2894 purple_conversation_get_account(conv), NULL, conv, |
2849 gtkconv); | 2895 gtkconv); |
2850 | 2896 |
2851 g_free(buf); | 2897 g_free(buf); |
2852 } | 2898 } |
2853 | 2899 |
3183 static gboolean | 3229 static gboolean |
3184 populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolean all) | 3230 populate_menu_with_options(GtkWidget *menu, PidginConversation *gtkconv, gboolean all) |
3185 { | 3231 { |
3186 GList *list; | 3232 GList *list; |
3187 PurpleConversation *conv; | 3233 PurpleConversation *conv; |
3234 PurpleAccount *account; | |
3188 PurpleBlistNode *node = NULL; | 3235 PurpleBlistNode *node = NULL; |
3189 PurpleChat *chat = NULL; | 3236 PurpleChat *chat = NULL; |
3190 PurpleBuddy *buddy = NULL; | 3237 PurpleBuddy *buddy = NULL; |
3191 gboolean ret; | 3238 gboolean ret; |
3192 | 3239 |
3193 conv = gtkconv->active_conv; | 3240 conv = gtkconv->active_conv; |
3241 account = purple_conversation_get_account(conv); | |
3194 | 3242 |
3195 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 3243 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
3196 chat = purple_blist_find_chat(conv->account, conv->name); | 3244 chat = purple_blist_find_chat(account, purple_conversation_get_name(conv)); |
3197 | 3245 |
3198 if ((chat == NULL) && (gtkconv->imhtml != NULL)) { | 3246 if ((chat == NULL) && (gtkconv->webview != NULL)) { |
3199 chat = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat"); | 3247 chat = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat"); |
3200 } | 3248 } |
3201 | 3249 |
3202 if ((chat == NULL) && (gtkconv->imhtml != NULL)) { | 3250 if ((chat == NULL) && (gtkconv->webview != NULL)) { |
3203 GHashTable *components; | 3251 GHashTable *components; |
3204 PurpleAccount *account = purple_conversation_get_account(conv); | 3252 PurpleAccount *account = purple_conversation_get_account(conv); |
3205 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); | 3253 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); |
3206 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); | 3254 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
3207 if (purple_account_get_connection(account) != NULL && | 3255 if (purple_account_get_connection(account) != NULL && |
3212 components = g_hash_table_new_full(g_str_hash, g_str_equal, | 3260 components = g_hash_table_new_full(g_str_hash, g_str_equal, |
3213 g_free, g_free); | 3261 g_free, g_free); |
3214 g_hash_table_replace(components, g_strdup("channel"), | 3262 g_hash_table_replace(components, g_strdup("channel"), |
3215 g_strdup(purple_conversation_get_name(conv))); | 3263 g_strdup(purple_conversation_get_name(conv))); |
3216 } | 3264 } |
3217 chat = purple_chat_new(conv->account, NULL, components); | 3265 chat = purple_chat_new(account, NULL, components); |
3218 purple_blist_node_set_flags((PurpleBlistNode *)chat, | 3266 purple_blist_node_set_flags((PurpleBlistNode *)chat, |
3219 PURPLE_BLIST_NODE_FLAG_NO_SAVE); | 3267 PURPLE_BLIST_NODE_FLAG_NO_SAVE); |
3220 g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_chat", | 3268 g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_chat", |
3221 chat, (GDestroyNotify)purple_blist_remove_chat); | 3269 chat, (GDestroyNotify)purple_blist_remove_chat); |
3222 } | 3270 } |
3223 } else { | 3271 } else { |
3224 if (!purple_account_is_connected(conv->account)) | 3272 if (!purple_account_is_connected(account)) |
3225 return FALSE; | 3273 return FALSE; |
3226 | 3274 |
3227 buddy = purple_find_buddy(conv->account, conv->name); | 3275 buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); |
3228 | 3276 |
3229 /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle | 3277 /* gotta remain bug-compatible :( libpurple < 2.0.2 didn't handle |
3230 * removing "isolated" buddy nodes well */ | 3278 * removing "isolated" buddy nodes well */ |
3231 if (purple_version_check(2, 0, 2) == NULL) { | 3279 if (purple_version_check(2, 0, 2) == NULL) { |
3232 if ((buddy == NULL) && (gtkconv->imhtml != NULL)) { | 3280 if ((buddy == NULL) && (gtkconv->webview != NULL)) { |
3233 buddy = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy"); | 3281 buddy = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); |
3234 } | 3282 } |
3235 | 3283 |
3236 if ((buddy == NULL) && (gtkconv->imhtml != NULL)) { | 3284 if ((buddy == NULL) && (gtkconv->webview != NULL)) { |
3237 buddy = purple_buddy_new(conv->account, conv->name, NULL); | 3285 buddy = purple_buddy_new(account, purple_conversation_get_name(conv), NULL); |
3238 purple_blist_node_set_flags((PurpleBlistNode *)buddy, | 3286 purple_blist_node_set_flags((PurpleBlistNode *)buddy, |
3239 PURPLE_BLIST_NODE_FLAG_NO_SAVE); | 3287 PURPLE_BLIST_NODE_FLAG_NO_SAVE); |
3240 g_object_set_data_full(G_OBJECT(gtkconv->imhtml), "transient_buddy", | 3288 g_object_set_data_full(G_OBJECT(gtkconv->webview), "transient_buddy", |
3241 buddy, (GDestroyNotify)purple_buddy_destroy); | 3289 buddy, (GDestroyNotify)purple_buddy_destroy); |
3242 } | 3290 } |
3243 } | 3291 } |
3244 } | 3292 } |
3245 | 3293 |
3254 pidgin_blist_make_buddy_menu(menu, buddy, TRUE); | 3302 pidgin_blist_make_buddy_menu(menu, buddy, TRUE); |
3255 else if (chat) { | 3303 else if (chat) { |
3256 /* XXX: */ | 3304 /* XXX: */ |
3257 } | 3305 } |
3258 } else if (node) { | 3306 } else if (node) { |
3259 if (purple_account_is_connected(conv->account)) | 3307 if (purple_account_is_connected(account)) |
3260 pidgin_append_blist_node_proto_menu(menu, conv->account->gc, node); | 3308 pidgin_append_blist_node_proto_menu(menu, purple_account_get_connection(account), node); |
3261 pidgin_append_blist_node_extended_menu(menu, node); | 3309 pidgin_append_blist_node_extended_menu(menu, node); |
3262 } | 3310 } |
3263 | 3311 |
3264 if ((list = gtk_container_get_children(GTK_CONTAINER(menu))) == NULL) { | 3312 if ((list = gtk_container_get_children(GTK_CONTAINER(menu))) == NULL) { |
3265 ret = FALSE; | 3313 ret = FALSE; |
3646 #endif | 3694 #endif |
3647 | 3695 |
3648 static void | 3696 static void |
3649 update_typing_message(PidginConversation *gtkconv, const char *message) | 3697 update_typing_message(PidginConversation *gtkconv, const char *message) |
3650 { | 3698 { |
3699 /* TODO WEBKIT: this is not handled at all */ | |
3700 #if 0 | |
3651 GtkTextBuffer *buffer; | 3701 GtkTextBuffer *buffer; |
3652 GtkTextMark *stmark, *enmark; | 3702 GtkTextMark *stmark, *enmark; |
3653 | 3703 |
3654 if (g_object_get_data(G_OBJECT(gtkconv->imhtml), "disable-typing-notification")) | 3704 if (g_object_get_data(G_OBJECT(gtkconv->imhtml), "disable-typing-notification")) |
3655 return; | 3705 return; |
3678 gtk_text_buffer_create_mark(buffer, "typing-notification-start", &iter, TRUE); | 3728 gtk_text_buffer_create_mark(buffer, "typing-notification-start", &iter, TRUE); |
3679 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, message, -1, "TYPING-NOTIFICATION", NULL); | 3729 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, message, -1, "TYPING-NOTIFICATION", NULL); |
3680 gtk_text_buffer_get_end_iter(buffer, &iter); | 3730 gtk_text_buffer_get_end_iter(buffer, &iter); |
3681 gtk_text_buffer_create_mark(buffer, "typing-notification-end", &iter, TRUE); | 3731 gtk_text_buffer_create_mark(buffer, "typing-notification-end", &iter, TRUE); |
3682 } | 3732 } |
3733 #endif /* if 0 */ | |
3683 } | 3734 } |
3684 | 3735 |
3685 static void | 3736 static void |
3686 update_typing_icon(PidginConversation *gtkconv) | 3737 update_typing_icon(PidginConversation *gtkconv) |
3687 { | 3738 { |
3734 return FALSE; | 3785 return FALSE; |
3735 | 3786 |
3736 if (win->menu.send_to == NULL) | 3787 if (win->menu.send_to == NULL) |
3737 return FALSE; | 3788 return FALSE; |
3738 | 3789 |
3739 if (!(b = purple_find_buddy(account, conv->name))) | 3790 if (!(b = purple_find_buddy(account, purple_conversation_get_name(conv)))) |
3740 return FALSE; | 3791 return FALSE; |
3741 | 3792 |
3742 | 3793 |
3743 gtk_widget_show(win->menu.send_to); | 3794 gtk_widget_show(win->menu.send_to); |
3744 | 3795 |
3894 win->menu.send_to, 2); | 3945 win->menu.send_to, 2); |
3895 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.send_to), menu); | 3946 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win->menu.send_to), menu); |
3896 | 3947 |
3897 gtk_widget_show(menu); | 3948 gtk_widget_show(menu); |
3898 | 3949 |
3899 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM) { | 3950 if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM) { |
3900 buds = purple_find_buddies(gtkconv->active_conv->account, gtkconv->active_conv->name); | 3951 buds = purple_find_buddies(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv)); |
3901 | 3952 |
3902 if (buds == NULL) | 3953 if (buds == NULL) |
3903 { | 3954 { |
3904 /* The user isn't on the buddy list. So we don't create any sendto menu. */ | 3955 /* The user isn't on the buddy list. So we don't create any sendto menu. */ |
3905 } | 3956 } |
3919 | 3970 |
3920 if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) | 3971 if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) |
3921 continue; | 3972 continue; |
3922 | 3973 |
3923 account = purple_buddy_get_account(buddy); | 3974 account = purple_buddy_get_account(buddy); |
3924 if (purple_account_is_connected(account) || account == gtkconv->active_conv->account) | 3975 /* TODO WEBKIT: (I'm not actually sure if this is webkit-related --Mark Doliner) */ |
3976 if (purple_account_is_connected(account) /*|| account == purple_conversation_get_account(gtkconv->active_conv)*/) | |
3925 { | 3977 { |
3926 /* Use the PurplePresence to get unique buddies. */ | 3978 /* Use the PurplePresence to get unique buddies. */ |
3927 PurplePresence *presence = purple_buddy_get_presence(buddy); | 3979 PurplePresence *presence = purple_buddy_get_presence(buddy); |
3928 if (!g_list_find_custom(list, presence, (GCompareFunc)compare_buddy_presence)) | 3980 if (!g_list_find_custom(list, presence, (GCompareFunc)compare_buddy_presence)) |
3929 list = g_list_prepend(list, presence); | 3981 list = g_list_prepend(list, presence); |
3978 } | 4030 } |
3979 | 4031 |
3980 static void | 4032 static void |
3981 deleting_chat_buddy_cb(PurpleConvChatBuddy *cb) | 4033 deleting_chat_buddy_cb(PurpleConvChatBuddy *cb) |
3982 { | 4034 { |
3983 if (cb->ui_data) { | 4035 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); |
3984 GtkTreeRowReference *ref = cb->ui_data; | 4036 |
4037 if (ref) { | |
3985 gtk_tree_row_reference_free(ref); | 4038 gtk_tree_row_reference_free(ref); |
3986 cb->ui_data = NULL; | 4039 purple_conv_chat_cb_set_ui_data(cb, NULL); |
3987 } | 4040 } |
3988 } | 4041 } |
3989 | 4042 |
3990 static void | 4043 static void |
3991 add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name) | 4044 add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name) |
4000 GtkTreePath *newpath; | 4053 GtkTreePath *newpath; |
4001 const char *stock; | 4054 const char *stock; |
4002 GtkTreeIter iter; | 4055 GtkTreeIter iter; |
4003 gboolean is_me = FALSE; | 4056 gboolean is_me = FALSE; |
4004 gboolean is_buddy; | 4057 gboolean is_buddy; |
4005 gchar *tmp, *alias_key, *name, *alias; | 4058 const gchar *name, *alias; |
4059 gchar *tmp, *alias_key; | |
4006 PurpleConvChatBuddyFlags flags; | 4060 PurpleConvChatBuddyFlags flags; |
4007 GdkColor *color = NULL; | 4061 GdkColor *color = NULL; |
4008 | 4062 |
4009 alias = cb->alias; | 4063 alias = purple_conv_chat_cb_get_alias(cb); |
4010 name = cb->name; | 4064 name = purple_conv_chat_cb_get_name(cb); |
4011 flags = cb->flags; | 4065 flags = purple_conv_chat_cb_get_flags(cb); |
4012 | 4066 |
4013 chat = PURPLE_CONV_CHAT(conv); | 4067 chat = PURPLE_CONV_CHAT(conv); |
4014 gtkconv = PIDGIN_CONVERSATION(conv); | 4068 gtkconv = PIDGIN_CONVERSATION(conv); |
4015 gtkchat = gtkconv->u.chat; | 4069 gtkchat = gtkconv->u.chat; |
4016 gc = purple_conversation_get_gc(conv); | 4070 gc = purple_conversation_get_gc(conv); |
4017 | 4071 |
4018 if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl))) | 4072 if (!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)))) |
4019 return; | 4073 return; |
4020 | 4074 |
4021 tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); | 4075 tm = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list)); |
4022 ls = GTK_LIST_STORE(tm); | 4076 ls = GTK_LIST_STORE(tm); |
4023 | 4077 |
4024 stock = get_chat_buddy_status_icon(chat, name, flags); | 4078 stock = get_chat_buddy_status_icon(chat, name, flags); |
4025 | 4079 |
4026 if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name))) | 4080 if (!strcmp(purple_conv_chat_get_nick(chat), purple_normalize(purple_conversation_get_account(conv), old_name != NULL ? old_name : name))) |
4027 is_me = TRUE; | 4081 is_me = TRUE; |
4028 | 4082 |
4029 is_buddy = cb->buddy; | 4083 is_buddy = purple_conv_chat_cb_is_buddy(cb); |
4030 | 4084 |
4031 tmp = g_utf8_casefold(alias, -1); | 4085 tmp = g_utf8_casefold(alias, -1); |
4032 alias_key = g_utf8_collate_key(tmp, -1); | 4086 alias_key = g_utf8_collate_key(tmp, -1); |
4033 g_free(tmp); | 4087 g_free(tmp); |
4034 | 4088 |
4035 if (is_me) { | 4089 if (is_me) { |
4090 #if 0 | |
4091 /* TODO WEBKIT: No tags in webkit stuff, yet. */ | |
4036 GtkTextTag *tag = gtk_text_tag_table_lookup( | 4092 GtkTextTag *tag = gtk_text_tag_table_lookup( |
4037 gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->imhtml)->text_buffer), | 4093 gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->webview)->text_buffer), |
4038 "send-name"); | 4094 "send-name"); |
4039 g_object_get(tag, "foreground-gdk", &color, NULL); | 4095 g_object_get(tag, "foreground-gdk", &color, NULL); |
4096 #endif /* if 0 */ | |
4040 } else { | 4097 } else { |
4041 GtkTextTag *tag; | 4098 GtkTextTag *tag; |
4042 if ((tag = get_buddy_tag(conv, name, 0, FALSE))) | 4099 if ((tag = get_buddy_tag(conv, name, 0, FALSE))) |
4043 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL); | 4100 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_NORMAL, NULL); |
4044 if ((tag = get_buddy_tag(conv, name, PURPLE_MESSAGE_NICK, FALSE))) | 4101 if ((tag = get_buddy_tag(conv, name, PURPLE_MESSAGE_NICK, FALSE))) |
4062 CHAT_USERS_FLAGS_COLUMN, flags, | 4119 CHAT_USERS_FLAGS_COLUMN, flags, |
4063 CHAT_USERS_COLOR_COLUMN, color, | 4120 CHAT_USERS_COLOR_COLUMN, color, |
4064 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, | 4121 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
4065 -1); | 4122 -1); |
4066 | 4123 |
4067 if (cb->ui_data) { | 4124 if (purple_conv_chat_cb_get_ui_data(cb)) { |
4068 GtkTreeRowReference *ref = cb->ui_data; | 4125 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); |
4069 gtk_tree_row_reference_free(ref); | 4126 gtk_tree_row_reference_free(ref); |
4070 } | 4127 } |
4071 | 4128 |
4072 newpath = gtk_tree_model_get_path(tm, &iter); | 4129 newpath = gtk_tree_model_get_path(tm, &iter); |
4073 cb->ui_data = gtk_tree_row_reference_new(tm, newpath); | 4130 purple_conv_chat_cb_set_ui_data(cb, gtk_tree_row_reference_new(tm, newpath)); |
4074 gtk_tree_path_free(newpath); | 4131 gtk_tree_path_free(newpath); |
4075 | 4132 |
4076 if (is_me && color) | 4133 if (is_me && color) |
4077 gdk_color_free(color); | 4134 gdk_color_free(color); |
4078 g_free(alias_key); | 4135 g_free(alias_key); |
4098 * @param name The buddy name or alias or slash command name that we're | 4155 * @param name The buddy name or alias or slash command name that we're |
4099 * checking for a match. | 4156 * checking for a match. |
4100 */ | 4157 */ |
4101 static void | 4158 static void |
4102 tab_complete_process_item(int *most_matched, const char *entered, gsize entered_bytes, char **partial, char *nick_partial, | 4159 tab_complete_process_item(int *most_matched, const char *entered, gsize entered_bytes, char **partial, char *nick_partial, |
4103 GList **matches, char *name) | 4160 GList **matches, const char *name) |
4104 { | 4161 { |
4105 memcpy(nick_partial, name, entered_bytes); | 4162 memcpy(nick_partial, name, entered_bytes); |
4106 if (purple_utf8_strcasecmp(nick_partial, entered)) | 4163 if (purple_utf8_strcasecmp(nick_partial, entered)) |
4107 return; | 4164 return; |
4108 | 4165 |
4220 int f; | 4277 int f; |
4221 | 4278 |
4222 /* Users */ | 4279 /* Users */ |
4223 for (; l != NULL; l = l->next) { | 4280 for (; l != NULL; l = l->next) { |
4224 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, | 4281 tab_complete_process_item(&most_matched, entered, entered_bytes, &partial, nick_partial, |
4225 &matches, ((PurpleConvChatBuddy *)l->data)->name); | 4282 &matches, purple_conv_chat_cb_get_name((PurpleConvChatBuddy *)l->data)); |
4226 } | 4283 } |
4227 | 4284 |
4228 | 4285 |
4229 /* Aliases */ | 4286 /* Aliases */ |
4230 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 4287 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
4320 char *new_topic; | 4377 char *new_topic; |
4321 const char *current_topic; | 4378 const char *current_topic; |
4322 | 4379 |
4323 gc = purple_conversation_get_gc(conv); | 4380 gc = purple_conversation_get_gc(conv); |
4324 | 4381 |
4325 if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl))) | 4382 if(!gc || !(prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)))) |
4326 return; | 4383 return; |
4327 | 4384 |
4328 if(prpl_info->set_chat_topic == NULL) | 4385 if(prpl_info->set_chat_topic == NULL) |
4329 return; | 4386 return; |
4330 | 4387 |
4395 static void | 4452 static void |
4396 update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection *gc, PurplePluginProtocolInfo *prpl_info) | 4453 update_chat_alias(PurpleBuddy *buddy, PurpleConversation *conv, PurpleConnection *gc, PurplePluginProtocolInfo *prpl_info) |
4397 { | 4454 { |
4398 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); | 4455 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
4399 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); | 4456 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); |
4457 PurpleAccount *account = purple_conversation_get_account(conv); | |
4400 GtkTreeModel *model; | 4458 GtkTreeModel *model; |
4401 char *normalized_name; | 4459 char *normalized_name; |
4402 GtkTreeIter iter; | 4460 GtkTreeIter iter; |
4403 int f; | 4461 int f; |
4404 | 4462 |
4409 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list)); | 4467 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list)); |
4410 | 4468 |
4411 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 4469 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
4412 return; | 4470 return; |
4413 | 4471 |
4414 normalized_name = g_strdup(purple_normalize(conv->account, buddy->name)); | 4472 normalized_name = g_strdup(purple_normalize(account, buddy->name)); |
4415 | 4473 |
4416 do { | 4474 do { |
4417 char *name; | 4475 char *name; |
4418 | 4476 |
4419 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); | 4477 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); |
4420 | 4478 |
4421 if (!strcmp(normalized_name, purple_normalize(conv->account, name))) { | 4479 if (!strcmp(normalized_name, purple_normalize(account, name))) { |
4422 const char *alias = name; | 4480 const char *alias = name; |
4423 char *tmp; | 4481 char *tmp; |
4424 char *alias_key = NULL; | 4482 char *alias_key = NULL; |
4425 PurpleBuddy *buddy2; | 4483 PurpleBuddy *buddy2; |
4426 | 4484 |
4427 if (strcmp(chat->nick, purple_normalize(conv->account, name))) { | 4485 if (strcmp(purple_conv_chat_get_nick(chat), purple_normalize(account, name))) { |
4428 /* This user is not me, so look into updating the alias. */ | 4486 /* This user is not me, so look into updating the alias. */ |
4429 | 4487 |
4430 if ((buddy2 = purple_find_buddy(conv->account, name)) != NULL) { | 4488 if ((buddy2 = purple_find_buddy(account, name)) != NULL) { |
4431 alias = purple_buddy_get_contact_alias(buddy2); | 4489 alias = purple_buddy_get_contact_alias(buddy2); |
4432 } | 4490 } |
4433 | 4491 |
4434 tmp = g_utf8_casefold(alias, -1); | 4492 tmp = g_utf8_casefold(alias, -1); |
4435 alias_key = g_utf8_collate_key(tmp, -1); | 4493 alias_key = g_utf8_collate_key(tmp, -1); |
4462 g_return_if_fail(node != NULL); | 4520 g_return_if_fail(node != NULL); |
4463 g_return_if_fail(conv != NULL); | 4521 g_return_if_fail(conv != NULL); |
4464 | 4522 |
4465 gc = purple_conversation_get_gc(conv); | 4523 gc = purple_conversation_get_gc(conv); |
4466 g_return_if_fail(gc != NULL); | 4524 g_return_if_fail(gc != NULL); |
4467 g_return_if_fail(gc->prpl != NULL); | 4525 g_return_if_fail(purple_connection_get_prpl(gc) != NULL); |
4468 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 4526 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
4469 | 4527 |
4470 if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) | 4528 if (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) |
4471 return; | 4529 return; |
4472 | 4530 |
4473 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) | 4531 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) |
4512 model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list)); | 4570 model = gtk_tree_view_get_model(GTK_TREE_VIEW(PIDGIN_CONVERSATION(conv)->u.chat->list)); |
4513 | 4571 |
4514 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 4572 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
4515 return; | 4573 return; |
4516 | 4574 |
4517 normalized_name = g_strdup(purple_normalize(conv->account, buddy->name)); | 4575 normalized_name = g_strdup(purple_normalize(purple_conversation_get_account(conv), buddy->name)); |
4518 | 4576 |
4519 do { | 4577 do { |
4520 char *name; | 4578 char *name; |
4521 | 4579 |
4522 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); | 4580 gtk_tree_model_get(model, &iter, CHAT_USERS_NAME_COLUMN, &name, -1); |
4523 | 4581 |
4524 if (!strcmp(normalized_name, purple_normalize(conv->account, name))) { | 4582 if (!strcmp(normalized_name, purple_normalize(purple_conversation_get_account(conv), name))) { |
4525 gtk_list_store_set(GTK_LIST_STORE(model), &iter, | 4583 gtk_list_store_set(GTK_LIST_STORE(model), &iter, |
4526 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1); | 4584 CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1); |
4527 g_free(name); | 4585 g_free(name); |
4528 break; | 4586 break; |
4529 } | 4587 } |
4598 GtkTextIter iter; | 4656 GtkTextIter iter; |
4599 int lines; | 4657 int lines; |
4600 GdkRectangle oneline; | 4658 GdkRectangle oneline; |
4601 int height, diff; | 4659 int height, diff; |
4602 int pad_top, pad_inside, pad_bottom; | 4660 int pad_top, pad_inside, pad_bottom; |
4603 int total_height = (gtkconv->imhtml->allocation.height + gtkconv->entry->allocation.height); | 4661 int total_height = (gtkconv->webview->allocation.height + gtkconv->entry->allocation.height); |
4604 int max_height = total_height / 2; | 4662 int max_height = total_height / 2; |
4605 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines"); | 4663 int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines"); |
4606 int min_height; | 4664 int min_height; |
4607 gboolean interior_focus; | 4665 gboolean interior_focus; |
4608 int focus_width; | 4666 int focus_width; |
4671 static void | 4729 static void |
4672 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) | 4730 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) |
4673 { | 4731 { |
4674 PurpleConversation *conv = gtkconv->active_conv; | 4732 PurpleConversation *conv = gtkconv->active_conv; |
4675 PurpleConnection *gc = purple_conversation_get_gc(conv); | 4733 PurpleConnection *gc = purple_conversation_get_gc(conv); |
4676 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 4734 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
4677 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) | 4735 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) |
4678 { | 4736 { |
4679 GtkWidget *hbox, *label; | 4737 GtkWidget *hbox, *label; |
4680 PidginChatPane *gtkchat = gtkconv->u.chat; | 4738 PidginChatPane *gtkchat = gtkconv->u.chat; |
4681 | 4739 |
4712 PurpleBlistNode *node; | 4770 PurpleBlistNode *node; |
4713 PurplePluginProtocolInfo *prpl_info; | 4771 PurplePluginProtocolInfo *prpl_info; |
4714 PurpleAccount *account = purple_conversation_get_account(conv); | 4772 PurpleAccount *account = purple_conversation_get_account(conv); |
4715 char *who = NULL; | 4773 char *who = NULL; |
4716 | 4774 |
4717 if (account->gc == NULL) | 4775 if (purple_account_get_connection(account) == NULL) |
4718 return FALSE; | 4776 return FALSE; |
4719 | 4777 |
4720 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)) | 4778 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path)) |
4721 return FALSE; | 4779 return FALSE; |
4722 | 4780 |
4723 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); | 4781 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); |
4724 | 4782 |
4725 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl); | 4783 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(purple_account_get_connection(account))); |
4726 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who)); | 4784 node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), who)); |
4727 if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) | 4785 if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME)) |
4728 pidgin_blist_draw_tooltip(node, gtkconv->infopane); | 4786 pidgin_blist_draw_tooltip(node, gtkconv->infopane); |
4729 | 4787 |
4730 g_free(who); | 4788 g_free(who); |
4731 return FALSE; | 4789 return FALSE; |
4822 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); | 4880 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); |
4823 gtk_widget_show(list); | 4881 gtk_widget_show(list); |
4824 | 4882 |
4825 gtkchat->list = list; | 4883 gtkchat->list = list; |
4826 | 4884 |
4827 gtk_box_pack_start(GTK_BOX(lbox), | 4885 gtk_box_pack_start(GTK_BOX(lbox), |
4828 pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), | 4886 pidgin_make_scrollable(list, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1), |
4829 TRUE, TRUE, 0); | 4887 TRUE, TRUE, 0); |
4830 } | 4888 } |
4831 | 4889 |
4832 static gboolean | 4890 static gboolean |
4836 PurpleConversation *conv; | 4894 PurpleConversation *conv; |
4837 PidginConversation *gtkconv = userdata; | 4895 PidginConversation *gtkconv = userdata; |
4838 | 4896 |
4839 conv = gtkconv->active_conv; | 4897 conv = gtkconv->active_conv; |
4840 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { | 4898 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
4841 node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name)); | 4899 node = (PurpleBlistNode*)(purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv))); |
4842 if (!node) | 4900 if (!node) |
4843 node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat"); | 4901 node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_chat"); |
4844 } else { | 4902 } else { |
4845 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, conv->name)); | 4903 node = (PurpleBlistNode*)(purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv))); |
4846 #if 0 | 4904 #if 0 |
4847 /* Using the transient blist nodes to show the tooltip doesn't quite work yet. */ | 4905 /* Using the transient blist nodes to show the tooltip doesn't quite work yet. */ |
4848 if (!node) | 4906 if (!node) |
4849 node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy"); | 4907 node = g_object_get_data(G_OBJECT(gtkconv->webview), "transient_buddy"); |
4850 #endif | 4908 #endif |
4851 } | 4909 } |
4852 | 4910 |
4853 if (node) | 4911 if (node) |
4854 pidgin_blist_draw_tooltip(node, gtkconv->infopane); | 4912 pidgin_blist_draw_tooltip(node, gtkconv->infopane); |
4859 static gboolean | 4917 static gboolean |
4860 pidgin_conv_end_quickfind(PidginConversation *gtkconv) | 4918 pidgin_conv_end_quickfind(PidginConversation *gtkconv) |
4861 { | 4919 { |
4862 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); | 4920 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); |
4863 | 4921 |
4864 gtk_imhtml_search_clear(GTK_IMHTML(gtkconv->imhtml)); | 4922 webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(gtkconv->webview)); |
4865 gtk_widget_hide_all(gtkconv->quickfind.container); | 4923 gtk_widget_hide_all(gtkconv->quickfind.container); |
4866 | 4924 |
4867 gtk_widget_grab_focus(gtkconv->entry); | 4925 gtk_widget_grab_focus(gtkconv->entry); |
4868 return TRUE; | 4926 return TRUE; |
4869 } | 4927 } |
4872 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv) | 4930 quickfind_process_input(GtkWidget *entry, GdkEventKey *event, PidginConversation *gtkconv) |
4873 { | 4931 { |
4874 switch (event->keyval) { | 4932 switch (event->keyval) { |
4875 case GDK_Return: | 4933 case GDK_Return: |
4876 case GDK_KP_Enter: | 4934 case GDK_KP_Enter: |
4877 if (gtk_imhtml_search_find(GTK_IMHTML(gtkconv->imhtml), gtk_entry_get_text(GTK_ENTRY(entry)))) { | 4935 if (webkit_web_view_search_text(WEBKIT_WEB_VIEW(gtkconv->webview), gtk_entry_get_text(GTK_ENTRY(entry)), FALSE, TRUE, TRUE)) { |
4878 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); | 4936 gtk_widget_modify_base(gtkconv->quickfind.entry, GTK_STATE_NORMAL, NULL); |
4879 } else { | 4937 } else { |
4880 GdkColor col; | 4938 GdkColor col; |
4881 col.red = 0xffff; | 4939 col.red = 0xffff; |
4882 col.green = 0xafff; | 4940 col.green = 0xafff; |
4922 G_CALLBACK(pidgin_conv_end_quickfind), gtkconv); | 4980 G_CALLBACK(pidgin_conv_end_quickfind), gtkconv); |
4923 } | 4981 } |
4924 | 4982 |
4925 /* }}} */ | 4983 /* }}} */ |
4926 | 4984 |
4985 static char * | |
4986 replace_header_tokens(PurpleConversation *conv, const char *text) | |
4987 { | |
4988 PurpleAccount *account = purple_conversation_get_account(conv); | |
4989 GString *str; | |
4990 const char *cur = text; | |
4991 const char *prev = cur; | |
4992 | |
4993 if (text == NULL || *text == '\0') | |
4994 return NULL; | |
4995 | |
4996 str = g_string_new(NULL); | |
4997 while ((cur = strchr(cur, '%'))) { | |
4998 const char *replace = NULL; | |
4999 const char *fin = NULL; | |
5000 | |
5001 if (g_str_has_prefix(cur, "%chatName%")) { | |
5002 replace = purple_conversation_get_name(conv); | |
5003 | |
5004 } else if (g_str_has_prefix(cur, "%sourceName%")) { | |
5005 replace = purple_account_get_alias(account); | |
5006 if (replace == NULL) | |
5007 replace = purple_account_get_username(account); | |
5008 | |
5009 } else if (g_str_has_prefix(cur, "%destinationName%")) { | |
5010 PurpleBuddy *buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); | |
5011 if (buddy) { | |
5012 replace = purple_buddy_get_alias(buddy); | |
5013 } else { | |
5014 replace = purple_conversation_get_name(conv); | |
5015 } | |
5016 | |
5017 } else if (g_str_has_prefix(cur, "%incomingIconPath%")) { | |
5018 PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); | |
5019 if (icon) | |
5020 replace = purple_buddy_icon_get_full_path(icon); | |
5021 | |
5022 } else if (g_str_has_prefix(cur, "%outgoingIconPath%")) { | |
5023 replace = purple_account_get_buddy_icon_path(account); | |
5024 | |
5025 } else if (g_str_has_prefix(cur, "%timeOpened")) { | |
5026 const char *tmp = cur + strlen("%timeOpened"); | |
5027 char *format = NULL; | |
5028 if (*tmp == '{') { | |
5029 const char *end; | |
5030 tmp++; | |
5031 end = strstr(tmp, "}%"); | |
5032 if (!end) /* Invalid string */ | |
5033 continue; | |
5034 format = g_strndup(tmp, end - tmp); | |
5035 fin = end + 1; | |
5036 } | |
5037 replace = purple_utf8_strftime(format ? format : "%X", NULL); | |
5038 g_free(format); | |
5039 | |
5040 } else { | |
5041 continue; | |
5042 } | |
5043 | |
5044 /* Here we have a replacement to make */ | |
5045 g_string_append_len(str, prev, cur - prev); | |
5046 if (replace) | |
5047 g_string_append(str, replace); | |
5048 | |
5049 /* And update the pointers */ | |
5050 if (fin) { | |
5051 prev = cur = fin + 1; | |
5052 } else { | |
5053 prev = cur = strchr(cur + 1, '%') + 1; | |
5054 } | |
5055 } | |
5056 | |
5057 /* And wrap it up */ | |
5058 g_string_append(str, prev); | |
5059 return g_string_free(str, FALSE); | |
5060 } | |
5061 | |
5062 static char * | |
5063 replace_template_tokens(PidginConvTheme *theme, const char *header, const char *footer) | |
5064 { | |
5065 GString *str; | |
5066 const char *text; | |
5067 char **ms; | |
5068 char *path; | |
5069 | |
5070 text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN); | |
5071 if (text == NULL) | |
5072 return NULL; | |
5073 | |
5074 ms = g_strsplit(text, "%@", 6); | |
5075 if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) { | |
5076 g_strfreev(ms); | |
5077 return NULL; | |
5078 } | |
5079 | |
5080 str = g_string_new(NULL); | |
5081 | |
5082 g_string_append(str, ms[0]); | |
5083 g_string_append(str, "file://"); | |
5084 path = pidgin_conversation_theme_get_template_path(theme); | |
5085 g_string_append(str, path); | |
5086 g_free(path); | |
5087 | |
5088 g_string_append(str, ms[1]); | |
5089 | |
5090 text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS); | |
5091 g_string_append(str, text); | |
5092 | |
5093 g_string_append(str, ms[2]); | |
5094 | |
5095 g_string_append(str, "file://"); | |
5096 path = pidgin_conversation_theme_get_css_path(theme); | |
5097 g_string_append(str, path); | |
5098 g_free(path); | |
5099 | |
5100 g_string_append(str, ms[3]); | |
5101 if (header) | |
5102 g_string_append(str, header); | |
5103 g_string_append(str, ms[4]); | |
5104 if (footer) | |
5105 g_string_append(str, footer); | |
5106 g_string_append(str, ms[5]); | |
5107 | |
5108 g_strfreev(ms); | |
5109 | |
5110 return g_string_free(str, FALSE); | |
5111 } | |
5112 | |
5113 static void | |
5114 set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme) | |
5115 { | |
5116 WebKitWebSettings *settings; | |
5117 const GValue *val; | |
5118 | |
5119 g_object_get(G_OBJECT(webview), "settings", &settings, NULL); | |
5120 | |
5121 val = pidgin_conversation_theme_lookup(theme, "DefaultFontFamily", TRUE); | |
5122 if (val && G_VALUE_HOLDS_STRING(val)) | |
5123 g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL); | |
5124 | |
5125 val = pidgin_conversation_theme_lookup(theme, "DefaultFontSize", TRUE); | |
5126 if (val && G_VALUE_HOLDS_INT(val)) | |
5127 g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL); | |
5128 | |
5129 val = pidgin_conversation_theme_lookup(theme, "DefaultBackgroundIsTransparent", TRUE); | |
5130 if (val && G_VALUE_HOLDS_BOOLEAN(val)) | |
5131 /* this does not work :( */ | |
5132 webkit_web_view_set_transparent(webview, g_value_get_boolean(val)); | |
5133 } | |
5134 | |
5135 static void | |
5136 conv_variant_changed_cb(GObject *gobject, GParamSpec *pspec, gpointer user_data) | |
5137 { | |
5138 PidginConversation *gtkconv = user_data; | |
5139 const char *path; | |
5140 char *js; | |
5141 | |
5142 path = pidgin_conversation_theme_get_css_path(PIDGIN_CONV_THEME(gobject)); | |
5143 js = g_strdup_printf("setStylesheet(\"mainStyle\", \"file://%s\");", path); | |
5144 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), js); | |
5145 g_free(js); | |
5146 } | |
5147 | |
4927 static GtkWidget * | 5148 static GtkWidget * |
4928 setup_common_pane(PidginConversation *gtkconv) | 5149 setup_common_pane(PidginConversation *gtkconv) |
4929 { | 5150 { |
4930 GtkWidget *vbox, *frame, *imhtml_sw, *event_box; | 5151 GtkWidget *vbox, *frame, *webview_sw, *event_box; |
4931 GtkCellRenderer *rend; | 5152 GtkCellRenderer *rend; |
4932 GtkTreePath *path; | 5153 GtkTreePath *path; |
4933 PurpleConversation *conv = gtkconv->active_conv; | 5154 PurpleConversation *conv = gtkconv->active_conv; |
4934 PurpleBuddy *buddy; | 5155 PurpleBuddy *buddy; |
4935 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); | 5156 gboolean chat = (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT); |
4936 int buddyicon_size = 0; | 5157 int buddyicon_size = 0; |
5158 char *header, *footer; | |
5159 char *template; | |
4937 | 5160 |
4938 /* Setup the top part of the pane */ | 5161 /* Setup the top part of the pane */ |
4939 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 5162 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4940 gtk_widget_show(vbox); | 5163 gtk_widget_show(vbox); |
4941 | 5164 |
5021 rend = gtk_cell_renderer_pixbuf_new(); | 5244 rend = gtk_cell_renderer_pixbuf_new(); |
5022 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE); | 5245 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE); |
5023 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL); | 5246 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL); |
5024 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); | 5247 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); |
5025 | 5248 |
5026 /* Setup the gtkimhtml widget */ | 5249 /* Setup the webkit widget */ |
5027 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); | 5250 frame = pidgin_create_webview(FALSE, >kconv->webview, NULL, &webview_sw); |
5028 gtk_widget_set_size_request(gtkconv->imhtml, -1, 0); | 5251 gtk_widget_set_size_request(gtkconv->webview, -1, 0); |
5252 | |
5253 header = replace_header_tokens(conv, | |
5254 pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER)); | |
5255 footer = replace_header_tokens(conv, | |
5256 pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER)); | |
5257 template = replace_template_tokens(gtkconv->theme, header, footer); | |
5258 g_free(header); | |
5259 g_free(footer); | |
5260 | |
5261 if (template != NULL) { | |
5262 char *basedir; | |
5263 char *baseuri; | |
5264 | |
5265 purple_debug_info("webkit", "template: %s\n", template); | |
5266 | |
5267 set_theme_webkit_settings(WEBKIT_WEB_VIEW(gtkconv->webview), gtkconv->theme); | |
5268 | |
5269 basedir = pidgin_conversation_theme_get_template_path(gtkconv->theme); | |
5270 baseuri = g_strdup_printf("file://%s", basedir); | |
5271 webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtkconv->webview), template, "text/html", "UTF-8", baseuri); | |
5272 | |
5273 if (chat) | |
5274 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), "document.getElementById('Chat').className = 'groupchat'"); | |
5275 | |
5276 g_signal_connect(G_OBJECT(gtkconv->theme), "notify::variant", | |
5277 G_CALLBACK(conv_variant_changed_cb), gtkconv); | |
5278 | |
5279 g_free(basedir); | |
5280 g_free(baseuri); | |
5281 g_free(template); | |
5282 } | |
5283 | |
5029 if (chat) { | 5284 if (chat) { |
5030 GtkWidget *hpaned; | 5285 GtkWidget *hpaned; |
5031 | 5286 |
5032 /* Add the topic */ | 5287 /* Add the topic */ |
5033 setup_chat_topic(gtkconv, vbox); | 5288 setup_chat_topic(gtkconv, vbox); |
5041 /* Now add the userlist */ | 5296 /* Now add the userlist */ |
5042 setup_chat_userlist(gtkconv, hpaned); | 5297 setup_chat_userlist(gtkconv, hpaned); |
5043 } else { | 5298 } else { |
5044 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | 5299 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
5045 } | 5300 } |
5046 gtk_widget_show(frame); | 5301 gtk_widget_show_all(frame); |
5047 | 5302 |
5048 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); | 5303 gtk_widget_set_name(gtkconv->webview, "pidgin_conv_webview"); |
5049 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); | 5304 g_object_set_data(G_OBJECT(gtkconv->webview), "gtkconv", gtkconv); |
5050 g_object_set_data(G_OBJECT(gtkconv->imhtml), "gtkconv", gtkconv); | 5305 |
5051 | 5306 g_signal_connect_after(G_OBJECT(gtkconv->webview), "button_press_event", |
5052 g_object_set(G_OBJECT(imhtml_sw), "vscrollbar-policy", GTK_POLICY_ALWAYS, NULL); | |
5053 | |
5054 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", | |
5055 G_CALLBACK(entry_stop_rclick_cb), NULL); | 5307 G_CALLBACK(entry_stop_rclick_cb), NULL); |
5056 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", | 5308 g_signal_connect(G_OBJECT(gtkconv->webview), "key_press_event", |
5057 G_CALLBACK(refocus_entry_cb), gtkconv); | 5309 G_CALLBACK(refocus_entry_cb), gtkconv); |
5058 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", | 5310 g_signal_connect(G_OBJECT(gtkconv->webview), "key_release_event", |
5059 G_CALLBACK(refocus_entry_cb), gtkconv); | 5311 G_CALLBACK(refocus_entry_cb), gtkconv); |
5060 | 5312 |
5061 pidgin_conv_setup_quickfind(gtkconv, vbox); | 5313 pidgin_conv_setup_quickfind(gtkconv, vbox); |
5062 | 5314 |
5063 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 5315 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
5069 gtk_box_pack_start(GTK_BOX(gtkconv->lower_hbox), frame, TRUE, TRUE, 0); | 5321 gtk_box_pack_start(GTK_BOX(gtkconv->lower_hbox), frame, TRUE, TRUE, 0); |
5070 gtk_widget_show(frame); | 5322 gtk_widget_show(frame); |
5071 | 5323 |
5072 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); | 5324 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); |
5073 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), | 5325 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), |
5074 purple_account_get_protocol_name(conv->account)); | 5326 purple_account_get_protocol_name(purple_conversation_get_account(conv))); |
5075 | 5327 |
5076 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", | 5328 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", |
5077 G_CALLBACK(entry_popup_menu_cb), gtkconv); | 5329 G_CALLBACK(entry_popup_menu_cb), gtkconv); |
5078 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", | 5330 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", |
5079 G_CALLBACK(entry_key_press_cb), gtkconv); | 5331 G_CALLBACK(entry_key_press_cb), gtkconv); |
5116 PurpleConversation *conv = gtkconv->active_conv; | 5368 PurpleConversation *conv = gtkconv->active_conv; |
5117 PidginWindow *win = gtkconv->win; | 5369 PidginWindow *win = gtkconv->win; |
5118 PurpleConversation *c; | 5370 PurpleConversation *c; |
5119 PurpleAccount *convaccount = purple_conversation_get_account(conv); | 5371 PurpleAccount *convaccount = purple_conversation_get_account(conv); |
5120 PurpleConnection *gc = purple_account_get_connection(convaccount); | 5372 PurpleConnection *gc = purple_account_get_connection(convaccount); |
5121 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl) : NULL; | 5373 PurplePluginProtocolInfo *prpl_info = gc ? PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)) : NULL; |
5122 | 5374 |
5123 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) | 5375 if (sd->target == gdk_atom_intern("PURPLE_BLIST_NODE", FALSE)) |
5124 { | 5376 { |
5125 PurpleBlistNode *n = NULL; | 5377 PurpleBlistNode *n = NULL; |
5126 PurpleBuddy *b; | 5378 PurpleBuddy *b; |
5236 }; | 5488 }; |
5237 | 5489 |
5238 static PidginConversation * | 5490 static PidginConversation * |
5239 pidgin_conv_find_gtkconv(PurpleConversation * conv) | 5491 pidgin_conv_find_gtkconv(PurpleConversation * conv) |
5240 { | 5492 { |
5241 PurpleBuddy *bud = purple_find_buddy(conv->account, conv->name); | 5493 PurpleBuddy *bud = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
5242 PurpleContact *c; | 5494 PurpleContact *c; |
5243 PurpleBlistNode *cn, *bn; | 5495 PurpleBlistNode *cn, *bn; |
5244 | 5496 |
5245 if (!bud) | 5497 if (!bud) |
5246 return NULL; | 5498 return NULL; |
5251 cn = PURPLE_BLIST_NODE(c); | 5503 cn = PURPLE_BLIST_NODE(c); |
5252 for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) { | 5504 for (bn = purple_blist_node_get_first_child(cn); bn; bn = purple_blist_node_get_sibling_next(bn)) { |
5253 PurpleBuddy *b = PURPLE_BUDDY(bn); | 5505 PurpleBuddy *b = PURPLE_BUDDY(bn); |
5254 PurpleConversation *conv; | 5506 PurpleConversation *conv; |
5255 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) { | 5507 if ((conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, b->name, b->account))) { |
5256 if (conv->ui_data) | 5508 if (PIDGIN_CONVERSATION(conv)) |
5257 return conv->ui_data; | 5509 return PIDGIN_CONVERSATION(conv); |
5258 } | 5510 } |
5259 } | 5511 } |
5260 | 5512 |
5261 return NULL; | 5513 return NULL; |
5262 } | 5514 } |
5294 return FALSE; | 5546 return FALSE; |
5295 } | 5547 } |
5296 | 5548 |
5297 static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversation *gtkconv) | 5549 static void set_typing_font(GtkWidget *widget, GtkStyle *style, PidginConversation *gtkconv) |
5298 { | 5550 { |
5551 /* TODO WEBKIT */ | |
5552 #if 0 | |
5299 static PangoFontDescription *font_desc = NULL; | 5553 static PangoFontDescription *font_desc = NULL; |
5300 static GdkColor *color = NULL; | 5554 static GdkColor *color = NULL; |
5301 static gboolean enable = TRUE; | 5555 static gboolean enable = TRUE; |
5302 | 5556 |
5303 if (font_desc == NULL) { | 5557 if (font_desc == NULL) { |
5324 g_object_set_data(G_OBJECT(widget), "disable-typing-notification", GINT_TO_POINTER(TRUE)); | 5578 g_object_set_data(G_OBJECT(widget), "disable-typing-notification", GINT_TO_POINTER(TRUE)); |
5325 /* or may be 'gtkconv->disable_typing = TRUE;' instead? */ | 5579 /* or may be 'gtkconv->disable_typing = TRUE;' instead? */ |
5326 } | 5580 } |
5327 | 5581 |
5328 g_signal_handlers_disconnect_by_func(G_OBJECT(widget), set_typing_font, gtkconv); | 5582 g_signal_handlers_disconnect_by_func(G_OBJECT(widget), set_typing_font, gtkconv); |
5583 #endif /* if 0 */ | |
5329 } | 5584 } |
5330 | 5585 |
5331 /************************************************************************** | 5586 /************************************************************************** |
5332 * Conversation UI operations | 5587 * Conversation UI operations |
5333 **************************************************************************/ | 5588 **************************************************************************/ |
5334 static void | 5589 static void |
5335 private_gtkconv_new(PurpleConversation *conv, gboolean hidden) | 5590 private_gtkconv_new(PurpleConversation *conv, gboolean hidden) |
5336 { | 5591 { |
5337 PidginConversation *gtkconv; | 5592 PidginConversation *gtkconv; |
5593 PurpleTheme *theme; | |
5338 PurpleConversationType conv_type = purple_conversation_get_type(conv); | 5594 PurpleConversationType conv_type = purple_conversation_get_type(conv); |
5339 GtkWidget *pane = NULL; | 5595 GtkWidget *pane = NULL; |
5340 GtkWidget *tab_cont; | 5596 GtkWidget *tab_cont; |
5341 PurpleBlistNode *convnode; | 5597 PurpleBlistNode *convnode; |
5342 PurpleValue *value; | 5598 PurpleValue *value; |
5343 | 5599 |
5344 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { | 5600 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { |
5345 conv->ui_data = gtkconv; | 5601 purple_conversation_set_ui_data(conv, gtkconv); |
5346 if (!g_list_find(gtkconv->convs, conv)) | 5602 if (!g_list_find(gtkconv->convs, conv)) |
5347 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); | 5603 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); |
5348 pidgin_conv_switch_active_conversation(conv); | 5604 pidgin_conv_switch_active_conversation(conv); |
5349 return; | 5605 return; |
5350 } | 5606 } |
5351 | 5607 |
5352 gtkconv = g_new0(PidginConversation, 1); | 5608 gtkconv = g_new0(PidginConversation, 1); |
5353 conv->ui_data = gtkconv; | 5609 purple_conversation_set_ui_data(conv, gtkconv); |
5354 gtkconv->active_conv = conv; | 5610 gtkconv->active_conv = conv; |
5355 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); | 5611 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); |
5356 gtkconv->send_history = g_list_append(NULL, NULL); | 5612 gtkconv->send_history = g_list_append(NULL, NULL); |
5357 | 5613 |
5358 /* Setup some initial variables. */ | 5614 /* Setup some initial variables. */ |
5359 gtkconv->tooltips = gtk_tooltips_new(); | 5615 gtkconv->tooltips = gtk_tooltips_new(); |
5360 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; | 5616 gtkconv->unseen_state = PIDGIN_UNSEEN_NONE; |
5361 gtkconv->unseen_count = 0; | 5617 gtkconv->unseen_count = 0; |
5618 theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation"); | |
5619 if (!theme) | |
5620 theme = purple_theme_manager_find_theme("Default", "conversation"); | |
5621 gtkconv->theme = PIDGIN_CONV_THEME(g_object_ref(theme)); | |
5622 gtkconv->last_flags = 0; | |
5362 | 5623 |
5363 if (conv_type == PURPLE_CONV_TYPE_IM) { | 5624 if (conv_type == PURPLE_CONV_TYPE_IM) { |
5364 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); | 5625 gtkconv->u.im = g_malloc0(sizeof(PidginImPane)); |
5365 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { | 5626 } else if (conv_type == PURPLE_CONV_TYPE_CHAT) { |
5366 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); | 5627 gtkconv->u.chat = g_malloc0(sizeof(PidginChatPane)); |
5367 } | 5628 } |
5368 pane = setup_common_pane(gtkconv); | 5629 pane = setup_common_pane(gtkconv); |
5369 | |
5370 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->imhtml), | |
5371 gtk_imhtml_get_format_functions(GTK_IMHTML(gtkconv->imhtml)) | GTK_IMHTML_IMAGE); | |
5372 | 5630 |
5373 if (pane == NULL) { | 5631 if (pane == NULL) { |
5374 if (conv_type == PURPLE_CONV_TYPE_CHAT) | 5632 if (conv_type == PURPLE_CONV_TYPE_CHAT) |
5375 g_free(gtkconv->u.chat); | 5633 g_free(gtkconv->u.chat); |
5376 else if (conv_type == PURPLE_CONV_TYPE_IM) | 5634 else if (conv_type == PURPLE_CONV_TYPE_IM) |
5377 g_free(gtkconv->u.im); | 5635 g_free(gtkconv->u.im); |
5378 | 5636 |
5379 g_free(gtkconv); | 5637 g_free(gtkconv); |
5380 conv->ui_data = NULL; | 5638 purple_conversation_set_ui_data(conv, NULL); |
5381 return; | 5639 return; |
5382 } | 5640 } |
5383 | 5641 |
5384 /* Setup drag-and-drop */ | 5642 /* Setup drag-and-drop */ |
5385 gtk_drag_dest_set(pane, | 5643 gtk_drag_dest_set(pane, |
5390 gtk_drag_dest_set(pane, | 5648 gtk_drag_dest_set(pane, |
5391 GTK_DEST_DEFAULT_MOTION | | 5649 GTK_DEST_DEFAULT_MOTION | |
5392 GTK_DEST_DEFAULT_DROP, | 5650 GTK_DEST_DEFAULT_DROP, |
5393 te, sizeof(te) / sizeof(GtkTargetEntry), | 5651 te, sizeof(te) / sizeof(GtkTargetEntry), |
5394 GDK_ACTION_COPY); | 5652 GDK_ACTION_COPY); |
5395 gtk_drag_dest_set(gtkconv->imhtml, 0, | 5653 gtk_drag_dest_set(gtkconv->webview, 0, |
5396 te, sizeof(te) / sizeof(GtkTargetEntry), | 5654 te, sizeof(te) / sizeof(GtkTargetEntry), |
5397 GDK_ACTION_COPY); | 5655 GDK_ACTION_COPY); |
5398 | 5656 |
5399 gtk_drag_dest_set(gtkconv->entry, 0, | 5657 gtk_drag_dest_set(gtkconv->entry, 0, |
5400 te, sizeof(te) / sizeof(GtkTargetEntry), | 5658 te, sizeof(te) / sizeof(GtkTargetEntry), |
5402 | 5660 |
5403 g_signal_connect(G_OBJECT(pane), "button_press_event", | 5661 g_signal_connect(G_OBJECT(pane), "button_press_event", |
5404 G_CALLBACK(ignore_middle_click), NULL); | 5662 G_CALLBACK(ignore_middle_click), NULL); |
5405 g_signal_connect(G_OBJECT(pane), "drag_data_received", | 5663 g_signal_connect(G_OBJECT(pane), "drag_data_received", |
5406 G_CALLBACK(conv_dnd_recv), gtkconv); | 5664 G_CALLBACK(conv_dnd_recv), gtkconv); |
5407 g_signal_connect(G_OBJECT(gtkconv->imhtml), "drag_data_received", | 5665 g_signal_connect(G_OBJECT(gtkconv->webview), "drag_data_received", |
5408 G_CALLBACK(conv_dnd_recv), gtkconv); | 5666 G_CALLBACK(conv_dnd_recv), gtkconv); |
5409 g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received", | 5667 g_signal_connect(G_OBJECT(gtkconv->entry), "drag_data_received", |
5410 G_CALLBACK(conv_dnd_recv), gtkconv); | 5668 G_CALLBACK(conv_dnd_recv), gtkconv); |
5411 | 5669 |
5412 g_signal_connect(gtkconv->imhtml, "style-set", G_CALLBACK(set_typing_font), gtkconv); | 5670 g_signal_connect(gtkconv->webview, "style-set", G_CALLBACK(set_typing_font), gtkconv); |
5413 | 5671 |
5414 /* Setup the container for the tab. */ | 5672 /* Setup the container for the tab. */ |
5415 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); | 5673 gtkconv->tab_cont = tab_cont = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
5416 g_object_set_data(G_OBJECT(tab_cont), "PidginConversation", gtkconv); | 5674 g_object_set_data(G_OBJECT(tab_cont), "PidginConversation", gtkconv); |
5417 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), PIDGIN_HIG_BOX_SPACE); | 5675 gtk_container_set_border_width(GTK_CONTAINER(tab_cont), PIDGIN_HIG_BOX_SPACE); |
5437 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) | 5695 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons")) |
5438 gtk_widget_show(gtkconv->infopane_hbox); | 5696 gtk_widget_show(gtkconv->infopane_hbox); |
5439 else | 5697 else |
5440 gtk_widget_hide(gtkconv->infopane_hbox); | 5698 gtk_widget_hide(gtkconv->infopane_hbox); |
5441 | 5699 |
5442 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | |
5443 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps")); | |
5444 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), | |
5445 purple_account_get_protocol_name(conv->account)); | |
5446 | 5700 |
5447 g_signal_connect_swapped(G_OBJECT(pane), "focus", | 5701 g_signal_connect_swapped(G_OBJECT(pane), "focus", |
5448 G_CALLBACK(gtk_widget_grab_focus), | 5702 G_CALLBACK(gtk_widget_grab_focus), |
5449 gtkconv->entry); | 5703 gtkconv->entry); |
5450 | 5704 |
5453 else | 5707 else |
5454 pidgin_conv_placement_place(gtkconv); | 5708 pidgin_conv_placement_place(gtkconv); |
5455 | 5709 |
5456 if (nick_colors == NULL) { | 5710 if (nick_colors == NULL) { |
5457 nbr_nick_colors = NUM_NICK_COLORS; | 5711 nbr_nick_colors = NUM_NICK_COLORS; |
5458 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); | 5712 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->webview)->base[GTK_STATE_NORMAL]); |
5459 } | 5713 } |
5460 | 5714 |
5461 if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) | 5715 if (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) |
5462 pidgin_themes_smiley_themeize_custom(gtkconv->entry); | 5716 pidgin_themes_smiley_themeize_custom(gtkconv->entry); |
5463 } | 5717 } |
5464 | 5718 |
5465 static void | 5719 static void |
5466 pidgin_conv_new_hidden(PurpleConversation *conv) | 5720 pidgin_conv_new_hidden(PurpleConversation *conv) |
5566 g_list_free(gtkconv->send_history); | 5820 g_list_free(gtkconv->send_history); |
5567 | 5821 |
5568 if (gtkconv->attach.timer) { | 5822 if (gtkconv->attach.timer) { |
5569 g_source_remove(gtkconv->attach.timer); | 5823 g_source_remove(gtkconv->attach.timer); |
5570 } | 5824 } |
5825 | |
5826 g_object_disconnect(G_OBJECT(gtkconv->theme), "any_signal::notify", | |
5827 conv_variant_changed_cb, gtkconv, NULL); | |
5828 g_object_unref(gtkconv->theme); | |
5571 | 5829 |
5572 g_free(gtkconv); | 5830 g_free(gtkconv); |
5573 } | 5831 } |
5574 | 5832 |
5575 | 5833 |
5594 } | 5852 } |
5595 | 5853 |
5596 purple_conversation_write(conv, who, message, flags, mtime); | 5854 purple_conversation_write(conv, who, message, flags, mtime); |
5597 } | 5855 } |
5598 | 5856 |
5857 #if 0 | |
5599 static const char * | 5858 static const char * |
5600 get_text_tag_color(GtkTextTag *tag) | 5859 get_text_tag_color(GtkTextTag *tag) |
5601 { | 5860 { |
5602 GdkColor *color = NULL; | 5861 GdkColor *color = NULL; |
5603 gboolean set = FALSE; | 5862 gboolean set = FALSE; |
5674 } | 5933 } |
5675 } | 5934 } |
5676 | 5935 |
5677 return FALSE; | 5936 return FALSE; |
5678 } | 5937 } |
5938 #endif | |
5679 | 5939 |
5680 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, | 5940 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, |
5681 gboolean create) | 5941 gboolean create) |
5682 { | 5942 { |
5943 /* TODO WEBKIT */ | |
5944 #if 0 | |
5683 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); | 5945 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
5684 GtkTextTag *buddytag; | 5946 GtkTextTag *buddytag; |
5685 gchar *str; | 5947 gchar *str; |
5686 gboolean highlight = (flag & PURPLE_MESSAGE_NICK); | 5948 gboolean highlight = (flag & PURPLE_MESSAGE_NICK); |
5687 GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; | 5949 GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; |
5711 } | 5973 } |
5712 | 5974 |
5713 g_free(str); | 5975 g_free(str); |
5714 | 5976 |
5715 return buddytag; | 5977 return buddytag; |
5716 } | 5978 #endif /* if 0 */ |
5717 | 5979 return NULL; |
5980 } | |
5981 | |
5982 #if 0 | |
5718 static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime) | 5983 static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime) |
5719 { | 5984 { |
5720 struct tm *tm = localtime(&mtime); | 5985 struct tm *tm = localtime(&mtime); |
5721 | 5986 |
5722 tm->tm_hour = tm->tm_min = tm->tm_sec = 0; | 5987 tm->tm_hour = tm->tm_min = tm->tm_sec = 0; |
5758 | 6023 |
5759 g_free(*str); | 6024 g_free(*str); |
5760 *str = ret; | 6025 *str = ret; |
5761 #endif | 6026 #endif |
5762 } | 6027 } |
6028 #endif | |
6029 | |
6030 static char * | |
6031 replace_message_tokens( | |
6032 const char *text, | |
6033 PurpleConversation *conv, | |
6034 const char *name, | |
6035 const char *alias, | |
6036 const char *message, | |
6037 PurpleMessageFlags flags, | |
6038 time_t mtime) | |
6039 { | |
6040 GString *str; | |
6041 const char *cur = text; | |
6042 const char *prev = cur; | |
6043 | |
6044 if (text == NULL) | |
6045 return g_strdup(""); | |
6046 | |
6047 str = g_string_new(NULL); | |
6048 while ((cur = strchr(cur, '%'))) { | |
6049 const char *replace = NULL; | |
6050 const char *fin = NULL; | |
6051 | |
6052 if (g_str_has_prefix(cur, "%message%")) { | |
6053 replace = message; | |
6054 | |
6055 } else if (g_str_has_prefix(cur, "%messageClasses%")) { | |
6056 replace = flags & PURPLE_MESSAGE_SEND ? "outgoing" : | |
6057 flags & PURPLE_MESSAGE_RECV ? "incoming" : "event"; | |
6058 | |
6059 } else if (g_str_has_prefix(cur, "%time")) { | |
6060 const char *tmp = cur + strlen("%time"); | |
6061 char *format = NULL; | |
6062 if (*tmp == '{') { | |
6063 char *end; | |
6064 tmp++; | |
6065 end = strstr(tmp, "}%"); | |
6066 if (!end) /* Invalid string */ | |
6067 continue; | |
6068 format = g_strndup(tmp, end - tmp); | |
6069 fin = end + 1; | |
6070 } | |
6071 replace = purple_utf8_strftime(format ? format : "%X", NULL); | |
6072 g_free(format); | |
6073 | |
6074 } else if (g_str_has_prefix(cur, "%userIconPath%")) { | |
6075 if (flags & PURPLE_MESSAGE_SEND) { | |
6076 if (purple_account_get_bool(purple_conversation_get_account(conv), "use-global-buddyicon", TRUE)) { | |
6077 replace = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon"); | |
6078 } else { | |
6079 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(purple_conversation_get_account(conv)); | |
6080 replace = purple_imgstore_get_filename(img); | |
6081 } | |
6082 if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { | |
6083 replace = g_build_filename("Outgoing", "buddy_icon.png", NULL); | |
6084 } | |
6085 } else if (flags & PURPLE_MESSAGE_RECV) { | |
6086 PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); | |
6087 if (icon) | |
6088 replace = purple_buddy_icon_get_full_path(icon); | |
6089 if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { | |
6090 replace = g_build_filename("Incoming", "buddy_icon.png", NULL); | |
6091 } | |
6092 } | |
6093 | |
6094 } else if (g_str_has_prefix(cur, "%senderScreenName%")) { | |
6095 replace = name; | |
6096 | |
6097 } else if (g_str_has_prefix(cur, "%sender%")) { | |
6098 replace = alias; | |
6099 | |
6100 } else if (g_str_has_prefix(cur, "%service%")) { | |
6101 replace = purple_account_get_protocol_name(purple_conversation_get_account(conv)); | |
6102 | |
6103 } else { | |
6104 cur++; | |
6105 continue; | |
6106 } | |
6107 | |
6108 /* Here we have a replacement to make */ | |
6109 g_string_append_len(str, prev, cur - prev); | |
6110 if (replace) | |
6111 g_string_append(str, replace); | |
6112 | |
6113 /* And update the pointers */ | |
6114 if (fin) { | |
6115 prev = cur = fin + 1; | |
6116 } else { | |
6117 prev = cur = strchr(cur + 1, '%') + 1; | |
6118 } | |
6119 | |
6120 } | |
6121 | |
6122 /* And wrap it up */ | |
6123 g_string_append(str, prev); | |
6124 | |
6125 return g_string_free(str, FALSE); | |
6126 } | |
5763 | 6127 |
5764 static void | 6128 static void |
5765 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, | 6129 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, |
5766 const char *message, PurpleMessageFlags flags, | 6130 const char *message, PurpleMessageFlags flags, |
5767 time_t mtime) | 6131 time_t mtime) |
5768 { | 6132 { |
5769 PidginConversation *gtkconv; | 6133 PidginConversation *gtkconv; |
5770 PurpleConnection *gc; | 6134 PurpleConnection *gc; |
5771 PurpleAccount *account; | 6135 PurpleAccount *account; |
6136 #if 0 | |
5772 int gtk_font_options = 0; | 6137 int gtk_font_options = 0; |
5773 int gtk_font_options_all = 0; | 6138 int gtk_font_options_all = 0; |
5774 int max_scrollback_lines; | |
5775 int line_count; | |
5776 char buf2[BUF_LONG]; | 6139 char buf2[BUF_LONG]; |
5777 gboolean show_date; | 6140 gboolean show_date; |
5778 char *mdate; | 6141 char *mdate; |
5779 char *str; | 6142 char *str; |
5780 char *with_font_tag; | 6143 char *with_font_tag; |
5781 char *sml_attrib = NULL; | 6144 char *sml_attrib = NULL; |
6145 #endif | |
5782 size_t length; | 6146 size_t length; |
5783 PurpleConversationType type; | 6147 PurpleConversationType type; |
5784 char *displaying; | 6148 char *displaying; |
5785 gboolean plugin_return; | 6149 gboolean plugin_return; |
5786 char *bracket; | 6150 #if 0 |
5787 int tag_count = 0; | |
5788 gboolean is_rtl_message = FALSE; | 6151 gboolean is_rtl_message = FALSE; |
6152 #endif | |
6153 | |
6154 const char *message_html; | |
6155 char *msg; | |
6156 char *escape; | |
6157 char *script; | |
6158 char *smileyed; | |
6159 PurpleMessageFlags old_flags; | |
6160 const char *func = "appendMessage"; | |
5789 | 6161 |
5790 g_return_if_fail(conv != NULL); | 6162 g_return_if_fail(conv != NULL); |
5791 gtkconv = PIDGIN_CONVERSATION(conv); | 6163 gtkconv = PIDGIN_CONVERSATION(conv); |
5792 g_return_if_fail(gtkconv != NULL); | 6164 g_return_if_fail(gtkconv != NULL); |
5793 | 6165 |
5840 g_free(displaying); | 6212 g_free(displaying); |
5841 return; | 6213 return; |
5842 } | 6214 } |
5843 length = strlen(displaying) + 1; | 6215 length = strlen(displaying) + 1; |
5844 | 6216 |
5845 /* Awful hack to work around GtkIMHtml's inefficient rendering of messages with lots of formatting changes. | 6217 old_flags = gtkconv->last_flags; |
5846 * If a message has over 100 '<' characters, strip formatting before appending it. Hopefully nobody actually | 6218 if ((flags & PURPLE_MESSAGE_SEND) && (old_flags & PURPLE_MESSAGE_SEND)) { |
5847 * needs that much formatting, anyway. | 6219 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT); |
5848 */ | 6220 func = "appendNextMessage"; |
5849 for (bracket = strchr(displaying, '<'); bracket && *(bracket + 1); bracket = strchr(bracket + 1, '<')) | 6221 } else if (flags & PURPLE_MESSAGE_SEND) { |
5850 tag_count++; | 6222 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT); |
5851 | 6223 } else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) { |
5852 if (tag_count > 100) { | 6224 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT); |
5853 char *tmp = displaying; | 6225 func = "appendNextMessage"; |
5854 displaying = purple_markup_strip_html(tmp); | 6226 } else if (flags & PURPLE_MESSAGE_RECV) { |
5855 g_free(tmp); | 6227 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT); |
5856 } | 6228 } else { |
5857 | 6229 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS); |
5858 line_count = gtk_text_buffer_get_line_count( | 6230 } |
5859 gtk_text_view_get_buffer(GTK_TEXT_VIEW( | 6231 gtkconv->last_flags = flags; |
5860 gtkconv->imhtml))); | 6232 |
5861 | 6233 smileyed = smiley_parse_markup(message, purple_account_get_protocol_id(account)); |
5862 max_scrollback_lines = purple_prefs_get_int( | 6234 msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime); |
5863 PIDGIN_PREFS_ROOT "/conversations/scrollback_lines"); | 6235 escape = gtk_webview_quote_js_string(msg); |
5864 /* If we're sitting at more than 100 lines more than the | 6236 script = g_strdup_printf("%s(%s)", func, escape); |
5865 max scrollback, trim down to max scrollback */ | 6237 |
5866 if (max_scrollback_lines > 0 | 6238 purple_debug_info("webkit", "JS: %s\n", script); |
5867 && line_count > (max_scrollback_lines + 100)) { | 6239 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), script); |
5868 GtkTextBuffer *text_buffer = gtk_text_view_get_buffer( | 6240 |
5869 GTK_TEXT_VIEW(gtkconv->imhtml)); | 6241 g_free(script); |
5870 GtkTextIter start, end; | 6242 g_free(smileyed); |
5871 | 6243 g_free(msg); |
5872 gtk_text_buffer_get_start_iter(text_buffer, &start); | 6244 g_free(escape); |
5873 gtk_text_buffer_get_iter_at_line(text_buffer, &end, | 6245 |
5874 (line_count - max_scrollback_lines)); | 6246 #if 0 |
5875 gtk_imhtml_delete(GTK_IMHTML(gtkconv->imhtml), &start, &end); | 6247 /* if the buffer is not empty add a <br> */ |
5876 } | 6248 if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview))) |
5877 | 6249 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />"); |
5878 if (type == PURPLE_CONV_TYPE_CHAT) | |
5879 { | |
5880 /* Create anchor for user */ | |
5881 GtkTextIter iter; | |
5882 char *tmp = g_strconcat("user:", name, NULL); | |
5883 | |
5884 gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), &iter); | |
5885 gtk_text_buffer_create_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), | |
5886 tmp, &iter, TRUE); | |
5887 g_free(tmp); | |
5888 } | |
5889 | |
5890 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling")) | |
5891 gtk_font_options_all |= GTK_IMHTML_USE_SMOOTHSCROLLING; | |
5892 | |
5893 if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)))) | |
5894 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR>", gtk_font_options_all | GTK_IMHTML_NO_SCROLL); | |
5895 | 6250 |
5896 /* First message in a conversation. */ | 6251 /* First message in a conversation. */ |
5897 if (gtkconv->newday == 0) | 6252 if (gtkconv->newday == 0) |
5898 pidgin_conv_calculate_newday(gtkconv, mtime); | 6253 pidgin_conv_calculate_newday(gtkconv, mtime); |
5899 | 6254 |
5932 if ((flags & PURPLE_MESSAGE_RECV) && | 6287 if ((flags & PURPLE_MESSAGE_RECV) && |
5933 !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting")) | 6288 !purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_incoming_formatting")) |
5934 gtk_font_options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES | GTK_IMHTML_NO_FORMATTING; | 6289 gtk_font_options |= GTK_IMHTML_NO_COLOURS | GTK_IMHTML_NO_FONTS | GTK_IMHTML_NO_SIZES | GTK_IMHTML_NO_FORMATTING; |
5935 | 6290 |
5936 /* this is gonna crash one day, I can feel it. */ | 6291 /* this is gonna crash one day, I can feel it. */ |
5937 if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(conv->account)))->options & | 6292 if (PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(purple_conversation_get_account(conv))))->options & |
5938 OPT_PROTO_USE_POINTSIZE) { | 6293 OPT_PROTO_USE_POINTSIZE) { |
5939 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; | 6294 gtk_font_options |= GTK_IMHTML_USE_POINTSIZE; |
5940 } | 6295 } |
5941 | 6296 |
5942 if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) | 6297 if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) |
5943 { | 6298 { |
5944 /* We want to see our own smileys. Need to revert it after send*/ | 6299 /* We want to see our own smileys. Need to revert it after send*/ |
5945 pidgin_themes_smiley_themeize_custom(gtkconv->imhtml); | 6300 pidgin_themes_smiley_themeize_custom(gtkconv->webview); |
5946 } | 6301 } |
5947 | 6302 |
5948 /* TODO: These colors should not be hardcoded so log.c can use them */ | 6303 /* TODO: These colors should not be hardcoded so log.c can use them */ |
5949 if (flags & PURPLE_MESSAGE_RAW) { | 6304 if (flags & PURPLE_MESSAGE_RAW) { |
5950 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all); | 6305 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), message); |
5951 } else if (flags & PURPLE_MESSAGE_SYSTEM) { | 6306 } else if (flags & PURPLE_MESSAGE_SYSTEM) { |
5952 g_snprintf(buf2, sizeof(buf2), | 6307 g_snprintf(buf2, sizeof(buf2), |
5953 "<FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT>", | 6308 "<font %s><font size=\"2\"><span class='timestamp'>%s</span></font><b>%s</b></font>", |
5954 sml_attrib ? sml_attrib : "", mdate, displaying); | 6309 sml_attrib ? sml_attrib : "", mdate, displaying); |
5955 | 6310 |
5956 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); | 6311 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
5957 | 6312 |
5958 } else if (flags & PURPLE_MESSAGE_ERROR) { | 6313 } else if (flags & PURPLE_MESSAGE_ERROR) { |
5959 g_snprintf(buf2, sizeof(buf2), | 6314 g_snprintf(buf2, sizeof(buf2), |
5960 "<FONT COLOR=\"#ff0000\"><FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT></FONT>", | 6315 "<font color=\"#ff0000\"><font %s><font size=\"2\"><span class='timestamp'>%s</span> </font><b>%s</b></font></font>", |
5961 sml_attrib ? sml_attrib : "", mdate, displaying); | 6316 sml_attrib ? sml_attrib : "", mdate, displaying); |
5962 | 6317 |
5963 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); | 6318 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
5964 | 6319 |
5965 } else if (flags & PURPLE_MESSAGE_NO_LOG) { | 6320 } else if (flags & PURPLE_MESSAGE_NO_LOG) { |
5966 g_snprintf(buf2, BUF_LONG, | 6321 g_snprintf(buf2, BUF_LONG, |
5967 "<B><FONT %s COLOR=\"#777777\">%s</FONT></B>", | 6322 "<b><font %s color=\"#777777\">%s</font></b>", |
5968 sml_attrib ? sml_attrib : "", displaying); | 6323 sml_attrib ? sml_attrib : "", displaying); |
5969 | 6324 |
5970 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); | 6325 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
5971 } else { | 6326 } else { |
5972 char *new_message = g_memdup(displaying, length); | 6327 char *new_message = g_memdup(displaying, length); |
5973 char *alias_escaped = (alias ? g_markup_escape_text(alias, strlen(alias)) : g_strdup("")); | 6328 char *alias_escaped = (alias ? g_markup_escape_text(alias, strlen(alias)) : g_strdup("")); |
5974 /* The initial offset is to deal with | 6329 /* The initial offset is to deal with |
5975 * escaped entities making the string longer */ | 6330 * escaped entities making the string longer */ |
5976 int tag_start_offset = 0; | 6331 int tag_start_offset = 0; |
5977 int tag_end_offset = 0; | 6332 int tag_end_offset = 0; |
5978 const char *tagname = NULL; | 6333 const char *tagname = NULL; |
5979 | |
5980 GtkTextIter start, end; | |
5981 GtkTextMark *mark; | |
5982 GtkTextTag *tag; | |
5983 GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; | |
5984 | 6334 |
5985 /* Enforce direction on alias */ | 6335 /* Enforce direction on alias */ |
5986 if (is_rtl_message) | 6336 if (is_rtl_message) |
5987 str_embed_direction_chars(&alias_escaped); | 6337 str_embed_direction_chars(&alias_escaped); |
5988 | 6338 |
6040 } | 6390 } |
6041 } | 6391 } |
6042 | 6392 |
6043 g_free(alias_escaped); | 6393 g_free(alias_escaped); |
6044 | 6394 |
6395 /* TODO WEBKIT */ | |
6396 #if 0 | |
6045 if (tagname) | 6397 if (tagname) |
6046 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname); | 6398 tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname); |
6047 else | 6399 else |
6048 tag = get_buddy_tag(conv, name, flags, TRUE); | 6400 tag = get_buddy_tag(conv, name, flags, TRUE); |
6049 | 6401 |
6050 if (GTK_IMHTML(gtkconv->imhtml)->show_comments) { | 6402 if (GTK_IMHTML(gtkconv->imhtml)->show_comments) { |
6403 { | |
6051 /* The color for the timestamp has to be set in the font-tags, unfortunately. | 6404 /* The color for the timestamp has to be set in the font-tags, unfortunately. |
6052 * Applying the nick-tag to timestamps would work, but that can make it | 6405 * Applying the nick-tag to timestamps would work, but that can make it |
6053 * bold. I thought applying the "comment" tag again, which has "weight" set | 6406 * bold. I thought applying the "comment" tag again, which has "weight" set |
6054 * to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So | 6407 * to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So |
6055 * this will have to do. I don't terribly like it. -- sadrul */ | 6408 * this will have to do. I don't terribly like it. -- sadrul */ |
6056 const char *color = get_text_tag_color(tag); | 6409 /* const char *color = get_text_tag_color(tag); */ |
6057 g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>", | 6410 g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>", |
6058 color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate); | 6411 color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate); |
6059 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL); | 6412 gtk_webview_append_html (GTK_WEBVIEW(gtkconv->webview), buf2); |
6060 } | 6413 } |
6061 | 6414 #endif /* if 0 */ |
6062 gtk_text_buffer_get_end_iter(buffer, &end); | 6415 g_snprintf(buf2, BUF_LONG, "<font %s>%s</font> ", sml_attrib ? sml_attrib : "", str); |
6063 mark = gtk_text_buffer_create_mark(buffer, NULL, &end, TRUE); | 6416 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), buf2); |
6064 | |
6065 g_snprintf(buf2, BUF_LONG, "<FONT %s>%s</FONT> ", sml_attrib ? sml_attrib : "", str); | |
6066 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL); | |
6067 | |
6068 gtk_text_buffer_get_end_iter(buffer, &end); | |
6069 gtk_text_buffer_get_iter_at_mark(buffer, &start, mark); | |
6070 gtk_text_buffer_apply_tag(buffer, tag, &start, &end); | |
6071 gtk_text_buffer_delete_mark(buffer, mark); | |
6072 | 6417 |
6073 g_free(str); | 6418 g_free(str); |
6074 | 6419 |
6075 if(gc){ | 6420 if (gc) { |
6076 char *pre = g_strdup_printf("<font %s>", sml_attrib ? sml_attrib : ""); | 6421 char *pre = g_strdup_printf("<font %s>", sml_attrib ? sml_attrib : ""); |
6077 char *post = "</font>"; | 6422 char *post = "</font>"; |
6078 int pre_len = strlen(pre); | 6423 with_font_tag = g_strdup_printf("%s%s%s", pre, new_message, post); |
6079 int post_len = strlen(post); | |
6080 | |
6081 with_font_tag = g_malloc(length + pre_len + post_len + 1); | |
6082 | |
6083 strcpy(with_font_tag, pre); | |
6084 memcpy(with_font_tag + pre_len, new_message, length); | |
6085 strcpy(with_font_tag + pre_len + length, post); | |
6086 | |
6087 length += pre_len + post_len; | |
6088 g_free(pre); | 6424 g_free(pre); |
6089 } else | 6425 } else |
6090 with_font_tag = g_memdup(new_message, length); | 6426 with_font_tag = g_memdup(new_message, length); |
6091 | 6427 |
6092 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), | 6428 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), |
6093 with_font_tag, gtk_font_options | gtk_font_options_all); | 6429 with_font_tag); |
6094 | 6430 |
6095 g_free(with_font_tag); | 6431 g_free(with_font_tag); |
6096 g_free(new_message); | 6432 g_free(new_message); |
6097 } | 6433 } |
6098 | 6434 |
6099 g_free(mdate); | 6435 g_free(mdate); |
6100 g_free(sml_attrib); | 6436 g_free(sml_attrib); |
6437 | |
6438 #endif | |
6101 | 6439 |
6102 /* Tab highlighting stuff */ | 6440 /* Tab highlighting stuff */ |
6103 if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv)) | 6441 if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv)) |
6104 { | 6442 { |
6105 PidginUnseenState unseen = PIDGIN_UNSEEN_NONE; | 6443 PidginUnseenState unseen = PIDGIN_UNSEEN_NONE; |
6115 unseen = PIDGIN_UNSEEN_TEXT; | 6453 unseen = PIDGIN_UNSEEN_TEXT; |
6116 | 6454 |
6117 gtkconv_set_unseen(gtkconv, unseen); | 6455 gtkconv_set_unseen(gtkconv, unseen); |
6118 } | 6456 } |
6119 | 6457 |
6120 if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) | 6458 #if 0 |
6459 if (!(flags & PURPLE_MESSAGE_RECV) && (purple_conversation_get_features(conv) & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)) | |
6121 { | 6460 { |
6122 /* Restore the smiley-data */ | 6461 /* Restore the smiley-data */ |
6123 pidgin_themes_smiley_themeize(gtkconv->imhtml); | 6462 pidgin_themes_smiley_themeize(gtkconv->webview); |
6124 } | 6463 } |
6464 #endif | |
6125 | 6465 |
6126 purple_signal_emit(pidgin_conversations_get_handle(), | 6466 purple_signal_emit(pidgin_conversations_get_handle(), |
6127 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), | 6467 (type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"), |
6128 account, name, displaying, conv, flags); | 6468 account, name, displaying, conv, flags); |
6129 g_free(displaying); | 6469 g_free(displaying); |
6130 update_typing_message(gtkconv, NULL); | 6470 update_typing_message(gtkconv, NULL); |
6131 } | 6471 } |
6132 | 6472 |
6133 static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter) | 6473 static gboolean get_iter_from_chatbuddy(PurpleConvChatBuddy *cb, GtkTreeIter *iter) |
6134 { | 6474 { |
6135 GtkTreeRowReference *ref = cb->ui_data; | 6475 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cb); |
6136 GtkTreePath *path; | 6476 GtkTreePath *path; |
6137 GtkTreeModel *model; | 6477 GtkTreeModel *model; |
6138 | 6478 |
6139 if (!ref) | 6479 if (!ref) |
6140 return FALSE; | 6480 return FALSE; |
6216 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 6556 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
6217 return; | 6557 return; |
6218 | 6558 |
6219 old_cbuddy = purple_conv_chat_cb_find(chat, old_name); | 6559 old_cbuddy = purple_conv_chat_cb_find(chat, old_name); |
6220 if (get_iter_from_chatbuddy(old_cbuddy, &iter)) { | 6560 if (get_iter_from_chatbuddy(old_cbuddy, &iter)) { |
6221 GtkTreeRowReference *ref = old_cbuddy->ui_data; | 6561 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(old_cbuddy); |
6222 | 6562 |
6223 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | 6563 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); |
6224 gtk_tree_row_reference_free(ref); | 6564 gtk_tree_row_reference_free(ref); |
6225 old_cbuddy->ui_data = NULL; | 6565 purple_conv_chat_cb_set_ui_data(old_cbuddy, NULL); |
6226 } | 6566 } |
6227 | 6567 |
6228 if ((tag = get_buddy_tag(conv, old_name, 0, FALSE))) | 6568 if ((tag = get_buddy_tag(conv, old_name, 0, FALSE))) |
6229 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); | 6569 g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, NULL); |
6230 if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE))) | 6570 if ((tag = get_buddy_tag(conv, old_name, PURPLE_MESSAGE_NICK, FALSE))) |
6314 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) | 6654 if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter)) |
6315 return; | 6655 return; |
6316 | 6656 |
6317 cbuddy = purple_conv_chat_cb_find(chat, user); | 6657 cbuddy = purple_conv_chat_cb_find(chat, user); |
6318 if (get_iter_from_chatbuddy(cbuddy, &iter)) { | 6658 if (get_iter_from_chatbuddy(cbuddy, &iter)) { |
6319 GtkTreeRowReference *ref = cbuddy->ui_data; | 6659 GtkTreeRowReference *ref = purple_conv_chat_cb_get_ui_data(cbuddy); |
6320 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); | 6660 gtk_list_store_remove(GTK_LIST_STORE(model), &iter); |
6321 gtk_tree_row_reference_free(ref); | 6661 gtk_tree_row_reference_free(ref); |
6322 cbuddy->ui_data = NULL; | 6662 purple_conv_chat_cb_set_ui_data(cbuddy, NULL); |
6323 } | 6663 } |
6324 | 6664 |
6325 if (cbuddy) | 6665 if (cbuddy) |
6326 add_chat_buddy_common(conv, cbuddy, NULL); | 6666 add_chat_buddy_common(conv, cbuddy, NULL); |
6327 } | 6667 } |
6364 | 6704 |
6365 return TRUE; | 6705 return TRUE; |
6366 } | 6706 } |
6367 | 6707 |
6368 static gboolean | 6708 static gboolean |
6709 add_custom_smiley_for_webview(GtkWebView *webview, const char *sml, const char *smile) | |
6710 { | |
6711 /* TODO WEBKIT: Smileys need to be added to webkit stuff */ | |
6712 return TRUE; | |
6713 } | |
6714 | |
6715 static gboolean | |
6369 pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote) | 6716 pidgin_conv_custom_smiley_add(PurpleConversation *conv, const char *smile, gboolean remote) |
6370 { | 6717 { |
6371 PidginConversation *gtkconv; | 6718 PidginConversation *gtkconv; |
6372 struct smiley_list *list; | 6719 struct smiley_list *list; |
6373 const char *sml = NULL, *conv_sml; | 6720 const char *sml = NULL, *conv_sml; |
6380 if (pidgin_themes_smileys_disabled()) | 6727 if (pidgin_themes_smileys_disabled()) |
6381 return FALSE; | 6728 return FALSE; |
6382 | 6729 |
6383 /* If possible add this smiley to the current theme. | 6730 /* If possible add this smiley to the current theme. |
6384 * The addition is only temporary: custom smilies aren't saved to disk. */ | 6731 * The addition is only temporary: custom smilies aren't saved to disk. */ |
6385 conv_sml = purple_account_get_protocol_name(conv->account); | 6732 conv_sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
6386 gtkconv = PIDGIN_CONVERSATION(conv); | 6733 gtkconv = PIDGIN_CONVERSATION(conv); |
6387 | 6734 |
6388 for (list = (struct smiley_list *)current_smiley_theme->list; list; list = list->next) { | 6735 for (list = (struct smiley_list *)current_smiley_theme->list; list; list = list->next) { |
6389 if (!strcmp(list->sml, conv_sml)) { | 6736 if (!strcmp(list->sml, conv_sml)) { |
6390 sml = list->sml; | 6737 sml = list->sml; |
6391 break; | 6738 break; |
6392 } | 6739 } |
6393 } | 6740 } |
6394 | 6741 |
6395 if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->imhtml), sml, smile)) | 6742 if (!add_custom_smiley_for_webview(GTK_WEBVIEW(gtkconv->webview), sml, smile)) |
6396 return FALSE; | 6743 return FALSE; |
6397 | 6744 |
6398 if (!remote) /* If it's a local custom smiley, then add it for the entry */ | 6745 if (!remote) /* If it's a local custom smiley, then add it for the entry */ |
6399 if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->entry), sml, smile)) | 6746 if (!add_custom_smiley_for_imhtml(GTK_IMHTML(gtkconv->entry), sml, smile)) |
6400 return FALSE; | 6747 return FALSE; |
6404 | 6751 |
6405 static void | 6752 static void |
6406 pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile, | 6753 pidgin_conv_custom_smiley_write(PurpleConversation *conv, const char *smile, |
6407 const guchar *data, gsize size) | 6754 const guchar *data, gsize size) |
6408 { | 6755 { |
6756 /* TODO WEBKIT */ | |
6757 #if 0 | |
6409 PidginConversation *gtkconv; | 6758 PidginConversation *gtkconv; |
6410 GtkIMHtmlSmiley *smiley; | 6759 GtkIMHtmlSmiley *smiley; |
6411 const char *sml; | 6760 const char *sml; |
6412 GError *error = NULL; | 6761 GError *error = NULL; |
6413 | 6762 |
6414 sml = purple_account_get_protocol_name(conv->account); | 6763 sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
6415 gtkconv = PIDGIN_CONVERSATION(conv); | 6764 gtkconv = PIDGIN_CONVERSATION(conv); |
6416 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); | 6765 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); |
6417 | 6766 |
6418 if (!smiley) | 6767 if (!smiley) |
6419 return; | 6768 return; |
6425 if (!smiley->loader) | 6774 if (!smiley->loader) |
6426 return; | 6775 return; |
6427 | 6776 |
6428 if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) { | 6777 if (!gdk_pixbuf_loader_write(smiley->loader, data, size, &error) || error) { |
6429 purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() " | 6778 purple_debug_warning("gtkconv", "gdk_pixbuf_loader_write() " |
6430 "failed with size=%zu: %s\n", size, | 6779 "failed with size=%" G_GSIZE_FORMAT ": %s\n", size, |
6431 error ? error->message : "(no error message)"); | 6780 error ? error->message : "(no error message)"); |
6432 if (error) | 6781 if (error) |
6433 g_error_free(error); | 6782 g_error_free(error); |
6434 /* We must stop using the GdkPixbufLoader because trying to load | 6783 /* We must stop using the GdkPixbufLoader because trying to load |
6435 certain invalid GIFs with at least gdk-pixbuf 2.23.3 can return | 6784 certain invalid GIFs with at least gdk-pixbuf 2.23.3 can return |
6438 But we also don't want to set smiley->loader to NULL because our | 6787 But we also don't want to set smiley->loader to NULL because our |
6439 code might expect it to be set. So create a new loader. */ | 6788 code might expect it to be set. So create a new loader. */ |
6440 g_object_unref(G_OBJECT(smiley->loader)); | 6789 g_object_unref(G_OBJECT(smiley->loader)); |
6441 smiley->loader = gdk_pixbuf_loader_new(); | 6790 smiley->loader = gdk_pixbuf_loader_new(); |
6442 } | 6791 } |
6792 #endif /* if 0 */ | |
6443 } | 6793 } |
6444 | 6794 |
6445 static void | 6795 static void |
6446 pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile) | 6796 pidgin_conv_custom_smiley_close(PurpleConversation *conv, const char *smile) |
6447 { | 6797 { |
6798 /* TODO WEBKIT */ | |
6799 #if 0 | |
6448 PidginConversation *gtkconv; | 6800 PidginConversation *gtkconv; |
6449 GtkIMHtmlSmiley *smiley; | 6801 GtkIMHtmlSmiley *smiley; |
6450 const char *sml; | 6802 const char *sml; |
6451 GError *error = NULL; | 6803 GError *error = NULL; |
6452 | 6804 |
6453 g_return_if_fail(conv != NULL); | 6805 g_return_if_fail(conv != NULL); |
6454 g_return_if_fail(smile != NULL); | 6806 g_return_if_fail(smile != NULL); |
6455 | 6807 |
6456 sml = purple_account_get_protocol_name(conv->account); | 6808 sml = purple_account_get_protocol_name(purple_conversation_get_account(conv)); |
6457 gtkconv = PIDGIN_CONVERSATION(conv); | 6809 gtkconv = PIDGIN_CONVERSATION(conv); |
6458 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); | 6810 smiley = gtk_imhtml_smiley_get(GTK_IMHTML(gtkconv->imhtml), sml, smile); |
6459 | 6811 |
6460 if (!smiley) | 6812 if (!smiley) |
6461 return; | 6813 return; |
6479 to set smiley->loader to NULL because our code might expect it | 6831 to set smiley->loader to NULL because our code might expect it |
6480 to be set. So create a new loader. */ | 6832 to be set. So create a new loader. */ |
6481 g_object_unref(G_OBJECT(smiley->loader)); | 6833 g_object_unref(G_OBJECT(smiley->loader)); |
6482 smiley->loader = gdk_pixbuf_loader_new(); | 6834 smiley->loader = gdk_pixbuf_loader_new(); |
6483 } | 6835 } |
6836 #endif /* if 0 */ | |
6484 } | 6837 } |
6485 | 6838 |
6486 static void | 6839 static void |
6487 pidgin_conv_send_confirm(PurpleConversation *conv, const char *message) | 6840 pidgin_conv_send_confirm(PurpleConversation *conv, const char *message) |
6488 { | 6841 { |
6510 win = pidgin_conv_get_window(gtkconv); | 6863 win = pidgin_conv_get_window(gtkconv); |
6511 gc = purple_conversation_get_gc(conv); | 6864 gc = purple_conversation_get_gc(conv); |
6512 account = purple_conversation_get_account(conv); | 6865 account = purple_conversation_get_account(conv); |
6513 | 6866 |
6514 if (gc != NULL) | 6867 if (gc != NULL) |
6515 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 6868 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
6516 | 6869 |
6517 if (win->menu.send_to != NULL) | 6870 if (win->menu.send_to != NULL) |
6518 update_send_to_selection(win); | 6871 update_send_to_selection(win); |
6519 | 6872 |
6520 /* | 6873 /* |
6588 */ | 6941 */ |
6589 if ((gc != NULL) && | 6942 if ((gc != NULL) && |
6590 ((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) || | 6943 ((purple_conversation_get_type(conv) != PURPLE_CONV_TYPE_CHAT) || |
6591 !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) )) | 6944 !purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)) )) |
6592 { | 6945 { |
6946 PurpleConnectionFlags features = purple_conversation_get_features(conv); | |
6593 /* Account is online */ | 6947 /* Account is online */ |
6594 /* Deal with the toolbar */ | 6948 /* Deal with the toolbar */ |
6595 if (conv->features & PURPLE_CONNECTION_HTML) | 6949 if (features & PURPLE_CONNECTION_HTML) |
6596 { | 6950 { |
6597 buttons = GTK_IMHTML_ALL; /* Everything on */ | 6951 buttons = GTK_IMHTML_ALL; /* Everything on */ |
6598 if (conv->features & PURPLE_CONNECTION_NO_BGCOLOR) | 6952 if (features & PURPLE_CONNECTION_NO_BGCOLOR) |
6599 buttons &= ~GTK_IMHTML_BACKCOLOR; | 6953 buttons &= ~GTK_IMHTML_BACKCOLOR; |
6600 if (conv->features & PURPLE_CONNECTION_NO_FONTSIZE) | 6954 if (features & PURPLE_CONNECTION_NO_FONTSIZE) |
6601 { | 6955 { |
6602 buttons &= ~GTK_IMHTML_GROW; | 6956 buttons &= ~GTK_IMHTML_GROW; |
6603 buttons &= ~GTK_IMHTML_SHRINK; | 6957 buttons &= ~GTK_IMHTML_SHRINK; |
6604 } | 6958 } |
6605 if (conv->features & PURPLE_CONNECTION_NO_URLDESC) | 6959 if (features & PURPLE_CONNECTION_NO_URLDESC) |
6606 buttons &= ~GTK_IMHTML_LINKDESC; | 6960 buttons &= ~GTK_IMHTML_LINKDESC; |
6607 } else { | 6961 } else { |
6608 buttons = GTK_IMHTML_SMILEY | GTK_IMHTML_IMAGE; | 6962 buttons = GTK_IMHTML_SMILEY | GTK_IMHTML_IMAGE; |
6609 } | 6963 } |
6610 | 6964 |
6611 if (!(prpl_info->options & OPT_PROTO_IM_IMAGE)) | 6965 if (!(prpl_info->options & OPT_PROTO_IM_IMAGE) |
6612 conv->features |= PURPLE_CONNECTION_NO_IMAGES; | 6966 && !(features & PURPLE_CONNECTION_NO_IMAGES)) { |
6613 | 6967 features |= PURPLE_CONNECTION_NO_IMAGES; |
6614 if(conv->features & PURPLE_CONNECTION_NO_IMAGES) | 6968 purple_conversation_set_features(conv, features); |
6969 } | |
6970 | |
6971 if (features & PURPLE_CONNECTION_NO_IMAGES) | |
6615 buttons &= ~GTK_IMHTML_IMAGE; | 6972 buttons &= ~GTK_IMHTML_IMAGE; |
6616 | 6973 |
6617 if (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) | 6974 if (features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY) |
6618 buttons |= GTK_IMHTML_CUSTOM_SMILEY; | 6975 buttons |= GTK_IMHTML_CUSTOM_SMILEY; |
6619 else | 6976 else |
6620 buttons &= ~GTK_IMHTML_CUSTOM_SMILEY; | 6977 buttons &= ~GTK_IMHTML_CUSTOM_SMILEY; |
6621 | 6978 |
6622 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); | 6979 gtk_imhtml_set_format_functions(GTK_IMHTML(gtkconv->entry), buttons); |
6626 /* Deal with menu items */ | 6983 /* Deal with menu items */ |
6627 gtk_widget_set_sensitive(win->menu.view_log, TRUE); | 6984 gtk_widget_set_sensitive(win->menu.view_log, TRUE); |
6628 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); | 6985 gtk_widget_set_sensitive(win->menu.add_pounce, TRUE); |
6629 gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); | 6986 gtk_widget_set_sensitive(win->menu.get_info, (prpl_info->get_info != NULL)); |
6630 gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); | 6987 gtk_widget_set_sensitive(win->menu.invite, (prpl_info->chat_invite != NULL)); |
6631 gtk_widget_set_sensitive(win->menu.insert_link, (conv->features & PURPLE_CONNECTION_HTML)); | 6988 gtk_widget_set_sensitive(win->menu.insert_link, (features & PURPLE_CONNECTION_HTML)); |
6632 gtk_widget_set_sensitive(win->menu.insert_image, !(conv->features & PURPLE_CONNECTION_NO_IMAGES)); | 6989 gtk_widget_set_sensitive(win->menu.insert_image, !(features & PURPLE_CONNECTION_NO_IMAGES)); |
6633 | 6990 |
6634 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) | 6991 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) |
6635 { | 6992 { |
6636 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL) || (prpl_info->add_buddy_with_invite != NULL)); | 6993 gtk_widget_set_sensitive(win->menu.add, (prpl_info->add_buddy != NULL)); |
6637 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); | 6994 gtk_widget_set_sensitive(win->menu.remove, (prpl_info->remove_buddy != NULL)); |
6638 gtk_widget_set_sensitive(win->menu.send_file, | 6995 gtk_widget_set_sensitive(win->menu.send_file, |
6639 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || | 6996 (prpl_info->send_file != NULL && (!prpl_info->can_receive_file || |
6640 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); | 6997 prpl_info->can_receive_file(gc, purple_conversation_get_name(conv))))); |
6641 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL)); | 6998 gtk_widget_set_sensitive(g_object_get_data(G_OBJECT(win->window), "get_attention"), (prpl_info->send_attention != NULL)); |
6678 { | 7035 { |
6679 GList *l = NULL; | 7036 GList *l = NULL; |
6680 if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) && | 7037 if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) && |
6681 (gtkconv->u.im->anim)) | 7038 (gtkconv->u.im->anim)) |
6682 { | 7039 { |
6683 PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name); | 7040 PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
6684 window_icon = | 7041 window_icon = |
6685 gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); | 7042 gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); |
6686 | 7043 |
6687 if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) | 7044 if (buddy && !PURPLE_BUDDY_IS_ONLINE(buddy)) |
6688 gdk_pixbuf_saturate_and_pixelate(window_icon, window_icon, 0.0, FALSE); | 7045 gdk_pixbuf_saturate_and_pixelate(window_icon, window_icon, 0.0, FALSE); |
6751 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, | 7108 gtk_tooltips_set_tip(gtkconv->tooltips, gtkchat->topic_text, |
6752 topic ? topic : "", NULL); | 7109 topic ? topic : "", NULL); |
6753 } | 7110 } |
6754 } | 7111 } |
6755 | 7112 |
7113 #if 0 | |
6756 if (fields & PIDGIN_CONV_SMILEY_THEME) | 7114 if (fields & PIDGIN_CONV_SMILEY_THEME) |
6757 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->imhtml); | 7115 pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview); |
7116 #endif | |
6758 | 7117 |
6759 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) || | 7118 if ((fields & PIDGIN_CONV_COLORIZE_TITLE) || |
6760 (fields & PIDGIN_CONV_SET_TITLE) || | 7119 (fields & PIDGIN_CONV_SET_TITLE) || |
6761 (fields & PIDGIN_CONV_TOPIC)) | 7120 (fields & PIDGIN_CONV_TOPIC)) |
6762 { | 7121 { |
6779 title = g_strdup_printf("(%s)", purple_conversation_get_title(conv)); | 7138 title = g_strdup_printf("(%s)", purple_conversation_get_title(conv)); |
6780 else | 7139 else |
6781 title = g_strdup(purple_conversation_get_title(conv)); | 7140 title = g_strdup(purple_conversation_get_title(conv)); |
6782 | 7141 |
6783 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 7142 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
6784 buddy = purple_find_buddy(account, conv->name); | 7143 buddy = purple_find_buddy(account, purple_conversation_get_name(conv)); |
6785 if (buddy) { | 7144 if (buddy) { |
6786 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE); | 7145 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE); |
6787 } else { | 7146 } else { |
6788 markup = title; | 7147 markup = title; |
6789 } | 7148 } |
6824 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { | 7183 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { |
6825 atk_object_set_description(accessibility_obj, _("Nick Said")); | 7184 atk_object_set_description(accessibility_obj, _("Nick Said")); |
6826 style = "tab-label-attention"; | 7185 style = "tab-label-attention"; |
6827 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { | 7186 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { |
6828 atk_object_set_description(accessibility_obj, _("Unread Messages")); | 7187 atk_object_set_description(accessibility_obj, _("Unread Messages")); |
6829 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT) | 7188 if (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_CHAT) |
6830 style = "tab-label-unreadchat"; | 7189 style = "tab-label-unreadchat"; |
6831 else | 7190 else |
6832 style = "tab-label-attention"; | 7191 style = "tab-label-attention"; |
6833 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { | 7192 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { |
6834 atk_object_set_description(accessibility_obj, _("New Event")); | 7193 atk_object_set_description(accessibility_obj, _("New Event")); |
7330 | 7689 |
7331 gtk_check_menu_item_set_active( | 7690 gtk_check_menu_item_set_active( |
7332 GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), | 7691 GTK_CHECK_MENU_ITEM(win->menu.show_timestamps), |
7333 (gboolean)GPOINTER_TO_INT(value)); | 7692 (gboolean)GPOINTER_TO_INT(value)); |
7334 | 7693 |
7694 /* TODO WEBKIT: Use WebKit version of this. */ | |
7695 #if 0 | |
7335 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), | 7696 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), |
7336 (gboolean)GPOINTER_TO_INT(value)); | 7697 (gboolean)GPOINTER_TO_INT(value)); |
7698 #endif /* if 0 */ | |
7337 } | 7699 } |
7338 } | 7700 } |
7339 | 7701 |
7340 static void | 7702 static void |
7341 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type, | 7703 show_formatting_toolbar_pref_cb(const char *name, PurplePrefType type, |
7499 gtkconv = l->data; | 7861 gtkconv = l->data; |
7500 l = l->next; | 7862 l = l->next; |
7501 | 7863 |
7502 conv = gtkconv->active_conv; | 7864 conv = gtkconv->active_conv; |
7503 | 7865 |
7504 if (conv->type == PURPLE_CONV_TYPE_CHAT || | 7866 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT || |
7505 gtkconv->unseen_count == 0 || | 7867 gtkconv->unseen_count == 0 || |
7506 (when_away && !purple_status_is_available( | 7868 (when_away && !purple_status_is_available( |
7507 purple_account_get_active_status( | 7869 purple_account_get_active_status( |
7508 purple_conversation_get_account(conv))))) | 7870 purple_conversation_get_account(conv))))) |
7509 continue; | 7871 continue; |
7564 /* if (purple_conversation_get_account(conv) == account) */ | 7926 /* if (purple_conversation_get_account(conv) == account) */ |
7565 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | | 7927 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | |
7566 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); | 7928 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); |
7567 | 7929 |
7568 if (PURPLE_CONNECTION_IS_CONNECTED(gc) && | 7930 if (PURPLE_CONNECTION_IS_CONNECTED(gc) && |
7569 conv->type == PURPLE_CONV_TYPE_CHAT && | 7931 purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && |
7570 conv->account == gc->account && | 7932 purple_conversation_get_account(conv) == purple_connection_get_account(gc) && |
7571 purple_conversation_get_data(conv, "want-to-rejoin")) { | 7933 purple_conversation_get_data(conv, "want-to-rejoin")) { |
7572 GHashTable *comps = NULL; | 7934 GHashTable *comps = NULL; |
7573 PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name); | 7935 PurpleChat *chat = purple_blist_find_chat(purple_conversation_get_account(conv), purple_conversation_get_name(conv)); |
7574 if (chat == NULL) { | 7936 if (chat == NULL) { |
7575 if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) | 7937 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
7576 comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, conv->name); | 7938 |
7939 if (prpl_info->chat_info_defaults != NULL) | |
7940 comps = prpl_info->chat_info_defaults(gc, purple_conversation_get_name(conv)); | |
7577 } else { | 7941 } else { |
7578 comps = chat->components; | 7942 comps = chat->components; |
7579 } | 7943 } |
7580 serv_join_chat(gc, comps); | 7944 serv_join_chat(gc, comps); |
7581 if (chat == NULL && comps != NULL) | 7945 if (chat == NULL && comps != NULL) |
7726 { | 8090 { |
7727 PidginConversation *gtkconv = data; | 8091 PidginConversation *gtkconv = data; |
7728 int count = 0; | 8092 int count = 0; |
7729 int timer = gtkconv->attach.timer; | 8093 int timer = gtkconv->attach.timer; |
7730 time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); | 8094 time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); |
7731 gboolean im = (gtkconv->active_conv->type == PURPLE_CONV_TYPE_IM); | 8095 gboolean im = (purple_conversation_get_type(gtkconv->active_conv) == PURPLE_CONV_TYPE_IM); |
7732 | 8096 |
7733 gtkconv->attach.timer = 0; | 8097 gtkconv->attach.timer = 0; |
7734 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ | 8098 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ |
7735 PurpleConvMessage *msg = gtkconv->attach.current->data; | 8099 PurpleConvMessage *msg = gtkconv->attach.current->data; |
7736 if (!im && when && when < msg->when) { | 8100 if (!im && when && when < msg->when) { |
7737 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0); | 8101 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR><HR>"); |
7738 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); | 8102 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
7739 } | 8103 } |
7740 pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when); | 8104 pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when); |
7741 if (im) { | 8105 if (im) { |
7742 gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current); | 8106 gtkconv->attach.current = g_list_delete_link(gtkconv->attach.current, gtkconv->attach.current); |
7767 msgs = g_list_sort(msgs, message_compare); | 8131 msgs = g_list_sort(msgs, message_compare); |
7768 for (; msgs; msgs = g_list_delete_link(msgs, msgs)) { | 8132 for (; msgs; msgs = g_list_delete_link(msgs, msgs)) { |
7769 PurpleConvMessage *msg = msgs->data; | 8133 PurpleConvMessage *msg = msgs->data; |
7770 pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when); | 8134 pidgin_conv_write_conv(msg->conv, msg->who, msg->alias, msg->what, msg->flags, msg->when); |
7771 } | 8135 } |
7772 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0); | 8136 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<BR><HR>"); |
7773 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); | 8137 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
7774 } | 8138 } |
7775 | 8139 |
7776 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); | 8140 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
7777 purple_signal_emit(pidgin_conversations_get_handle(), | 8141 purple_signal_emit(pidgin_conversations_get_handle(), |
7850 } else { | 8214 } else { |
7851 purple_signal_emit(pidgin_conversations_get_handle(), | 8215 purple_signal_emit(pidgin_conversations_get_handle(), |
7852 "conversation-displayed", gtkconv); | 8216 "conversation-displayed", gtkconv); |
7853 } | 8217 } |
7854 | 8218 |
7855 if (conv->type == PURPLE_CONV_TYPE_CHAT) { | 8219 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { |
7856 pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC); | 8220 pidgin_conv_update_fields(conv, PIDGIN_CONV_TOPIC); |
7857 pidgin_conv_chat_add_users(conv, PURPLE_CONV_CHAT(conv)->in_room, TRUE); | 8221 pidgin_conv_chat_add_users(conv, purple_conv_chat_get_users(PURPLE_CONV_CHAT(conv)), TRUE); |
7858 } | 8222 } |
7859 | 8223 |
7860 return TRUE; | 8224 return TRUE; |
7861 } | 8225 } |
7862 | 8226 |
7874 void *handle = pidgin_conversations_get_handle(); | 8238 void *handle = pidgin_conversations_get_handle(); |
7875 void *blist_handle = purple_blist_get_handle(); | 8239 void *blist_handle = purple_blist_get_handle(); |
7876 | 8240 |
7877 /* Conversations */ | 8241 /* Conversations */ |
7878 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations"); | 8242 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations"); |
8243 purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations/themes"); | |
7879 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE); | 8244 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE); |
7880 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE); | 8245 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE); |
7881 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE); | 8246 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE); |
7882 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE); | 8247 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE); |
7883 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE); | 8248 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE); |
8157 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, | 8522 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, |
8158 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); | 8523 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
8159 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, | 8524 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, |
8160 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); | 8525 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
8161 | 8526 |
8527 purple_theme_manager_register_type(g_object_new(PIDGIN_TYPE_CONV_THEME_LOADER, "type", "conversation", NULL)); | |
8528 | |
8162 { | 8529 { |
8163 /* Set default tab colors */ | 8530 /* Set default tab colors */ |
8164 GString *str = g_string_new(NULL); | 8531 GString *str = g_string_new(NULL); |
8165 GtkSettings *settings = gtk_settings_get_default(); | 8532 GtkSettings *settings = gtk_settings_get_default(); |
8166 GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now; | 8533 GtkStyle *parent = gtk_rc_get_style_by_paths(settings, "tab-container.tab-label*", NULL, G_TYPE_NONE), *now; |
9045 if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) { | 9412 if (!GTK_WIDGET_VISIBLE(gtkconv->infopane)) { |
9046 /* There's already an entry for alias. Let's not create another one. */ | 9413 /* There's already an entry for alias. Let's not create another one. */ |
9047 return FALSE; | 9414 return FALSE; |
9048 } | 9415 } |
9049 | 9416 |
9050 if (!purple_account_is_connected(gtkconv->active_conv->account)) { | 9417 if (!purple_account_is_connected(purple_conversation_get_account(gtkconv->active_conv))) { |
9051 /* Do not allow aliasing someone on a disconnected account. */ | 9418 /* Do not allow aliasing someone on a disconnected account. */ |
9052 return FALSE; | 9419 return FALSE; |
9053 } | 9420 } |
9054 | 9421 |
9055 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { | 9422 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
9056 PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name); | 9423 PurpleBuddy *buddy = purple_find_buddy(purple_conversation_get_account(gtkconv->active_conv), purple_conversation_get_name(gtkconv->active_conv)); |
9057 if (!buddy) | 9424 if (!buddy) |
9058 /* This buddy isn't in your buddy list, so we can't alias him */ | 9425 /* This buddy isn't in your buddy list, so we can't alias him */ |
9059 return FALSE; | 9426 return FALSE; |
9060 | 9427 |
9061 text = purple_buddy_get_contact_alias(buddy); | 9428 text = purple_buddy_get_contact_alias(buddy); |
9063 PurpleConnection *gc; | 9430 PurpleConnection *gc; |
9064 PurplePluginProtocolInfo *prpl_info = NULL; | 9431 PurplePluginProtocolInfo *prpl_info = NULL; |
9065 | 9432 |
9066 gc = purple_conversation_get_gc(conv); | 9433 gc = purple_conversation_get_gc(conv); |
9067 if (gc != NULL) | 9434 if (gc != NULL) |
9068 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); | 9435 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_connection_get_prpl(gc)); |
9069 if (prpl_info && prpl_info->set_chat_topic == NULL) | 9436 if (prpl_info && prpl_info->set_chat_topic == NULL) |
9070 /* This protocol doesn't support setting the chat room topic */ | 9437 /* This protocol doesn't support setting the chat room topic */ |
9071 return FALSE; | 9438 return FALSE; |
9072 | 9439 |
9073 text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)); | 9440 text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)); |