# HG changeset patch # User Eric Polino # Date 1181683297 0 # Node ID ac904659104fa75f50dafe7ee0f5b1033568a57e # Parent 9018b785ef735b883cb24d03e8fab5fb90384ac4# Parent d7cd0afd3c36223e9431f4c812db63b0215b3db1 propagate from branch 'im.pidgin.pidgin.2.1.0' (head 121873f517c4c5e2d65c3a1cdd152694834d7db0) to branch 'im.pidgin.soc.2007.finchfeat' (head c079bc8ba4b62373e63c0923c45007d2eac37aa2) diff -r 9018b785ef73 -r ac904659104f COPYRIGHT --- a/COPYRIGHT Mon Jun 11 17:36:40 2007 +0000 +++ b/COPYRIGHT Tue Jun 12 21:21:37 2007 +0000 @@ -274,6 +274,7 @@ Joao Luís Marques Pinto Aleksander Piotrowski Julien Pivotto +Eric Polino Ari Pollak Robey Pointer Stephen Pope diff -r 9018b785ef73 -r ac904659104f finch/gntdebug.c --- a/finch/gntdebug.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/gntdebug.c Tue Jun 12 21:21:37 2007 +0000 @@ -298,7 +298,7 @@ REGISTER_G_LOG_HANDLER("GThread"); g_set_print_handler(print_stderr); /* Redirect the debug messages to stderr */ - g_set_printerr_handler(suppress_error_messages); +// g_set_printerr_handler(suppress_error_messages); purple_prefs_add_none(PREF_ROOT); purple_prefs_add_string(PREF_ROOT "/filter", ""); diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gnt.h --- a/finch/libgnt/gnt.h Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gnt.h Tue Jun 12 21:21:37 2007 +0000 @@ -138,4 +138,3 @@ * @param string */ void gnt_set_clipboard_string(gchar *string); - diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntbindable.c --- a/finch/libgnt/gntbindable.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntbindable.c Tue Jun 12 21:21:37 2007 +0000 @@ -20,13 +20,201 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include + #include "gntbindable.h" #include "gntstyle.h" #include "gnt.h" #include "gntutils.h" +#include "gnttextview.h" +#include "gnttree.h" +#include "gntbox.h" +#include "gntbutton.h" +#include "gntwindow.h" +#include "gntlabel.h" static GObjectClass *parent_class = NULL; +static struct +{ + char * okeys; /* Old keystrokes */ + char * keys; /* New Keystrokes being bound to the action */ + GntBindableClass * klass; /* Class of the object that's getting keys rebound */ + char * name; /* The name of the action */ + GList * params; /* The list of paramaters */ + +} rebind_info = {NULL,NULL,NULL,NULL,NULL}; + +static void +gnt_bindable_free_rebind_info() +{ + g_free(rebind_info.name); + g_free(rebind_info.keys); + g_free(rebind_info.okeys); +} + +static gboolean +gnt_bindable_rebinding_cancel(GntBindable *bindable, gpointer data) +{ + gnt_bindable_free_rebind_info(); + gnt_widget_destroy(GNT_WIDGET(data)); + return TRUE; +} + +static gboolean +gnt_bindable_rebinding_rebind(GntBindable *bindable, gpointer data) +{ + + if(rebind_info.keys) { + gnt_bindable_register_binding(rebind_info.klass, + NULL, + rebind_info.okeys, + rebind_info.params); + gnt_bindable_register_binding(rebind_info.klass, + rebind_info.name, + rebind_info.keys, + rebind_info.params); + } + gnt_bindable_free_rebind_info(); + + gnt_widget_destroy(GNT_WIDGET(data)); + + return TRUE; +} + +static gboolean +gnt_bindable_rebinding_grab_key(GntBindable *bindable, const char *text, gpointer *data) +{ + + GntTextView *textview= GNT_TEXT_VIEW(data); + char *new_text; + const char *tmp; + + if(text && *text){ + + if(!strcmp(text, GNT_KEY_CTRL_I) || !strcmp(text, GNT_KEY_ENTER)){ + return FALSE; + } + + tmp = gnt_key_lookup(text); + new_text = g_strdup_printf("KEY: \"%s\"",tmp); + gnt_text_view_clear(textview); + gnt_text_view_append_text_with_flags(textview,new_text,GNT_TEXT_FLAG_NORMAL); + g_free(new_text); + + g_free(rebind_info.keys); + rebind_info.keys = g_strdup(text); + + + return TRUE; + } + return FALSE; +} +static void +gnt_bindable_rebinding_activate(GntBindable *data, gpointer bindable) +{ + + GntTree * tree = GNT_TREE(data); + + GntWidget *vbox = gnt_box_new(FALSE,TRUE); + + GntWidget *label; + const char * widget_name = g_type_name(G_OBJECT_TYPE(bindable)); + char * keys; + + GntWidget *key_textview; + + GntWidget *bind_button, *cancel_button; + GntWidget *button_box; + + GntWidget *win = gnt_window_new(); + GList * current_row_data,*itr; + char * tmp; + + rebind_info.klass = GNT_BINDABLE_GET_CLASS(bindable); + + current_row_data = gnt_tree_get_selection_text_list(tree); + rebind_info.name = g_strdup(g_list_nth_data(current_row_data,1)); + + keys = gnt_tree_get_selection_data(tree); + rebind_info.okeys = g_strdup(gnt_key_translate(keys)); + + rebind_info.params = NULL; + + itr = current_row_data; + while(itr){ + g_free(itr->data); + itr = itr->next; + } + g_list_free(current_row_data); + + gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID); + + gnt_box_set_title(GNT_BOX(win),"Key Capture"); + + tmp = g_strdup_printf("Type the new bindings for %s in a %s.",rebind_info.name,widget_name); + label = gnt_label_new(tmp); + g_free(tmp); + gnt_box_add_widget(GNT_BOX(vbox),label); + + tmp = g_strdup_printf("KEY: \"%s\"",keys); + key_textview = gnt_text_view_new(); + gnt_widget_set_size(key_textview,key_textview->priv.x,2); + gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(key_textview),tmp,GNT_TEXT_FLAG_NORMAL); + g_free(tmp); + gnt_widget_set_name(key_textview,"keystroke"); + gnt_box_add_widget(GNT_BOX(vbox),key_textview); + + g_signal_connect(G_OBJECT(win), "key_pressed", G_CALLBACK(gnt_bindable_rebinding_grab_key),key_textview); + + button_box = gnt_box_new(FALSE,FALSE); + + bind_button = gnt_button_new("BIND"); + gnt_widget_set_name(bind_button,"bind"); + gnt_box_add_widget(GNT_BOX(button_box), bind_button); + + cancel_button = gnt_button_new("Cancel"); + gnt_widget_set_name(cancel_button,"cancel"); + gnt_box_add_widget(GNT_BOX(button_box),cancel_button); + + g_signal_connect(G_OBJECT(bind_button), "activate", G_CALLBACK(gnt_bindable_rebinding_rebind),win); + g_signal_connect(G_OBJECT(cancel_button), "activate", G_CALLBACK(gnt_bindable_rebinding_cancel),win); + + + gnt_box_add_widget(GNT_BOX(vbox),button_box); + + gnt_box_add_widget(GNT_BOX(win),vbox); + gnt_widget_show(win); + +} + +typedef struct { + GHashTable *hash; + GntTree *tree; +} BindingView; + +static void +add_binding(gpointer key, gpointer value, gpointer data) +{ + BindingView *bv = data; + GntBindableActionParam *act = value; + const char *name = g_hash_table_lookup(bv->hash, act->action); + if (name && *name) { + const char *k = gnt_key_lookup(key); + if (!k) + k = key; + gnt_tree_add_row_after(bv->tree, (gpointer)k, + gnt_tree_create_row(bv->tree, k, name), NULL, NULL); + } +} + +static void +add_action(gpointer key, gpointer value, gpointer data) +{ + BindingView *bv = data; + g_hash_table_insert(bv->hash, value, key); +} + static void gnt_bindable_class_init(GntBindableClass *klass) { @@ -251,4 +439,56 @@ g_free(param); } +GntBindable * gnt_bindable_bindings_view(GntBindable *bind) +{ + GntBindable *tree = GNT_BINDABLE(gnt_tree_new_with_columns(2)); + GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bind)); + GHashTable *hash = g_hash_table_new(g_direct_hash, g_direct_equal); + BindingView bv = {hash, GNT_TREE(tree)}; + 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); + if (GNT_TREE(tree)->list == NULL) { + gnt_widget_destroy(GNT_WIDGET(tree)); + tree = NULL; + } else + gnt_tree_adjust_columns(bv.tree); + g_hash_table_destroy(hash); + + return tree; +} + +static void +reset_binding_window(GntBindableClass *window, gpointer k) +{ + GntBindableClass *klass = GNT_BINDABLE_CLASS(k); + klass->help_window = NULL; +} + +gboolean +gnt_bindable_build_help_window(GntBindable *bindable) +{ + + GntWidget *tree; + GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable); + char *title; + + tree = GNT_WIDGET(gnt_bindable_bindings_view(bindable)); + + klass->help_window = GNT_BINDABLE(gnt_window_new()); + title = g_strdup_printf("Bindings for %s", g_type_name(G_OBJECT_TYPE(bindable))); + gnt_box_set_title(GNT_BOX(klass->help_window), title); + if (tree) { + g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(gnt_bindable_rebinding_activate), bindable); + gnt_box_add_widget(GNT_BOX(klass->help_window), tree); + } else + gnt_box_add_widget(GNT_BOX(klass->help_window), gnt_label_new("This widget has no customizable bindings.")); + + g_signal_connect(G_OBJECT(klass->help_window), "destroy", G_CALLBACK(reset_binding_window), klass); + gnt_widget_show(GNT_WIDGET(klass->help_window)); + g_free(title); + + return TRUE; +} + diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntbindable.h --- a/finch/libgnt/gntbindable.h Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntbindable.h Tue Jun 12 21:21:37 2007 +0000 @@ -53,7 +53,8 @@ GHashTable *actions; /* name -> Action */ GHashTable *bindings; /* key -> ActionParam */ - void (*gnt_reserved1)(void); + GntBindable * help_window; + void (*gnt_reserved2)(void); void (*gnt_reserved3)(void); void (*gnt_reserved4)(void); @@ -146,6 +147,31 @@ */ gboolean gnt_bindable_perform_action_named(GntBindable *bindable, const char *name, ...); +/** +* Returns a GntTree populated with "key" -> "binding" for the widget. +*/ +/** +* +* @param widget +* +* @return +*/ +GntBindable * gnt_bindable_bindings_view(GntBindable *bind); + +/** + * + * Builds a window that list the key bindings for a GntBindable object. From this window a user can select a listing to rebind a new key for the given action. + * + */ +/** + * + * @param bindable + * + * @return + */ + +gboolean gnt_bindable_build_help_window(GntBindable *bindable); + G_END_DECLS #endif /* GNT_BINDABLE_H */ diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntbox.c --- a/finch/libgnt/gntbox.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntbox.c Tue Jun 12 21:21:37 2007 +0000 @@ -315,10 +315,6 @@ { find_next_focus(box); } - else if (strcmp(text, GNT_KEY_BACK_TAB) == 0) - { - find_prev_focus(box); - } } else if (text[0] == '\t') { diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntkeys.c --- a/finch/libgnt/gntkeys.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntkeys.c Tue Jun 12 21:21:37 2007 +0000 @@ -72,7 +72,6 @@ INSERT_KEY("pagedown", GNT_KEY_PGDOWN); INSERT_KEY("insert", GNT_KEY_INS); INSERT_KEY("delete", GNT_KEY_DEL); - INSERT_KEY("back_tab", GNT_KEY_BACK_TAB); INSERT_KEY("left", GNT_KEY_LEFT); INSERT_KEY("right", GNT_KEY_RIGHT); @@ -206,8 +205,8 @@ node->flags |= IS_END; return; } - while (*path && node->next[(unsigned char)*path]) { - node = node->next[(unsigned char)*path]; + while (*path && node->next[*path]) { + node = node->next[*path]; node->ref++; path++; } @@ -215,7 +214,7 @@ return; n = g_new0(struct _node, 1); n->ref = 1; - node->next[(unsigned char)*path++] = n; + node->next[*path++] = n; add_path(n, path); } @@ -230,13 +229,13 @@ if (!*path) return; - next = node->next[(unsigned char)*path]; + next = node->next[*path]; if (!next) return; del_path(next, path + 1); next->ref--; if (next->ref == 0) { - node->next[(unsigned char)*path] = NULL; + node->next[*path] = NULL; g_free(next); } } @@ -252,12 +251,12 @@ struct _node *n = &root; root.flags &= ~IS_END; - while (*path && n->next[(unsigned char)*path] && !(n->flags & IS_END)) { + while (*path && n->next[*path] && !(n->flags & IS_END)) { if (!g_ascii_isspace(*path) && !g_ascii_iscntrl(*path) && !g_ascii_isgraph(*path)) return 0; - n = n->next[(unsigned char)*path++]; + n = n->next[*path++]; depth++; } diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntkeys.h diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntmain.c --- a/finch/libgnt/gntmain.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntmain.c Tue Jun 12 21:21:37 2007 +0000 @@ -246,6 +246,12 @@ if (HOLDING_ESCAPE) keys[0] = '\033'; k = keys; + if(*k < 0){ /* Alt not sending ESC* */ + *(k + 1) = 128 - *k; + *k = 27; + *(k + 2) = 0; + rd++; + } while (rd) { char back; int p; diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntmenu.c --- a/finch/libgnt/gntmenu.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntmenu.c Tue Jun 12 21:21:37 2007 +0000 @@ -242,10 +242,7 @@ static void gnt_menu_hide(GntWidget *widget) { - GntMenu *sub, *menu = GNT_MENU(widget); - - while ((sub = menu->submenu)) - gnt_widget_hide(GNT_WIDGET(sub)); + GntMenu *menu = GNT_MENU(widget); if (menu->parentmenu) menu->parentmenu->submenu = NULL; } diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntstyle.c --- a/finch/libgnt/gntstyle.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntstyle.c Tue Jun 12 21:21:37 2007 +0000 @@ -22,6 +22,7 @@ #include "gntstyle.h" #include "gntcolors.h" + #include "gntws.h" #include @@ -294,7 +295,6 @@ str_styles[styles[i].en] = g_key_file_get_string(kfile, "general", styles[i].style, NULL); } - for (i = 0; i < nkeys; i++) g_hash_table_replace(unknowns, g_strdup(keys[i]), g_strdup(g_key_file_get_string(kfile, "general", keys[i], NULL))); @@ -338,7 +338,6 @@ for (i = 0; i < GNT_STYLES; i++) g_free(str_styles[i]); - g_hash_table_destroy(unknowns); #if GLIB_CHECK_VERSION(2,6,0) g_key_file_free(gkfile); #endif diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntstyle.h diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gnttree.c --- a/finch/libgnt/gnttree.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gnttree.c Tue Jun 12 21:21:37 2007 +0000 @@ -303,7 +303,7 @@ notfirst = TRUE; - if (len > width - 2) { + if (len > width) { len = width - 1; cut = TRUE; } diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntutils.c diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntutils.h --- a/finch/libgnt/gntutils.h Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntutils.h Tue Jun 12 21:21:37 2007 +0000 @@ -99,6 +99,8 @@ * @param widget * * @return + * + * @deprecated Consider using gnt_bindable_bindings_view instead. */ GntWidget * gnt_widget_bindings_view(GntWidget *widget); diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntwidget.c diff -r 9018b785ef73 -r ac904659104f finch/libgnt/gntwm.c --- a/finch/libgnt/gntwm.c Mon Jun 11 17:36:40 2007 +0000 +++ b/finch/libgnt/gntwm.c Tue Jun 12 21:21:37 2007 +0000 @@ -34,7 +34,9 @@ #include #include +#include "gntbutton.h" #include "gntwm.h" +#include "gntentry.h" #include "gntstyle.h" #include "gntmarshal.h" #include "gnt.h" @@ -83,6 +85,7 @@ static time_t last_active_time; static gboolean idle_update; static GList *act = NULL; /* list of WS with unseen activitiy */ +static gboolean ignore_keys = FALSE; static GList * g_list_bring_to_front(GList *list, gpointer data) @@ -630,6 +633,7 @@ list_of_windows(GntWM *wm, gboolean workspace) { GntWidget *tree, *win; + setup__list(wm); wm->windows = &wm->_list; @@ -1128,6 +1132,71 @@ return TRUE; } +static gboolean +ignore_keys_start(GntBindable *bindable, GList *n) +{ + GntWM *wm = GNT_WM(bindable); + + if(!wm->menu && !wm->_list.window && wm->mode == GNT_KP_MODE_NORMAL){ + ignore_keys = TRUE; + return TRUE; + } + return FALSE; +} + +static gboolean +ignore_keys_end(GntBindable *bindable, GList *n) +{ + return ignore_keys ? !(ignore_keys = FALSE) : FALSE; +} + +static gboolean +help_for_bindable(GntWM *wm, GntBindable *bindable) +{ + gboolean ret = TRUE; + GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable); + + if (klass->help_window) { + gnt_wm_raise_window(wm, GNT_WIDGET(klass->help_window)); + } else { + ret = gnt_bindable_build_help_window(bindable); + } + return ret; + +} + +static gboolean +help_for_wm(GntBindable *bindable, GList *null) +{ + return help_for_bindable(GNT_WM(bindable),bindable); +} + +static gboolean +help_for_window(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *widget = wm->ordered->data; + + return help_for_bindable(wm,GNT_BINDABLE(widget)); +} + +static gboolean +help_for_widget(GntBindable *bindable, GList *null) +{ + GntWM *wm = GNT_WM(bindable); + GntWidget *widget; + + if (!wm->ordered) + return TRUE; + + widget = wm->ordered->data; + if (!GNT_IS_BOX(widget)) + return TRUE; + + return help_for_bindable(wm, GNT_BINDABLE(GNT_BOX(widget)->active)); + +} + static void gnt_wm_class_init(GntWMClass *klass) { @@ -1271,9 +1340,19 @@ gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "place-tagged", place_tagged, "\033" "T", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "workspace-list", workspace_list, - "\033" "s", NULL); + "\033" "s", NULL); gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-clipboard", toggle_clipboard, "\033" "C", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-wm", help_for_wm, + "\033" "\\", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "help-for-window", help_for_window, + "\033" "|", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "toggle-clipboard", toggle_clipboard, + "\033" "C", NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "ignore-keys-start", ignore_keys_start, + GNT_KEY_CTRL_G, NULL); + gnt_bindable_class_register_action(GNT_BINDABLE_CLASS(klass), "ignore-keys-end", ignore_keys_end, + "\033" GNT_KEY_CTRL_G, NULL); gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass)); @@ -1647,6 +1726,15 @@ idle_update = TRUE; + if(ignore_keys){ + if(keys && !strcmp(keys, "\033" GNT_KEY_CTRL_G)){ + if(gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)){ + return TRUE; + } + } + return wm->cws->ordered ? gnt_widget_key_pressed(GNT_WIDGET(wm->cws->ordered->data), keys) : FALSE; + } + if (gnt_bindable_perform_action_key(GNT_BINDABLE(wm), keys)) { return TRUE; }