comparison finch/libgnt/gntutils.c @ 19334:fda2d2d99850

Add support to parse and add XHTML in a textview. This we can use for logs, in the conversation window etc. places.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Thu, 23 Aug 2007 05:55:57 +0000
parents 7066896f6628
children e28db9ae02b3
comparison
equal deleted inserted replaced
19333:5e39506a0e3b 19334:fda2d2d99850
374 va_end(list); 374 va_end(list);
375 g_free(data); 375 g_free(data);
376 #endif 376 #endif
377 } 377 }
378 378
379 #ifndef NO_LIBXML
380 static void
381 util_parse_html_to_tv(xmlNode *node, GntTextView *tv, GntTextFormatFlags flag)
382 {
383 const char *name;
384 char *content;
385 xmlNode *ch;
386 gboolean processed = FALSE;
387 char *url = NULL;
388
389 if (node == NULL || node->name == NULL || node->type != XML_ELEMENT_NODE)
390 return;
391
392 name = (char*)node->name;
393 if (g_ascii_strcasecmp(name, "b") == 0 ||
394 g_ascii_strcasecmp(name, "strong") == 0 ||
395 g_ascii_strcasecmp(name, "i") == 0 ||
396 g_ascii_strcasecmp(name, "blockquote") == 0) {
397 flag |= GNT_TEXT_FLAG_BOLD;
398 } else if (g_ascii_strcasecmp(name, "u") == 0) {
399 flag |= GNT_TEXT_FLAG_UNDERLINE;
400 } else if (g_ascii_strcasecmp(name, "br") == 0) {
401 gnt_text_view_append_text_with_flags(tv, "\n", flag);
402 } else if (g_ascii_strcasecmp(name, "a") == 0) {
403 flag |= GNT_TEXT_FLAG_UNDERLINE;
404 url = (char *)xmlGetProp(node, (xmlChar*)"href");
405 } else {
406 /* XXX: Process other possible tags */
407 }
408
409 for (ch = node->children; ch; ch = ch->next) {
410 if (ch->type == XML_ELEMENT_NODE) {
411 processed = TRUE;
412 }
413 util_parse_html_to_tv(ch, tv, flag);
414 }
415
416 if (!processed) {
417 content = (char*)xmlNodeGetContent(node);
418 gnt_text_view_append_text_with_flags(tv, content, flag);
419 xmlFree(content);
420 }
421
422 if (url) {
423 char *href = g_strdup_printf(" (%s)", url);
424 gnt_text_view_append_text_with_flags(tv, href, flag);
425 g_free(href);
426 xmlFree(url);
427 }
428 }
429 #endif
430
431 gboolean gnt_util_parse_xhtml_to_textview(const char *string, GntTextView *tv)
432 {
433 #ifdef NO_LIBXML
434 return FALSE;
435 #else
436 xmlParserCtxtPtr ctxt;
437 xmlDocPtr doc;
438 xmlNodePtr node;
439 GntTextFormatFlags flag = GNT_TEXT_FLAG_NORMAL;
440 gboolean ret = FALSE;
441
442 ctxt = xmlNewParserCtxt();
443 doc = xmlCtxtReadDoc(ctxt, (xmlChar*)string, NULL, NULL, XML_PARSE_NOBLANKS | XML_PARSE_RECOVER);
444 if (doc) {
445 node = xmlDocGetRootElement(doc);
446 util_parse_html_to_tv(node, tv, flag);
447 xmlFreeDoc(doc);
448 ret = TRUE;
449 }
450 xmlCleanupParser();
451 return ret;
452 #endif
453 }
454
379 /* Setup trigger widget */ 455 /* Setup trigger widget */
380 typedef struct { 456 typedef struct {
381 char *text; 457 char *text;
382 GntWidget *button; 458 GntWidget *button;
383 } TriggerButton; 459 } TriggerButton;
406 tb->text = g_strdup(text); 482 tb->text = g_strdup(text);
407 tb->button = button; 483 tb->button = button;
408 g_signal_connect(G_OBJECT(wid), "key_pressed", G_CALLBACK(key_pressed), tb); 484 g_signal_connect(G_OBJECT(wid), "key_pressed", G_CALLBACK(key_pressed), tb);
409 g_signal_connect_swapped(G_OBJECT(button), "destroy", G_CALLBACK(free_trigger_button), tb); 485 g_signal_connect_swapped(G_OBJECT(button), "destroy", G_CALLBACK(free_trigger_button), tb);
410 } 486 }
411