comparison finch/libgnt/gntbindable.c @ 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 8410511f4dbb
children 15988e2bd270
comparison
equal deleted inserted replaced
17930:71df538ed27c 17931:3ee6ea8a66f8
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23 #include <string.h>
24
23 #include "gntbindable.h" 25 #include "gntbindable.h"
24 #include "gntstyle.h" 26 #include "gntstyle.h"
25 #include "gnt.h" 27 #include "gnt.h"
26 #include "gntutils.h" 28 #include "gntutils.h"
29 #include "gnttextview.h"
30 #include "gnttree.h"
31 #include "gntbox.h"
32 #include "gntbutton.h"
33 #include "gntwindow.h"
34 #include "gntlabel.h"
27 35
28 static GObjectClass *parent_class = NULL; 36 static GObjectClass *parent_class = NULL;
29 37
38 static struct
39 {
40 char * okeys; /* Old keystrokes */
41 char * keys; /* New Keystrokes being bound to the action */
42 GntBindableClass * klass; /* Class of the object that's getting keys rebound */
43 char * name; /* The name of the action */
44 GList * params; /* The list of paramaters */
45
46 } rebind_info = {NULL,NULL,NULL,NULL,NULL};
47
48 static void
49 gnt_bindable_free_rebind_info()
50 {
51 g_free(rebind_info.name);
52 g_free(rebind_info.keys);
53 g_free(rebind_info.okeys);
54 }
55
56 static gboolean
57 gnt_bindable_rebinding_cancel(GntBindable *bindable, gpointer data)
58 {
59 gnt_bindable_free_rebind_info();
60 gnt_widget_destroy(GNT_WIDGET(data));
61 return TRUE;
62 }
63
64 static gboolean
65 gnt_bindable_rebinding_rebind(GntBindable *bindable, gpointer data)
66 {
67
68 if(rebind_info.keys){
69 gnt_bindable_register_binding(rebind_info.klass,
70 NULL,
71 rebind_info.okeys,
72 rebind_info.params);
73 gnt_bindable_register_binding(rebind_info.klass,
74 rebind_info.name,
75 rebind_info.keys,
76 rebind_info.params);
77 }
78 gnt_bindable_free_rebind_info();
79
80 gnt_widget_destroy(GNT_WIDGET(data));
81
82 return TRUE;
83 }
84
85 static gboolean
86 gnt_bindable_rebinding_grab_key(GntBindable *bindable, const char *text, gpointer *data)
87 {
88
89 GntTextView *textview= GNT_TEXT_VIEW(data);
90 char *new_text;
91 const char *tmp;
92
93 if(text && *text){
94
95 if(!strcmp(text, GNT_KEY_CTRL_I) || !strcmp(text, GNT_KEY_ENTER)){
96 return FALSE;
97 }
98
99 tmp = gnt_key_lookup(text);
100 new_text = g_strdup_printf("KEY: \"%s\"",tmp);
101 gnt_text_view_clear(textview);
102 gnt_text_view_append_text_with_flags(textview,new_text,GNT_TEXT_FLAG_NORMAL);
103 g_free(new_text);
104
105 g_free(rebind_info.keys);
106 rebind_info.keys = g_strdup(text);
107
108
109 return TRUE;
110 }
111 return FALSE;
112 }
113 static void
114 gnt_bindable_rebinding_activate(GntBindable *data, gpointer bindable)
115 {
116
117 GntTree * tree = GNT_TREE(data);
118
119 GntWidget *vbox = gnt_box_new(FALSE,TRUE);
120
121 GntWidget *label;
122 const char * widget_name = g_type_name(G_OBJECT_TYPE(bindable));
123 char * keys;
124
125 GntWidget *key_textview;
126
127 GntWidget *bind_button, *cancel_button;
128 GntWidget *button_box;
129
130 GntWidget *win = gnt_window_new();
131 GList * current_row_data,*itr;
132 char * tmp;
133
134 rebind_info.klass = GNT_BINDABLE_GET_CLASS(bindable);
135
136 current_row_data = gnt_tree_get_selection_text_list(tree);
137 rebind_info.name = g_strdup(g_list_nth_data(current_row_data,1));
138
139 keys = gnt_tree_get_selection_data(tree);
140 rebind_info.okeys = g_strdup(gnt_key_translate(keys));
141
142 rebind_info.params = NULL;
143
144 itr = current_row_data;
145 while(itr){
146 g_free(itr->data);
147 itr = itr->next;
148 }
149 g_list_free(current_row_data);
150
151 gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID);
152
153 gnt_box_set_title(GNT_BOX(win),"Key Capture");
154
155 tmp = g_strdup_printf("Type the new bindings for %s in a %s.",rebind_info.name,widget_name);
156 label = gnt_label_new(tmp);
157 g_free(tmp);
158 gnt_box_add_widget(GNT_BOX(vbox),label);
159
160 tmp = g_strdup_printf("KEY: \"%s\"",keys);
161 key_textview = gnt_text_view_new();
162 gnt_widget_set_size(key_textview,key_textview->priv.x,2);
163 gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(key_textview),tmp,GNT_TEXT_FLAG_NORMAL);
164 g_free(tmp);
165 gnt_widget_set_name(key_textview,"keystroke");
166 gnt_box_add_widget(GNT_BOX(vbox),key_textview);
167
168 g_signal_connect(G_OBJECT(win), "key_pressed", G_CALLBACK(gnt_bindable_rebinding_grab_key),key_textview);
169
170 button_box = gnt_box_new(FALSE,FALSE);
171
172 bind_button = gnt_button_new("BIND");
173 gnt_widget_set_name(bind_button,"bind");
174 gnt_box_add_widget(GNT_BOX(button_box), bind_button);
175
176 cancel_button = gnt_button_new("Cancel");
177 gnt_widget_set_name(cancel_button,"cancel");
178 gnt_box_add_widget(GNT_BOX(button_box),cancel_button);
179
180 g_signal_connect(G_OBJECT(bind_button), "activate", G_CALLBACK(gnt_bindable_rebinding_rebind),win);
181 g_signal_connect(G_OBJECT(cancel_button), "activate", G_CALLBACK(gnt_bindable_rebinding_cancel),win);
182
183
184 gnt_box_add_widget(GNT_BOX(vbox),button_box);
185
186 gnt_box_add_widget(GNT_BOX(win),vbox);
187 gnt_widget_show(win);
188
189 }
190
191 typedef struct {
192 GHashTable *hash;
193 GntTree *tree;
194 } BindingView;
195
196 static void
197 add_binding(gpointer key, gpointer value, gpointer data)
198 {
199 BindingView *bv = data;
200 GntBindableActionParam *act = value;
201 const char *name = g_hash_table_lookup(bv->hash, act->action);
202 if (name && *name) {
203 const char *k = gnt_key_lookup(key);
204 if (!k)
205 k = key;
206 gnt_tree_add_row_after(bv->tree, (gpointer)k,
207 gnt_tree_create_row(bv->tree, k, name), NULL, NULL);
208 }
209 }
210
211 static void
212 add_action(gpointer key, gpointer value, gpointer data)
213 {
214 BindingView *bv = data;
215 g_hash_table_insert(bv->hash, value, key);
216 }
217
218
219
220
30 static void 221 static void
31 gnt_bindable_class_init(GntBindableClass *klass) 222 gnt_bindable_class_init(GntBindableClass *klass)
32 { 223 {
33 parent_class = g_type_class_peek_parent(klass); 224 parent_class = g_type_class_peek_parent(klass);
34 225
249 { 440 {
250 g_list_free(param->list); /* XXX: There may be a leak here for string parameters */ 441 g_list_free(param->list); /* XXX: There may be a leak here for string parameters */
251 g_free(param); 442 g_free(param);
252 } 443 }
253 444
254 445 GntBindable * gnt_bindable_bindings_view(GntBindable *bind)
446 {
447 GntBindable *tree = GNT_BINDABLE(gnt_tree_new_with_columns(2));
448 GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bind));
449 GHashTable *hash = g_hash_table_new(g_direct_hash, g_direct_equal);
450 BindingView bv = {hash, GNT_TREE(tree)};
451
452 gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate);
453 g_hash_table_foreach(klass->actions, add_action, &bv);
454 g_hash_table_foreach(klass->bindings, add_binding, &bv);
455 if (GNT_TREE(tree)->list == NULL) {
456 gnt_widget_destroy(GNT_WIDGET(tree));
457 tree = NULL;
458 } else
459 gnt_tree_adjust_columns(bv.tree);
460 g_hash_table_destroy(hash);
461
462 return tree;
463 }
464
465 gboolean
466 gnt_bindable_build_help_window(GntBindable *bindable)
467 {
468
469 GntWidget *tree;
470 GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable);
471 char *title;
472
473 tree = GNT_WIDGET(gnt_bindable_bindings_view(bindable));
474 g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(gnt_bindable_rebinding_activate), bindable);
475
476 klass->help_window = GNT_BINDABLE(gnt_window_new());
477 title = g_strdup_printf("Bindings for %s", g_type_name(G_OBJECT_TYPE(bindable)));
478 gnt_box_set_title(GNT_BOX(klass->help_window), title);
479 if (tree)
480 gnt_box_add_widget(GNT_BOX(klass->help_window), tree);
481 else
482 gnt_box_add_widget(GNT_BOX(klass->help_window), gnt_label_new("This widget has no customizable bindings."));
483
484 gnt_widget_show(GNT_WIDGET(klass->help_window));
485
486 return TRUE;
487
488 }
489
490