| 4943 G_CALLBACK(pidgin_conv_end_quickfind), gtkconv); |
4944 G_CALLBACK(pidgin_conv_end_quickfind), gtkconv); |
| 4944 } |
4945 } |
| 4945 |
4946 |
| 4946 /* }}} */ |
4947 /* }}} */ |
| 4947 |
4948 |
| |
4949 static char * |
| |
4950 replace_header_tokens(PurpleConversation *conv, const char *text) |
| |
4951 { |
| |
4952 GString *str; |
| |
4953 const char *cur = text; |
| |
4954 const char *prev = cur; |
| |
4955 |
| |
4956 if (text == NULL || *text == '\0') |
| |
4957 return NULL; |
| |
4958 |
| |
4959 str = g_string_new(NULL); |
| |
4960 while ((cur = strchr(cur, '%'))) { |
| |
4961 const char *replace = NULL; |
| |
4962 const char *fin = NULL; |
| |
4963 |
| |
4964 if (g_str_has_prefix(cur, "%chatName%")) { |
| |
4965 replace = conv->name; |
| |
4966 |
| |
4967 } else if (g_str_has_prefix(cur, "%sourceName%")) { |
| |
4968 replace = purple_account_get_alias(conv->account); |
| |
4969 if (replace == NULL) |
| |
4970 replace = purple_account_get_username(conv->account); |
| |
4971 |
| |
4972 } else if (g_str_has_prefix(cur, "%destinationName%")) { |
| |
4973 PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name); |
| |
4974 if (buddy) { |
| |
4975 replace = purple_buddy_get_alias(buddy); |
| |
4976 } else { |
| |
4977 replace = conv->name; |
| |
4978 } |
| |
4979 |
| |
4980 } else if (g_str_has_prefix(cur, "%incomingIconPath%")) { |
| |
4981 PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); |
| |
4982 if (icon) |
| |
4983 replace = purple_buddy_icon_get_full_path(icon); |
| |
4984 |
| |
4985 } else if (g_str_has_prefix(cur, "%outgoingIconPath%")) { |
| |
4986 replace = purple_account_get_buddy_icon_path(conv->account); |
| |
4987 |
| |
4988 } else if (g_str_has_prefix(cur, "%timeOpened")) { |
| |
4989 const char *tmp = cur + strlen("%timeOpened"); |
| |
4990 char *format = NULL; |
| |
4991 if (*tmp == '{') { |
| |
4992 const char *end; |
| |
4993 tmp++; |
| |
4994 end = strstr(tmp, "}%"); |
| |
4995 if (!end) /* Invalid string */ |
| |
4996 continue; |
| |
4997 format = g_strndup(tmp, end - tmp); |
| |
4998 fin = end + 1; |
| |
4999 } |
| |
5000 replace = purple_utf8_strftime(format ? format : "%X", NULL); |
| |
5001 g_free(format); |
| |
5002 |
| |
5003 } else { |
| |
5004 continue; |
| |
5005 } |
| |
5006 |
| |
5007 /* Here we have a replacement to make */ |
| |
5008 g_string_append_len(str, prev, cur - prev); |
| |
5009 if (replace) |
| |
5010 g_string_append(str, replace); |
| |
5011 |
| |
5012 /* And update the pointers */ |
| |
5013 if (fin) { |
| |
5014 prev = cur = fin + 1; |
| |
5015 } else { |
| |
5016 prev = cur = strchr(cur + 1, '%') + 1; |
| |
5017 } |
| |
5018 } |
| |
5019 |
| |
5020 /* And wrap it up */ |
| |
5021 g_string_append(str, prev); |
| |
5022 return g_string_free(str, FALSE); |
| |
5023 } |
| |
5024 |
| |
5025 static char * |
| |
5026 replace_template_tokens(PidginConvTheme *theme, const char *header, const char *footer) |
| |
5027 { |
| |
5028 GString *str; |
| |
5029 const char *text; |
| |
5030 char **ms; |
| |
5031 char *path; |
| |
5032 |
| |
5033 text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN); |
| |
5034 ms = g_strsplit(text, "%@", 6); |
| |
5035 if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) { |
| |
5036 g_strfreev(ms); |
| |
5037 return NULL; |
| |
5038 } |
| |
5039 |
| |
5040 str = g_string_new(NULL); |
| |
5041 |
| |
5042 g_string_append(str, ms[0]); |
| |
5043 g_string_append(str, "file://"); |
| |
5044 path = pidgin_conversation_theme_get_template_path(theme); |
| |
5045 g_string_append(str, path); |
| |
5046 g_free(path); |
| |
5047 |
| |
5048 g_string_append(str, ms[1]); |
| |
5049 |
| |
5050 text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS); |
| |
5051 g_string_append(str, text); |
| |
5052 |
| |
5053 g_string_append(str, ms[2]); |
| |
5054 |
| |
5055 g_string_append(str, "file://"); |
| |
5056 path = pidgin_conversation_theme_get_css_path(theme); |
| |
5057 g_string_append(str, path); |
| |
5058 g_free(path); |
| |
5059 |
| |
5060 g_string_append(str, ms[3]); |
| |
5061 if (header) |
| |
5062 g_string_append(str, header); |
| |
5063 g_string_append(str, ms[4]); |
| |
5064 if (footer) |
| |
5065 g_string_append(str, footer); |
| |
5066 g_string_append(str, ms[5]); |
| |
5067 |
| |
5068 g_strfreev(ms); |
| |
5069 |
| |
5070 return g_string_free(str, FALSE); |
| |
5071 } |
| |
5072 |
| |
5073 static void |
| |
5074 set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme) |
| |
5075 { |
| |
5076 WebKitWebSettings *settings; |
| |
5077 const GValue *val; |
| |
5078 |
| |
5079 g_object_get(G_OBJECT(webview), "settings", &settings, NULL); |
| |
5080 |
| |
5081 val = pidgin_conversation_theme_lookup(theme, "DefaultFontFamily", TRUE); |
| |
5082 if (val && G_VALUE_HOLDS_STRING(val)) |
| |
5083 g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL); |
| |
5084 |
| |
5085 val = pidgin_conversation_theme_lookup(theme, "DefaultFontSize", TRUE); |
| |
5086 if (val && G_VALUE_HOLDS_INT(val)) |
| |
5087 g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL); |
| |
5088 |
| |
5089 val = pidgin_conversation_theme_lookup(theme, "DefaultBackgroundIsTransparent", TRUE); |
| |
5090 if (val && G_VALUE_HOLDS_BOOLEAN(val)) |
| |
5091 /* this does not work :( */ |
| |
5092 webkit_web_view_set_transparent(webview, g_value_get_boolean(val)); |
| |
5093 } |
| |
5094 |
| 4948 static GtkWidget * |
5095 static GtkWidget * |
| 4949 setup_common_pane(PidginConversation *gtkconv) |
5096 setup_common_pane(PidginConversation *gtkconv) |
| 4950 { |
5097 { |
| 4951 GtkWidget *vbox, *frame, *webview_sw, *event_box; |
5098 GtkWidget *vbox, *frame, *webview_sw, *event_box; |
| 4952 GtkCellRenderer *rend; |
5099 GtkCellRenderer *rend; |
| 4953 GtkTreePath *path; |
5100 GtkTreePath *path; |
| 4954 PurpleConversation *conv = gtkconv->active_conv; |
5101 PurpleConversation *conv = gtkconv->active_conv; |
| 4955 PurpleBuddy *buddy; |
5102 PurpleBuddy *buddy; |
| 4956 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); |
5103 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); |
| 4957 int buddyicon_size = 0; |
5104 int buddyicon_size = 0; |
| |
5105 char *header, *footer; |
| |
5106 char *template; |
| 4958 |
5107 |
| 4959 /* Setup the top part of the pane */ |
5108 /* Setup the top part of the pane */ |
| 4960 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
5109 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 4961 gtk_widget_show(vbox); |
5110 gtk_widget_show(vbox); |
| 4962 |
5111 |
| 5045 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); |
5194 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); |
| 5046 |
5195 |
| 5047 /* Setup the webkit widget */ |
5196 /* Setup the webkit widget */ |
| 5048 frame = pidgin_create_webview(FALSE, >kconv->webview, NULL, &webview_sw); |
5197 frame = pidgin_create_webview(FALSE, >kconv->webview, NULL, &webview_sw); |
| 5049 gtk_widget_set_size_request(gtkconv->webview, -1, 0); |
5198 gtk_widget_set_size_request(gtkconv->webview, -1, 0); |
| |
5199 |
| |
5200 header = replace_header_tokens(conv, |
| |
5201 pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER)); |
| |
5202 footer = replace_header_tokens(conv, |
| |
5203 pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER)); |
| |
5204 template = replace_template_tokens(gtkconv->theme, header, footer); |
| |
5205 g_free(header); |
| |
5206 g_free(footer); |
| |
5207 |
| |
5208 if (template != NULL) { |
| |
5209 char *basedir; |
| |
5210 char *baseuri; |
| |
5211 |
| |
5212 purple_debug_info("webkit", "template: %s\n", template); |
| |
5213 |
| |
5214 set_theme_webkit_settings(WEBKIT_WEB_VIEW(gtkconv->webview), gtkconv->theme); |
| |
5215 |
| |
5216 basedir = pidgin_conversation_theme_get_template_path(gtkconv->theme); |
| |
5217 baseuri = g_strdup_printf("file://%s", basedir); |
| |
5218 webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtkconv->webview), template, "text/html", "UTF-8", baseuri); |
| |
5219 |
| |
5220 if (chat) |
| |
5221 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), "document.getElementById('Chat').className = 'groupchat'"); |
| |
5222 |
| |
5223 g_free(basedir); |
| |
5224 g_free(baseuri); |
| |
5225 g_free(template); |
| |
5226 } |
| 5050 |
5227 |
| 5051 if (chat) { |
5228 if (chat) { |
| 5052 GtkWidget *hpaned; |
5229 GtkWidget *hpaned; |
| 5053 |
5230 |
| 5054 /* Add the topic */ |
5231 /* Add the topic */ |
| 5777 |
5963 |
| 5778 g_free(*str); |
5964 g_free(*str); |
| 5779 *str = ret; |
5965 *str = ret; |
| 5780 #endif |
5966 #endif |
| 5781 } |
5967 } |
| |
5968 #endif |
| |
5969 |
| |
5970 static char * |
| |
5971 replace_message_tokens( |
| |
5972 const char *text, |
| |
5973 PurpleConversation *conv, |
| |
5974 const char *name, |
| |
5975 const char *alias, |
| |
5976 const char *message, |
| |
5977 PurpleMessageFlags flags, |
| |
5978 time_t mtime) |
| |
5979 { |
| |
5980 GString *str = g_string_new(NULL); |
| |
5981 const char *cur = text; |
| |
5982 const char *prev = cur; |
| |
5983 |
| |
5984 while ((cur = strchr(cur, '%'))) { |
| |
5985 const char *replace = NULL; |
| |
5986 const char *fin = NULL; |
| |
5987 |
| |
5988 if (g_str_has_prefix(cur, "%message%")) { |
| |
5989 replace = message; |
| |
5990 |
| |
5991 } else if (g_str_has_prefix(cur, "%messageClasses%")) { |
| |
5992 replace = flags & PURPLE_MESSAGE_SEND ? "outgoing" : |
| |
5993 flags & PURPLE_MESSAGE_RECV ? "incoming" : "event"; |
| |
5994 |
| |
5995 } else if (g_str_has_prefix(cur, "%time")) { |
| |
5996 const char *tmp = cur + strlen("%time"); |
| |
5997 char *format = NULL; |
| |
5998 if (*tmp == '{') { |
| |
5999 char *end; |
| |
6000 tmp++; |
| |
6001 end = strstr(tmp, "}%"); |
| |
6002 if (!end) /* Invalid string */ |
| |
6003 continue; |
| |
6004 format = g_strndup(tmp, end - tmp); |
| |
6005 fin = end + 1; |
| |
6006 } |
| |
6007 replace = purple_utf8_strftime(format ? format : "%X", NULL); |
| |
6008 g_free(format); |
| |
6009 |
| |
6010 } else if (g_str_has_prefix(cur, "%userIconPath%")) { |
| |
6011 if (flags & PURPLE_MESSAGE_SEND) { |
| |
6012 if (purple_account_get_bool(conv->account, "use-global-buddyicon", TRUE)) { |
| |
6013 replace = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon"); |
| |
6014 } else { |
| |
6015 PurpleStoredImage *img = purple_buddy_icons_find_account_icon(conv->account); |
| |
6016 replace = purple_imgstore_get_filename(img); |
| |
6017 } |
| |
6018 if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { |
| |
6019 replace = g_build_filename("Outgoing", "buddy_icon.png", NULL); |
| |
6020 } |
| |
6021 } else if (flags & PURPLE_MESSAGE_RECV) { |
| |
6022 PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv)); |
| |
6023 if (icon) |
| |
6024 replace = purple_buddy_icon_get_full_path(icon); |
| |
6025 if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) { |
| |
6026 replace = g_build_filename("Incoming", "buddy_icon.png", NULL); |
| |
6027 } |
| |
6028 } |
| |
6029 |
| |
6030 } else if (g_str_has_prefix(cur, "%senderScreenName%")) { |
| |
6031 replace = name; |
| |
6032 |
| |
6033 } else if (g_str_has_prefix(cur, "%sender%")) { |
| |
6034 replace = alias; |
| |
6035 |
| |
6036 } else if (g_str_has_prefix(cur, "%service%")) { |
| |
6037 replace = purple_account_get_protocol_name(conv->account); |
| |
6038 |
| |
6039 } else { |
| |
6040 cur++; |
| |
6041 continue; |
| |
6042 } |
| |
6043 |
| |
6044 /* Here we have a replacement to make */ |
| |
6045 g_string_append_len(str, prev, cur - prev); |
| |
6046 if (replace) |
| |
6047 g_string_append(str, replace); |
| |
6048 |
| |
6049 /* And update the pointers */ |
| |
6050 if (fin) { |
| |
6051 prev = cur = fin + 1; |
| |
6052 } else { |
| |
6053 prev = cur = strchr(cur + 1, '%') + 1; |
| |
6054 } |
| |
6055 |
| |
6056 } |
| |
6057 |
| |
6058 /* And wrap it up */ |
| |
6059 g_string_append(str, prev); |
| |
6060 |
| |
6061 return g_string_free(str, FALSE); |
| |
6062 } |
| 5782 |
6063 |
| 5783 static void |
6064 static void |
| 5784 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, |
6065 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, |
| 5785 const char *message, PurpleMessageFlags flags, |
6066 const char *message, PurpleMessageFlags flags, |
| 5786 time_t mtime) |
6067 time_t mtime) |
| 5787 { |
6068 { |
| 5788 PidginConversation *gtkconv; |
6069 PidginConversation *gtkconv; |
| 5789 PurpleConnection *gc; |
6070 PurpleConnection *gc; |
| 5790 PurpleAccount *account; |
6071 PurpleAccount *account; |
| |
6072 #if 0 |
| 5791 int gtk_font_options = 0; |
6073 int gtk_font_options = 0; |
| 5792 int gtk_font_options_all = 0; |
6074 int gtk_font_options_all = 0; |
| 5793 char buf2[BUF_LONG]; |
6075 char buf2[BUF_LONG]; |
| 5794 gboolean show_date; |
6076 gboolean show_date; |
| 5795 char *mdate; |
6077 char *mdate; |
| 5796 char *str; |
6078 char *str; |
| 5797 char *with_font_tag; |
6079 char *with_font_tag; |
| 5798 char *sml_attrib = NULL; |
6080 char *sml_attrib = NULL; |
| |
6081 #endif |
| 5799 size_t length; |
6082 size_t length; |
| 5800 PurpleConversationType type; |
6083 PurpleConversationType type; |
| 5801 char *displaying; |
6084 char *displaying; |
| 5802 gboolean plugin_return; |
6085 gboolean plugin_return; |
| |
6086 #if 0 |
| 5803 gboolean is_rtl_message = FALSE; |
6087 gboolean is_rtl_message = FALSE; |
| |
6088 #endif |
| |
6089 |
| |
6090 const char *message_html; |
| |
6091 char *msg; |
| |
6092 char *escape; |
| |
6093 char *script; |
| |
6094 char *smileyed; |
| |
6095 PurpleMessageFlags old_flags; |
| |
6096 const char *func = "appendMessage"; |
| 5804 |
6097 |
| 5805 g_return_if_fail(conv != NULL); |
6098 g_return_if_fail(conv != NULL); |
| 5806 gtkconv = PIDGIN_CONVERSATION(conv); |
6099 gtkconv = PIDGIN_CONVERSATION(conv); |
| 5807 g_return_if_fail(gtkconv != NULL); |
6100 g_return_if_fail(gtkconv != NULL); |
| 5808 |
6101 |
| 5855 g_free(displaying); |
6148 g_free(displaying); |
| 5856 return; |
6149 return; |
| 5857 } |
6150 } |
| 5858 length = strlen(displaying) + 1; |
6151 length = strlen(displaying) + 1; |
| 5859 |
6152 |
| |
6153 old_flags = gtkconv->last_flags; |
| |
6154 if ((flags & PURPLE_MESSAGE_SEND) && (old_flags & PURPLE_MESSAGE_SEND)) { |
| |
6155 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT); |
| |
6156 func = "appendNextMessage"; |
| |
6157 } else if (flags & PURPLE_MESSAGE_SEND) { |
| |
6158 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT); |
| |
6159 } else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) { |
| |
6160 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT); |
| |
6161 func = "appendNextMessage"; |
| |
6162 } else if (flags & PURPLE_MESSAGE_RECV) { |
| |
6163 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT); |
| |
6164 } else { |
| |
6165 message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS); |
| |
6166 } |
| |
6167 gtkconv->last_flags = flags; |
| |
6168 |
| |
6169 smileyed = smiley_parse_markup(message, purple_account_get_protocol_id(account)); |
| |
6170 msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime); |
| |
6171 escape = gtk_webview_quote_js_string(msg); |
| |
6172 script = g_strdup_printf("%s(%s)", func, escape); |
| |
6173 |
| |
6174 purple_debug_info("webkit", "JS: %s\n", script); |
| |
6175 gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), script); |
| |
6176 |
| |
6177 g_free(script); |
| |
6178 g_free(smileyed); |
| |
6179 g_free(msg); |
| |
6180 g_free(escape); |
| |
6181 |
| |
6182 #if 0 |
| 5860 /* if the buffer is not empty add a <br> */ |
6183 /* if the buffer is not empty add a <br> */ |
| 5861 if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview))) |
6184 if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview))) |
| 5862 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />"); |
6185 gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />"); |
| 5863 |
6186 |
| 5864 /* First message in a conversation. */ |
6187 /* First message in a conversation. */ |