# HG changeset patch # User Sadrul Habib Chowdhury # Date 1176681295 0 # Node ID cc5917d70ddef15a3bb23b7d918c24a66bbc67b9 # Parent aa6160248112d8ddc0f12596b9c8244dc6be11d2# Parent 7a2ffa981c1a61a0d24df6c3015a08dfe21dd0ee merge of '7c800719ac0b585a5b02eaeb188880c191d1da89' and '8be1fbdce101b63280239db93e1dac106cea6681' diff -r aa6160248112 -r cc5917d70dde finch/gntconv.c --- a/finch/gntconv.c Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/gntconv.c Sun Apr 15 23:54:55 2007 +0000 @@ -159,23 +159,6 @@ gnt_entry_clear(GNT_ENTRY(ggconv->entry)); return TRUE; } - else if (key[0] == 27) - { - if (strcmp(key, GNT_KEY_DOWN) == 0) - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), 1); - else if (strcmp(key, GNT_KEY_UP) == 0) - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -1); - else if (strcmp(key, GNT_KEY_PGDOWN) == 0) - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), ggconv->tv->priv.height - 2); - else if (strcmp(key, GNT_KEY_PGUP) == 0) - gnt_text_view_scroll(GNT_TEXT_VIEW(ggconv->tv), -(ggconv->tv->priv.height - 2)); - else - return FALSE; - return TRUE; - } - else - { - } return FALSE; } @@ -325,6 +308,9 @@ gnt_widget_set_size(ggc->tv, purple_prefs_get_int(PREF_ROOT "/size/width"), purple_prefs_get_int(PREF_ROOT "/size/height")); + ggc->info = gnt_vbox_new(FALSE); + gnt_box_add_widget(GNT_BOX(ggc->window), ggc->info); + ggc->entry = gnt_entry_new(NULL); gnt_box_add_widget(GNT_BOX(ggc->window), ggc->entry); gnt_widget_set_name(ggc->entry, "conversation-window-entry"); @@ -332,6 +318,7 @@ gnt_entry_set_word_suggest(GNT_ENTRY(ggc->entry), TRUE); gnt_entry_set_always_suggest(GNT_ENTRY(ggc->entry), FALSE); + gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(ggc->tv), ggc->entry); g_signal_connect_after(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); @@ -758,3 +745,21 @@ g_free(title); } +void finch_conversation_set_info_widget(PurpleConversation *conv, GntWidget *widget) +{ + FinchConv *fc = conv->ui_data; + int height, width; + + gnt_box_remove_all(GNT_BOX(fc->info)); + + if (widget) { + gnt_box_add_widget(GNT_BOX(fc->info), widget); + gnt_box_readjust(GNT_BOX(fc->info)); + } + + gnt_widget_get_size(fc->window, &width, &height); + gnt_box_readjust(GNT_BOX(fc->window)); + gnt_screen_resize_widget(fc->window, width, height); + gnt_box_give_focus_to_child(GNT_BOX(fc->window), fc->entry); +} + diff -r aa6160248112 -r cc5917d70dde finch/gntconv.h --- a/finch/gntconv.h Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/gntconv.h Sun Apr 15 23:54:55 2007 +0000 @@ -48,6 +48,7 @@ GntWidget *entry; /* entry */ GntWidget *tv; /* text-view */ GntWidget *menu; /* future use */ + GntWidget *info; union { @@ -90,6 +91,15 @@ */ void finch_conversation_set_active(PurpleConversation *conv); +/** + * Sets the information widget for the conversation window. + * + * @param conv The conversation. + * @param widget The widget containing the information. If @c NULL, + * the current information widget is removed. + */ +void finch_conversation_set_info_widget(PurpleConversation *conv, GntWidget *widget); + /*@}*/ #endif diff -r aa6160248112 -r cc5917d70dde finch/gntdebug.c --- a/finch/gntdebug.c Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/gntdebug.c Sun Apr 15 23:54:55 2007 +0000 @@ -46,26 +46,6 @@ gboolean timestamps; } debug; -static gboolean -debug_window_kpress_cb(GntWidget *wid, const char *key, GntTextView *view) -{ - if (key[0] == 27) - { - if (strcmp(key, GNT_KEY_DOWN) == 0) - gnt_text_view_scroll(view, 1); - else if (strcmp(key, GNT_KEY_UP) == 0) - gnt_text_view_scroll(view, -1); - else if (strcmp(key, GNT_KEY_PGDOWN) == 0) - gnt_text_view_scroll(view, wid->priv.height - 2); - else if (strcmp(key, GNT_KEY_PGUP) == 0) - gnt_text_view_scroll(view, -(wid->priv.height - 2)); - else - return FALSE; - return TRUE; - } - return FALSE; -} - static void finch_debug_print(PurpleDebugLevel level, const char *category, const char *args) @@ -265,7 +245,7 @@ gnt_widget_set_name(debug.window, "debug-window"); g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL); - g_signal_connect(G_OBJECT(debug.window), "key_pressed", G_CALLBACK(debug_window_kpress_cb), debug.tview); + gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(debug.tview), debug.window); } gnt_widget_show(debug.window); diff -r aa6160248112 -r cc5917d70dde finch/libgnt/Makefile.am --- a/finch/libgnt/Makefile.am Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/Makefile.am Sun Apr 15 23:54:55 2007 +0000 @@ -79,9 +79,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 aa6160248112 -r cc5917d70dde finch/libgnt/configure.ac --- a/finch/libgnt/configure.ac Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/configure.ac Sun Apr 15 23:54:55 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 aa6160248112 -r cc5917d70dde finch/libgnt/gnttextview.c --- a/finch/libgnt/gnttextview.c Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/gnttextview.c Sun Apr 15 23:54:55 2007 +0000 @@ -739,3 +739,25 @@ return count; } +static gboolean +scroll_tv(GntWidget *wid, const char *key, GntTextView *tv) +{ + if (strcmp(key, GNT_KEY_PGUP) == 0) { + gnt_text_view_scroll(tv, -(GNT_WIDGET(tv)->priv.height - 2)); + } else if (strcmp(key, GNT_KEY_PGDOWN) == 0) { + gnt_text_view_scroll(tv, GNT_WIDGET(tv)->priv.height - 2); + } else if (strcmp(key, GNT_KEY_DOWN) == 0) { + gnt_text_view_scroll(tv, 1); + } else if (strcmp(key, GNT_KEY_UP) == 0) { + gnt_text_view_scroll(tv, -1); + } else { + return FALSE; + } + return TRUE; +} + +void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget) +{ + g_signal_connect(G_OBJECT(widget), "key_pressed", G_CALLBACK(scroll_tv), view); +} + diff -r aa6160248112 -r cc5917d70dde finch/libgnt/gnttextview.h --- a/finch/libgnt/gnttextview.h Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/gnttextview.h Sun Apr 15 23:54:55 2007 +0000 @@ -81,6 +81,8 @@ /* If text is NULL, then the tag is removed. */ int gnt_text_view_tag_change(GntTextView *view, const char *name, const char *text, gboolean all); +void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget); + G_END_DECLS #endif /* GNT_TEXT_VIEW_H */ diff -r aa6160248112 -r cc5917d70dde finch/libgnt/gnttree.c --- a/finch/libgnt/gnttree.c Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/gnttree.c Sun Apr 15 23:54:55 2007 +0000 @@ -1525,7 +1525,7 @@ void gnt_tree_adjust_columns(GntTree *tree) { GntTreeRow *row = tree->root; - int *widths, i, twidth, height; + int *widths, i, twidth; widths = g_new0(int, tree->ncol); while (row) { @@ -1552,8 +1552,7 @@ } g_free(widths); - gnt_widget_get_size(GNT_WIDGET(tree), NULL, &height); - gnt_widget_set_size(GNT_WIDGET(tree), twidth, height); + gnt_widget_set_size(GNT_WIDGET(tree), twidth, -1); } void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd) diff -r aa6160248112 -r cc5917d70dde finch/libgnt/gntutils.c --- a/finch/libgnt/gntutils.c Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/gntutils.c Sun Apr 15 23:54:55 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 aa6160248112 -r cc5917d70dde finch/libgnt/gntutils.h --- a/finch/libgnt/gntutils.h Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/gntutils.h Sun Apr 15 23:54:55 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 aa6160248112 -r cc5917d70dde finch/libgnt/gntwm.c --- a/finch/libgnt/gntwm.c Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/gntwm.c Sun Apr 15 23:54:55 2007 +0000 @@ -15,10 +15,12 @@ #include "gntmarshal.h" #include "gnt.h" #include "gntbox.h" +#include "gntlabel.h" #include "gntmenu.h" #include "gnttextview.h" #include "gnttree.h" #include "gntutils.h" +#include "gntwindow.h" #define IDLE_CHECK_INTERVAL 5 /* 5 seconds */ @@ -417,6 +419,35 @@ return TRUE; } +static gboolean +help_for_widget(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *widget, *tree, *win, *active; + char *title; + + if (!wm->ordered) + return TRUE; + + widget = wm->ordered->data; + if (!GNT_IS_BOX(widget)) + return TRUE; + active = GNT_BOX(widget)->active; + + tree = gnt_widget_bindings_view(active); + win = gnt_window_new(); + title = g_strdup_printf("Bindings for %s", g_type_name(G_OBJECT_TYPE(active))); + gnt_box_set_title(GNT_BOX(win), title); + if (tree) + gnt_box_add_widget(GNT_BOX(win), tree); + else + gnt_box_add_widget(GNT_BOX(win), gnt_label_new("This widget has no customizable bindings.")); + + gnt_widget_show(win); + + return TRUE; +} + static void destroy__list(GntWidget *widget, GntWM *wm) { @@ -475,11 +506,11 @@ GntWidget *sel = gnt_tree_get_selection_data(GNT_TREE(widget)); switch (text[0]) { case '-': - case '<': + case ',': shift_window(wm, sel, -1); break; - case '+': - case '>': + case '=': + case '.': shift_window(wm, sel, 1); break; default: @@ -1006,6 +1037,8 @@ "\033" GNT_KEY_CTRL_J, NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "window-scroll-up", window_scroll_up, "\033" GNT_KEY_CTRL_K, NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-widget", help_for_widget, + "\033" "/", NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); @@ -1230,8 +1263,12 @@ idle_update = TRUE; - if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) + wm->event_stack = TRUE; + + if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) { + wm->event_stack = FALSE; return TRUE; + } /* Do some manual checking */ if (wm->ordered && wm->mode != GNT_KP_MODE_NORMAL) { @@ -1262,6 +1299,7 @@ if (ox != x || oy != y) { gnt_screen_move_widget(widget, x, y); window_reverse(widget, TRUE, wm); + wm->event_stack = FALSE; return TRUE; } } else if (wm->mode == GNT_KP_MODE_RESIZE) { @@ -1279,6 +1317,7 @@ if (oh != h || ow != w) { gnt_screen_resize_widget(widget, w, h); window_reverse(widget, TRUE, wm); + wm->event_stack = FALSE; return TRUE; } } @@ -1286,11 +1325,10 @@ window_reverse(widget, FALSE, wm); wm->mode = GNT_KP_MODE_NORMAL; } + wm->event_stack = FALSE; return TRUE; } - wm->event_stack = TRUE; - /* Escape to close the window-list or action-list window */ if (strcmp(keys, "\033") == 0) { if (wm->_list.window) { diff -r aa6160248112 -r cc5917d70dde finch/libgnt/test/Makefile --- a/finch/libgnt/test/Makefile Sun Apr 15 23:53:36 2007 +0000 +++ b/finch/libgnt/test/Makefile Sun Apr 15 23:54:55 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 aa6160248112 -r cc5917d70dde finch/libgnt/test/parse.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/finch/libgnt/test/parse.c Sun Apr 15 23:54:55 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; +} +