# HG changeset patch # User Sadrul Habib Chowdhury # Date 1176616167 0 # Node ID 5f204f55af090e7f6b964a601e2492cec2bd1efe # Parent ab3f93232a2d9f379d3ff2aa3c99890fe0246236 Add a utility function to create widgets from an XML description. diff -r ab3f93232a2d -r 5f204f55af09 finch/libgnt/Makefile.am --- a/finch/libgnt/Makefile.am Sun Apr 15 05:42:14 2007 +0000 +++ b/finch/libgnt/Makefile.am Sun Apr 15 05:49:27 2007 +0000 @@ -77,9 +77,11 @@ libgnt_la_LDFLAGS = -export-dynamic libgnt_la_LIBADD = \ $(GLIB_LIBS) \ - $(GNT_LIBS) + $(GNT_LIBS) \ + $(LIBXML_LIBS) AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(GNT_CFLAGS) \ - $(DEBUG_CFLAGS) + $(DEBUG_CFLAGS) \ + $(LIBXML_CFLAGS) diff -r ab3f93232a2d -r 5f204f55af09 finch/libgnt/configure.ac --- a/finch/libgnt/configure.ac Sun Apr 15 05:42:14 2007 +0000 +++ b/finch/libgnt/configure.ac Sun Apr 15 05:49:27 2007 +0000 @@ -203,6 +203,9 @@ GNT_CFLAGS= GNT_LIBS= +AC_ARG_WITH(ncurses-headers, [AC_HELP_STRING([--with-ncurses-headers=DIR], + [compile finch against the ncurses includes in DIR])], + [ac_ncurses_includes="$withval"], [ac_ncurses_includes=""]) AC_CHECK_LIB(ncursesw, initscr, [GNT_LIBS="-lncursesw"], [enable_gnt=no]) AC_CHECK_LIB(panelw, update_panels, [GNT_LIBS="$GNT_LIBS -lpanelw"], [enable_gnt=no]) @@ -214,8 +217,9 @@ else dnl # Some distros put the headers in ncursesw/, some don't found_ncurses_h=no - for f in /usr/include/ncursesw/ncurses.h /usr/include/ncurses.h + for location in $ac_ncurses_includes /usr/include/ncursesw /usr/include do + f="$location/ncurses.h" AC_CHECK_HEADER($f,[ AC_MSG_CHECKING([if $f supports wide characters]) AC_TRY_COMPILE([ @@ -226,7 +230,7 @@ # error get_wch not found! #endif ], [ - dir=`dirname $f` + dir=$location if test x"$dir" != x"." ; then GNT_CFLAGS="-I$dir/" else @@ -241,13 +245,29 @@ ]) ]) done + if test x"$found_ncurses_h" != "xyes"; then + enable_gnt="no" + fi fi AC_SUBST(GNT_CFLAGS) AC_SUBST(GNT_LIBS) if test "x$enable_gnt" = "xno"; then AC_MSG_ERROR([ -*** You need ncursesw or ncurses.]) +*** You need ncursesw or ncurses and its header files.]) +fi + +dnl Check for libxml +have_libxml=yes +PKG_CHECK_MODULES(LIBXML, [libxml-2.0], , [ + AC_MSG_RESULT(no) + have_libxml=no + ]) +AC_SUBST(LIBXML_CFLAGS) +AC_SUBST(LIBXML_LIBS) + +if test "x$have_libxml" = "xno"; then + AC_DEFINE(NO_LIBXML, 1, [Do not have libxml2.]) fi AC_OUTPUT([Makefile diff -r ab3f93232a2d -r 5f204f55af09 finch/libgnt/gntutils.c --- a/finch/libgnt/gntutils.c Sun Apr 15 05:42:14 2007 +0000 +++ b/finch/libgnt/gntutils.c Sun Apr 15 05:49:27 2007 +0000 @@ -1,9 +1,25 @@ -#include "gntutils.h" +#include "gntbutton.h" +#include "gntcheckbox.h" +#include "gntcombobox.h" +#include "gntentry.h" +#include "gntlabel.h" +#include "gntline.h" +#include "gnttextview.h" #include "gnttree.h" +#include "gntutils.h" +#include "gntwindow.h" +#include "config.h" + +#include #include #include +#ifndef NO_LIBXML +#include +#include +#endif + #include "config.h" void gnt_util_get_text_bound(const char *text, int *width, int *height) @@ -184,9 +200,156 @@ gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate); g_hash_table_foreach(klass->actions, add_action, &bv); g_hash_table_foreach(klass->bindings, add_binding, &bv); - gnt_tree_adjust_columns(bv.tree); + if (GNT_TREE(tree)->list == NULL) { + gnt_widget_destroy(tree); + tree = NULL; + } else + gnt_tree_adjust_columns(bv.tree); g_hash_table_destroy(hash); return tree; } +#ifndef NO_LIBXML +static GntWidget * +gnt_widget_from_xmlnode(xmlNode *node, GntWidget **data[]) +{ + GntWidget *widget = NULL; + char *name; + char *id, *prop, *content; + int val; + + if (node == NULL || node->name == NULL || node->type != XML_ELEMENT_NODE) + return NULL; + + name = (char*)node->name; + content = (char*)xmlNodeGetContent(node); + if (strcmp(name + 1, "window") == 0 || strcmp(name + 1, "box") == 0) { + xmlNode *ch; + char *title; + gboolean vert = (*name == 'v'); + + if (name[1] == 'w') + widget = gnt_window_box_new(FALSE, vert); + else + widget = gnt_box_new(FALSE, vert); + + title = (char*)xmlGetProp(node, (xmlChar*)"title"); + if (title) { + gnt_box_set_title(GNT_BOX(widget), title); + xmlFree(title); + } + + prop = (char*)xmlGetProp(node, (xmlChar*)"fill"); + if (prop) { + if (sscanf(prop, "%d", &val) == 1) + gnt_box_set_fill(GNT_BOX(widget), !!val); + xmlFree(prop); + } + + prop = (char*)xmlGetProp(node, (xmlChar*)"align"); + if (prop) { + if (sscanf(prop, "%d", &val) == 1) + gnt_box_set_alignment(GNT_BOX(widget), val); + xmlFree(prop); + } + + prop = (char*)xmlGetProp(node, (xmlChar*)"pad"); + if (prop) { + if (sscanf(prop, "%d", &val) == 1) + gnt_box_set_pad(GNT_BOX(widget), val); + xmlFree(prop); + } + + for (ch = node->children; ch; ch=ch->next) + gnt_box_add_widget(GNT_BOX(widget), gnt_widget_from_xmlnode(ch, data)); + } else if (strcmp(name, "button") == 0) { + widget = gnt_button_new(content); + } else if (strcmp(name, "label") == 0) { + widget = gnt_label_new(content); + } else if (strcmp(name, "entry") == 0) { + widget = gnt_entry_new(content); + } else if (strcmp(name, "combobox") == 0) { + widget = gnt_combo_box_new(); + } else if (strcmp(name, "checkbox") == 0) { + widget = gnt_check_box_new(content); + } else if (strcmp(name, "tree") == 0) { + widget = gnt_tree_new(); + } else if (strcmp(name, "textview") == 0) { + widget = gnt_text_view_new(); + } else if (strcmp(name + 1, "line") == 0) { + widget = gnt_line_new(*name == 'v'); + } + + xmlFree(content); + + if (widget == NULL) { + g_printerr("Invalid widget name %s\n", name); + return NULL; + } + + id = (char*)xmlGetProp(node, (xmlChar*)"id"); + if (id) { + int i; + sscanf(id, "%d", &i); + *data[i] = widget; + xmlFree(id); + } + + prop = (char*)xmlGetProp(node, (xmlChar*)"border"); + if (prop) { + int val; + if (sscanf(prop, "%d", &val) == 1) { + if (val) + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); + else + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER); + } + xmlFree(prop); + } + + prop = (char*)xmlGetProp(node, (xmlChar*)"shadow"); + if (prop) { + int val; + if (sscanf(prop, "%d", &val) == 1) { + if (val) + GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); + else + GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER); + } + xmlFree(prop); + } + + return widget; +} +#endif + +void gnt_util_parse_widgets(const char *string, int num, ...) +{ +#ifndef NO_LIBXML + xmlParserCtxtPtr ctxt; + xmlDocPtr doc; + xmlNodePtr node; + va_list list; + GntWidget ***data; + int id; + + ctxt = xmlNewParserCtxt(); + doc = xmlCtxtReadDoc(ctxt, (xmlChar*)string, NULL, NULL, XML_PARSE_NOBLANKS); + + data = g_new0(GntWidget **, num); + + va_start(list, num); + for (id = 0; id < num; id++) + data[id] = va_arg(list, gpointer); + + node = xmlDocGetRootElement(doc); + gnt_widget_from_xmlnode(node, data); + + xmlFreeDoc(doc); + xmlCleanupParser(); + va_end(list); + g_free(data); +#endif +} + diff -r ab3f93232a2d -r 5f204f55af09 finch/libgnt/gntutils.h --- a/finch/libgnt/gntutils.h Sun Apr 15 05:42:14 2007 +0000 +++ b/finch/libgnt/gntutils.h Sun Apr 15 05:49:27 2007 +0000 @@ -39,3 +39,8 @@ */ GntWidget *gnt_widget_bindings_view(GntWidget *widget); +/** + * Parse widgets from 'string'. + */ +void gnt_util_parse_widgets(const char *string, int num, ...); + diff -r ab3f93232a2d -r 5f204f55af09 finch/libgnt/test/Makefile --- a/finch/libgnt/test/Makefile Sun Apr 15 05:42:14 2007 +0000 +++ b/finch/libgnt/test/Makefile Sun Apr 15 05:49:27 2007 +0000 @@ -2,7 +2,7 @@ CFLAGS=`pkg-config --cflags gobject-2.0 gmodule-2.0` -g -I../ -DSTANDALONE LDFLAGS=`pkg-config --libs gobject-2.0 gmodule-2.0 gnt` -pg -EXAMPLES=combo focus tv multiwin keys menu +EXAMPLES=combo focus tv multiwin keys menu parse all: make examples diff -r ab3f93232a2d -r 5f204f55af09 finch/libgnt/test/parse.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/finch/libgnt/test/parse.c Sun Apr 15 05:49:27 2007 +0000 @@ -0,0 +1,18 @@ +#include "gntutils.h" + +int main() +{ + GntWidget *win, *button; + + gnt_init(); + + gnt_util_parse_widgets("", 2, &win, &button); + g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win); + gnt_widget_show(win); + + gnt_main(); + + gnt_quit(); + return 0; +} +