comparison src/gtkimhtml.c @ 7847:f10b8832360f

[gaim-migrate @ 8501] Improvement. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Sat, 13 Dec 2003 07:05:02 +0000
parents 10fe9f6d2b23
children 169e85869dcc
comparison
equal deleted inserted replaced
7846:61c07fefe1fc 7847:f10b8832360f
385 gtk_selection_data_set_text(selection_data, text, strlen(text)); 385 gtk_selection_data_set_text(selection_data, text, strlen(text));
386 } 386 }
387 g_free(text); 387 g_free(text);
388 } 388 }
389 389
390 static void gtk_imhtml_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml) 390 static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml)
391 { 391 {
392 GtkTextIter insert; 392 GtkTextIter insert;
393 GtkTextIter selection_bound; 393 GtkTextIter selection_bound;
394 394
395 gtk_text_buffer_get_iter_at_mark (imhtml->text_buffer, &insert, 395 gtk_text_buffer_get_iter_at_mark (imhtml->text_buffer, &insert,
455 GDK_SELECTION_PRIMARY))) 455 GDK_SELECTION_PRIMARY)))
456 gtk_text_buffer_remove_selection_clipboard (imhtml->text_buffer, clipboard); 456 gtk_text_buffer_remove_selection_clipboard (imhtml->text_buffer, clipboard);
457 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY), 457 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY),
458 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), 458 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry),
459 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, 459 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get,
460 (GtkClipboardClearFunc)gtk_imhtml_clipboard_clear, G_OBJECT(imhtml)); 460 (GtkClipboardClearFunc)gtk_imhtml_primary_clipboard_clear, G_OBJECT(imhtml));
461 } 461 }
462 return FALSE; 462 return FALSE;
463 } 463 }
464 #endif 464 #endif
465 465
968 gtk_imhtml_is_tag (const gchar *string, 968 gtk_imhtml_is_tag (const gchar *string,
969 gchar **tag, 969 gchar **tag,
970 gint *len, 970 gint *len,
971 gint *type) 971 gint *type)
972 { 972 {
973 char *close;
973 *type = 1; 974 *type = 1;
974 975
975 if (!strchr (string, '>')) 976
977 if (!(close = strchr (string, '>')))
976 return FALSE; 978 return FALSE;
977 979
978 VALID_TAG ("B"); 980 VALID_TAG ("B");
979 VALID_TAG ("BOLD"); 981 VALID_TAG ("BOLD");
980 VALID_TAG ("/B"); 982 VALID_TAG ("/B");
1036 VALID_OPT_TAG ("SPAN"); 1038 VALID_OPT_TAG ("SPAN");
1037 VALID_TAG ("/SPAN"); 1039 VALID_TAG ("/SPAN");
1038 VALID_TAG ("BR/"); /* hack until gtkimhtml handles things better */ 1040 VALID_TAG ("BR/"); /* hack until gtkimhtml handles things better */
1039 VALID_TAG ("IMG"); 1041 VALID_TAG ("IMG");
1040 VALID_OPT_TAG ("BR"); /* see comment 2 lines up */ 1042 VALID_OPT_TAG ("BR"); /* see comment 2 lines up */
1041 1043
1042 if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) { 1044 if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) {
1043 gchar *e = strstr (string + strlen("!--"), "-->"); 1045 gchar *e = strstr (string + strlen("!--"), "-->");
1044 if (e) { 1046 if (e) {
1045 *len = e - string + strlen ("-->"); 1047 *len = e - string + strlen ("-->");
1046 *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); 1048 *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->"));
1047 return TRUE; 1049 return TRUE;
1048 } 1050 }
1049 } 1051 }
1050 1052
1051 return FALSE; 1053 *type = -1;
1054 *len = close - string + 1;
1055 *tag = g_strndup(string, *len - 1);
1056 return TRUE;
1052 } 1057 }
1053 1058
1054 static gchar* 1059 static gchar*
1055 gtk_imhtml_get_html_opt (gchar *tag, 1060 gtk_imhtml_get_html_opt (gchar *tag,
1056 const gchar *opt) 1061 const gchar *opt)
1109 g_string_free(ret, FALSE); 1114 g_string_free(ret, FALSE);
1110 return val; 1115 return val;
1111 } 1116 }
1112 1117
1113 1118
1114 typedef enum {
1115 NEW_TEXT_BIT,
1116 NEW_COMMENT_BIT,
1117 NEW_SCALABLE_BIT
1118 } GtkIMHtmlBitType;
1119
1120 static inline void new_bit(GtkIMHtml *imhtml, GtkTextIter *iter, GtkIMHtmlBitType x, char *ws, int *wpos)
1121 {
1122 GtkTextMark *mark2;
1123 GtkTextIter siter;
1124 GtkIMHtmlScalable *scalable = NULL;
1125
1126 ws [*wpos] = '\0';
1127 mark2 = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE);
1128 gtk_text_buffer_insert(imhtml->text_buffer, iter, ws, -1);
1129
1130 gtk_text_buffer_delete_mark(imhtml->text_buffer, mark2);
1131 /*if (bold)
1132 gtk
1133 if (italics) \
1134 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", &siter, &iter); \
1135 if (underline) \
1136 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", &siter, &iter); \
1137 if (strike) \
1138 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", &siter, &iter); \
1139 if (sub) \
1140 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "SUB", &siter, &iter); \
1141 if (sup) \
1142 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "SUP", &siter, &iter); \
1143 if (pre) \
1144 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "PRE", &siter, &iter); \
1145 if (bg) { \
1146 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", bg, NULL); \
1147 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \
1148 } \
1149 if (fonts) { \
1150 GtkIMHtmlFontDetail *fd = fonts->data; \
1151 if (fd->fore) { \
1152 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", fd->fore, NULL); \
1153 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \
1154 } \
1155 if (fd->back) { \
1156 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", fd->back, NULL); \
1157 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \
1158 } \
1159 if (fd->face) { \
1160 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "family", fd->face, NULL); \
1161 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \
1162 } \
1163 if (fd->size) { \
1164 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "size-points", (double)POINT_SIZE(fd->size), NULL); \
1165 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \
1166 } \
1167 } \
1168 if (url) { \
1169 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "LINK", &siter, &iter); \
1170 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL); \
1171 \
1172 g_object_set_data(G_OBJECT(texttag), "link_url", g_strdup(url)); \
1173 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \
1174 } \
1175 */
1176 *wpos = 0;
1177 ws[0] = 0;
1178 gtk_text_buffer_get_end_iter(imhtml->text_buffer, iter);
1179 if (x == NEW_SCALABLE_BIT) {
1180 GdkRectangle rect;
1181
1182 }
1183 }
1184
1185 GString* gtk_imhtml_append_text_with_images (GtkIMHtml *imhtml, 1119 GString* gtk_imhtml_append_text_with_images (GtkIMHtml *imhtml,
1186 const gchar *text, 1120 const gchar *text,
1187 GtkIMHtmlOptions options, 1121 GtkIMHtmlOptions options,
1188 GSList *images) 1122 GSList *images)
1189 { 1123 {
1190 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); 1124 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer);
1191 GtkTextIter insert; 1125 GtkTextIter insert;
1126 GdkRectangle rect;
1192 gint pos = 0; 1127 gint pos = 0;
1193 GString *str = NULL; 1128 GString *str = NULL;
1194 GtkTextIter iter, siter; 1129 GtkTextIter iter;
1195 GtkTextMark *mark, *mark2; 1130 GtkTextMark *mark;
1196 GtkTextTag *texttag = NULL;
1197 gchar *ws; 1131 gchar *ws;
1198 gchar *tag; 1132 gchar *tag;
1199 gchar *url = NULL; 1133 gchar *url = NULL;
1200 gchar *bg = NULL; 1134 gchar *bg = NULL;
1201 gint len; 1135 gint len;
1213 title = 0, 1147 title = 0,
1214 pre = 0; 1148 pre = 0;
1215 1149
1216 GSList *fonts = NULL; 1150 GSList *fonts = NULL;
1217 GtkIMHtmlScalable *scalable = NULL; 1151 GtkIMHtmlScalable *scalable = NULL;
1218 GdkRectangle rect;
1219 int y, height; 1152 int y, height;
1220 1153
1221 1154
1222 g_return_val_if_fail (imhtml != NULL, NULL); 1155 g_return_val_if_fail (imhtml != NULL, NULL);
1223 g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL); 1156 g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL);
1238 1171
1239 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); 1172 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect);
1240 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height); 1173 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height);
1241 1174
1242 #if GTK_CHECK_VERSION(2,2,0) 1175 #if GTK_CHECK_VERSION(2,2,0)
1243 gtk_imhtml_clipboard_clear(NULL, imhtml); 1176 gtk_imhtml_primary_clipboard_clear(NULL, imhtml);
1244 #endif 1177 #endif
1245 gtk_text_buffer_move_mark (imhtml->text_buffer, 1178 gtk_text_buffer_move_mark (imhtml->text_buffer,
1246 gtk_text_buffer_get_mark (imhtml->text_buffer, "insert"), 1179 gtk_text_buffer_get_mark (imhtml->text_buffer, "insert"),
1247 &iter); 1180 &iter);
1248 1181
1253 1186
1254 while (pos < len) { 1187 while (pos < len) {
1255 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { 1188 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) {
1256 c++; 1189 c++;
1257 pos++; 1190 pos++;
1258 ws[wpos] = 0; 1191 ws[wpos] = '\0';
1259 switch (type) 1192 switch (type)
1260 { 1193 {
1261 case 1: /* B */ 1194 case 1: /* B */
1262 case 2: /* BOLD */ 1195 case 2: /* BOLD */
1263 case 54: /* STRONG */ 1196 case 54: /* STRONG */
1391 //NEW_BIT (NEW_TEXT_BIT); 1324 //NEW_BIT (NEW_TEXT_BIT);
1392 break; 1325 break;
1393 case 26: /* HR */ 1326 case 26: /* HR */
1394 case 42: /* HR (opt) */ 1327 case 42: /* HR (opt) */
1395 ws[wpos++] = '\n'; 1328 ws[wpos++] = '\n';
1329 if (url)
1330 gtk_imhtml_insert_link(imhtml, url, ws);
1331 else
1332 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos);
1396 scalable = gtk_imhtml_hr_new(); 1333 scalable = gtk_imhtml_hr_new();
1397 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); 1334 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect);
1398 scalable->add_to(scalable, imhtml, &iter); 1335 scalable->add_to(scalable, imhtml, &iter);
1399 scalable->scale(scalable, rect.width, rect.height); 1336 scalable->scale(scalable, rect.width, rect.height);
1400 imhtml->scalables = g_list_append(imhtml->scalables, scalable); 1337 imhtml->scalables = g_list_append(imhtml->scalables, scalable);
1427 g_free (font); 1364 g_free (font);
1428 } 1365 }
1429 break; 1366 break;
1430 case 28: /* /A */ 1367 case 28: /* /A */
1431 if (url) { 1368 if (url) {
1432 //NEW_BIT(NEW_TEXT_BIT); 1369 gtk_imhtml_insert_link(imhtml, url, ws);
1433 g_free(url); 1370 g_free(url);
1371 ws[0] = '\0'; wpos = 0;
1434 url = NULL; 1372 url = NULL;
1435 break; 1373 ins = gtk_text_buffer_get_insert(imhtml->text_buffer);
1374 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins);
1436 } 1375 }
1376 break;
1377
1437 case 29: /* P */ 1378 case 29: /* P */
1438 case 30: /* /P */ 1379 case 30: /* /P */
1439 case 31: /* H3 */ 1380 case 31: /* H3 */
1440 case 32: /* /H3 */ 1381 case 32: /* /H3 */
1441 case 33: /* HTML */ 1382 case 33: /* HTML */
1534 break; 1475 break;
1535 case 45: /* A (opt) */ 1476 case 45: /* A (opt) */
1536 { 1477 {
1537 gchar *href = gtk_imhtml_get_html_opt (tag, "HREF="); 1478 gchar *href = gtk_imhtml_get_html_opt (tag, "HREF=");
1538 if (href) { 1479 if (href) {
1539 // NEW_BIT (NEW_TEXT_BIT); 1480 if (url) {
1540 if (url) 1481 gtk_imhtml_insert_link(imhtml, url, ws);
1541 g_free (url); 1482 g_free(url);
1483 } else
1484 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos);
1485 ws[0] = '\0'; wpos = 0;
1542 url = href; 1486 url = href;
1543 } 1487 }
1544 } 1488 }
1545 break; 1489 break;
1546 case 46: /* IMG (opt) */ 1490 case 46: /* IMG (opt) */
1604 //NEW_BIT (NEW_TEXT_BIT); 1548 //NEW_BIT (NEW_TEXT_BIT);
1605 } 1549 }
1606 c++; 1550 c++;
1607 pos++; 1551 pos++;
1608 } else if (imhtml->show_smileys && (gtk_imhtml_is_smiley (imhtml, fonts, c, &smilelen) || gtk_imhtml_is_smiley(imhtml, NULL, c, &smilelen))) { 1552 } else if (imhtml->show_smileys && (gtk_imhtml_is_smiley (imhtml, fonts, c, &smilelen) || gtk_imhtml_is_smiley(imhtml, NULL, c, &smilelen))) {
1609 GtkTextChildAnchor *anchor;
1610 GtkWidget *icon = NULL;
1611 GtkTextIter copy;
1612 GdkPixbufAnimation *annipixbuf = NULL;
1613 GdkPixbuf *pixbuf = NULL;
1614 GtkIMHtmlFontDetail *fd; 1553 GtkIMHtmlFontDetail *fd;
1615 1554
1616 gchar *sml = NULL; 1555 gchar *sml = NULL;
1617 if (fonts) { 1556 if (fonts) {
1618 fd = fonts->data; 1557 fd = fonts->data;
2430 GdkPixbuf *pixbuf = NULL; 2369 GdkPixbuf *pixbuf = NULL;
2431 GdkPixbufAnimation *annipixbuf = NULL; 2370 GdkPixbufAnimation *annipixbuf = NULL;
2432 GtkWidget *icon = NULL; 2371 GtkWidget *icon = NULL;
2433 GtkTextChildAnchor *anchor; 2372 GtkTextChildAnchor *anchor;
2434 2373
2435 printf("%s %s\n", sml, smiley);
2436 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); 2374 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins);
2437 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, &iter); 2375 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, &iter);
2438 g_object_set_data(G_OBJECT(anchor), "text_tag", g_strdup(smiley)); 2376 g_object_set_data(G_OBJECT(anchor), "text_tag", g_strdup(smiley));
2439 2377
2440 annipixbuf = gtk_smiley_tree_image(imhtml, sml, smiley); 2378 annipixbuf = gtk_smiley_tree_image(imhtml, sml, smiley);
2506 break; 2444 break;
2507 if (sspan->end) 2445 if (sspan->end)
2508 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &tagend, sspan->end); 2446 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &tagend, sspan->end);
2509 if (sspan->end == NULL || gtk_text_iter_compare(&tagend, start) > 0) { 2447 if (sspan->end == NULL || gtk_text_iter_compare(&tagend, start) > 0) {
2510 str = g_string_append(str, sspan->start_tag); 2448 str = g_string_append(str, sspan->start_tag);
2511 closers = g_list_append(closers, sspan); 2449 closers = g_list_insert_sorted(closers, sspan, (GCompareFunc)span_compare_end);
2450 espan = (GtkIMHtmlFormatSpan*)closers->data;
2451 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end);
2512 } 2452 }
2513 sspan = (GtkIMHtmlFormatSpan*)starters->data; 2453 sspan = (GtkIMHtmlFormatSpan*)starters->data;
2514 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, sspan->start); 2454 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, sspan->start);
2515 starters = starters->next; 2455 starters = starters->next;
2516 } 2456 }
2542 while (gtk_text_iter_equal(&siter, &iter)) { 2482 while (gtk_text_iter_equal(&siter, &iter)) {
2543 /* This is where we shall insert the starting tag of 2483 /* This is where we shall insert the starting tag of
2544 * this format span */ 2484 * this format span */
2545 str = g_string_append(str, sspan->start_tag); 2485 str = g_string_append(str, sspan->start_tag);
2546 if (sspan->end) { 2486 if (sspan->end) {
2547 //espan = sspan;
2548 //gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end);
2549 closers = g_list_insert_sorted(closers, sspan, (GCompareFunc)span_compare_end); 2487 closers = g_list_insert_sorted(closers, sspan, (GCompareFunc)span_compare_end);
2550 espan = (GtkIMHtmlFormatSpan*)closers->data; 2488 espan = (GtkIMHtmlFormatSpan*)closers->data;
2551 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end); 2489 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end);
2552 2490
2553 } 2491 }
2618 { 2556 {
2619 char *text; 2557 char *text;
2620 GtkTextIter start, end; 2558 GtkTextIter start, end;
2621 2559
2622 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); 2560 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start);
2623 // gtk_text_iter_backward_char(&start);
2624 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); 2561 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end);
2625 text = gtk_imhtml_get_markup_range(imhtml, &start, &end); 2562 return gtk_imhtml_get_markup_range(imhtml, &start, &end);
2626
2627 // return gtk_imhtml_get_markup_range(imhtml, &start, &end);
2628 return text;
2629 } 2563 }
2630 2564
2631 char *gtk_imhtml_get_text(GtkIMHtml *imhtml) 2565 char *gtk_imhtml_get_text(GtkIMHtml *imhtml)
2632 { 2566 {
2633 GtkTextIter start_iter, end_iter; 2567 GtkTextIter start_iter, end_iter;