Mercurial > pidgin
changeset 17931:3ee6ea8a66f8
Moved rebinding functionality into GntBindable.
Added: If a bindinglist already exists, it isn't brought up again.
Deprecated gnt_widget_bindings_view out of gntutils and moved it to gntbindable
author | Eric Polino <aluink@pidgin.im> |
---|---|
date | Fri, 08 Jun 2007 04:14:56 +0000 |
parents | 71df538ed27c |
children | 15988e2bd270 |
files | finch/libgnt/gntbindable.c finch/libgnt/gntbindable.h finch/libgnt/gntutils.c finch/libgnt/gntutils.h finch/libgnt/gntwm.c |
diffstat | 5 files changed, 328 insertions(+), 243 deletions(-) [+] |
line wrap: on
line diff
--- a/finch/libgnt/gntbindable.c Thu Jun 07 21:58:04 2007 +0000 +++ b/finch/libgnt/gntbindable.c Fri Jun 08 04:14:56 2007 +0000 @@ -20,13 +20,204 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <string.h> + #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 +442,49 @@ 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; +} + +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)); + g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(gnt_bindable_rebinding_activate), 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) + 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.")); + + gnt_widget_show(GNT_WIDGET(klass->help_window)); + + return TRUE; + +} + +
--- a/finch/libgnt/gntbindable.h Thu Jun 07 21:58:04 2007 +0000 +++ b/finch/libgnt/gntbindable.h Fri Jun 08 04:14:56 2007 +0000 @@ -28,6 +28,7 @@ #include <glib-object.h> #include <ncurses.h> + #define GNT_TYPE_BINDABLE (gnt_bindable_get_gtype()) #define GNT_BINDABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_BINDABLE, GntBindable)) #define GNT_BINDABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_BINDABLE, GntBindableClass)) @@ -53,7 +54,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 +148,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 */
--- a/finch/libgnt/gntutils.c Thu Jun 07 21:58:04 2007 +0000 +++ b/finch/libgnt/gntutils.c Fri Jun 08 04:14:56 2007 +0000 @@ -30,6 +30,7 @@ #include "gnttree.h" #include "gntutils.h" #include "gntwindow.h" +#include "gntbindable.h" #include "config.h" @@ -184,53 +185,12 @@ return continue_emission; } -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); - } +GntWidget * gnt_widget_bindings_view(GntWidget *widget){ + return GNT_WIDGET(gnt_bindable_bindings_view(GNT_BINDABLE(widget))); } -static void -add_action(gpointer key, gpointer value, gpointer data) -{ - BindingView *bv = data; - g_hash_table_insert(bv->hash, value, key); -} -GntWidget *gnt_widget_bindings_view(GntWidget *widget) -{ - GntBindable *bind = GNT_BINDABLE(widget); - GntWidget *tree = 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(tree); - tree = NULL; - } else - gnt_tree_adjust_columns(bv.tree); - g_hash_table_destroy(hash); - - return tree; -} #ifndef NO_LIBXML static GntWidget *
--- a/finch/libgnt/gntutils.h Thu Jun 07 21:58:04 2007 +0000 +++ b/finch/libgnt/gntutils.h Fri Jun 08 04:14:56 2007 +0000 @@ -93,12 +93,16 @@ /** * Returns a GntTree populated with "key" -> "binding" for the widget. + * + * */ /** * * @param widget * * @return + * + * @deprecated Consider using gnt_bindable_bindings_view instead. */ GntWidget * gnt_widget_bindings_view(GntWidget *widget);
--- a/finch/libgnt/gntwm.c Thu Jun 07 21:58:04 2007 +0000 +++ b/finch/libgnt/gntwm.c Fri Jun 08 04:14:56 2007 +0000 @@ -83,16 +83,6 @@ static gboolean ignore_keys = FALSE; -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 GList * g_list_bring_to_front(GList *list, gpointer data) { @@ -519,196 +509,7 @@ return TRUE; } -static void -free_rebind_info() -{ - g_free(rebind_info.name); - g_free(rebind_info.keys); - g_free(rebind_info.okeys); -} -static gboolean -help_for_widget_cancel_button_activate(GntBindable *bindable, gpointer data) -{ - free_rebind_info(); - gnt_widget_destroy(GNT_WIDGET(data)); - return TRUE; -} - -static gboolean -help_for_widget_bind_button_activate(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); - } - free_rebind_info(); - - gnt_widget_destroy(GNT_WIDGET(data)); - - return TRUE; -} - -static gboolean -help_for_widget_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 -help_for_widget_activate(GntBindable *bindable, gpointer widget) -{ - - GntTree * tree = GNT_TREE(bindable); - - GntWidget *vbox = gnt_box_new(FALSE,TRUE); - - GntWidget *label; - const char * widget_name = g_type_name(G_OBJECT_TYPE(widget)); - 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(widget); - - 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(help_for_widget_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(help_for_widget_bind_button_activate),win); - g_signal_connect(G_OBJECT(cancel_button), "activate", G_CALLBACK(help_for_widget_cancel_button_activate),win); - - - gnt_box_add_widget(GNT_BOX(vbox),button_box); - - gnt_box_add_widget(GNT_BOX(win),vbox); - gnt_widget_show(win); - -} - -static gboolean -build_help_window(GntWidget *widget){ - - GntWidget *tree,*win; - char *title; - - tree = gnt_widget_bindings_view(widget); - g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(help_for_widget_activate), widget); - - win = gnt_window_new(); - title = g_strdup_printf("Bindings for %s", g_type_name(G_OBJECT_TYPE(widget))); - 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 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 build_help_window(GNT_BOX(widget)->active); - - -} - -static gboolean -help_for_wm(GntBindable *bindable, GList *null){ - - return build_help_window(GNT_WIDGET(bindable)); - -} static void destroy__list(GntWidget *widget, GntWM *wm) @@ -1230,11 +1031,68 @@ return ignore_keys ? !(ignore_keys = FALSE) : FALSE; } +static GntBox * +check_for_window_exist(GntWM *wm, const char *title) +{ + GList *iter; + for(iter = wm->list;iter;iter = iter->next){ + GntBox *box = GNT_BOX(iter->data); + if(!strcmp(box->title,title)) + return box; + } + return NULL; +} + +static gboolean +help_for_bindable(GntWM *wm, GntBindable *bindable) +{ + GntBox *box; + char * title; + gboolean ret = TRUE; + + title = g_strdup_printf("Bindings for %s",g_type_name(G_OBJECT_TYPE(bindable))); + + if((box = check_for_window_exist(wm,title))){ + gnt_wm_raise_window(wm,GNT_WIDGET(box)); + } + else{ + ret = gnt_bindable_build_help_window(bindable); + } + g_free(title); + return ret; + +} + +static gboolean +help_for_wm(GntBindable *bindable, GList *null) +{ + return help_for_bindable(GNT_WM(bindable),bindable); +} + +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) { int i; + + klass->new_window = gnt_wm_new_window_real; klass->decorate_window = NULL; klass->close_window = NULL;