changeset 17721: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;