comparison finch/libgnt/gntbindable.c @ 19174:974f9298814c

propagate from branch 'im.pidgin.pidgin.2.1.0' (head 1b855097a1f8ddde513bda1e81761c8d8455f931) to branch 'im.pidgin.soc.2007.finchfeat' (head 547aba29502f4db0b429e29c831c88b06270862e)
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sat, 11 Aug 2007 02:38:56 +0000
parents d5a0b09470ee
children 33201366bcd4
comparison
equal deleted inserted replaced
19097:7ee44399f2ea 19174:974f9298814c
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;
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 void
57 gnt_bindable_rebinding_cancel(GntWidget *button, gpointer data)
58 {
59 gnt_bindable_free_rebind_info();
60 gnt_widget_destroy(GNT_WIDGET(data));
61 }
62
63 static void
64 gnt_bindable_rebinding_rebind(GntWidget *button, gpointer data)
65 {
66
67 if(rebind_info.keys) {
68 gnt_bindable_register_binding(rebind_info.klass,
69 NULL,
70 rebind_info.okeys,
71 rebind_info.params);
72 gnt_bindable_register_binding(rebind_info.klass,
73 rebind_info.name,
74 rebind_info.keys,
75 rebind_info.params);
76 }
77 gnt_bindable_free_rebind_info();
78
79 gnt_widget_destroy(GNT_WIDGET(data));
80 }
81
82 static gboolean
83 gnt_bindable_rebinding_grab_key(GntBindable *bindable, const char *text, gpointer *data)
84 {
85
86 GntTextView *textview= GNT_TEXT_VIEW(data);
87 char *new_text;
88 const char *tmp;
89
90 if(text && *text){
91
92 if(!strcmp(text, GNT_KEY_CTRL_I) || !strcmp(text, GNT_KEY_ENTER)){
93 return FALSE;
94 }
95
96 tmp = gnt_key_lookup(text);
97 new_text = g_strdup_printf("KEY: \"%s\"",tmp);
98 gnt_text_view_clear(textview);
99 gnt_text_view_append_text_with_flags(textview,new_text,GNT_TEXT_FLAG_NORMAL);
100 g_free(new_text);
101
102 g_free(rebind_info.keys);
103 rebind_info.keys = g_strdup(text);
104
105
106 return TRUE;
107 }
108 return FALSE;
109 }
110 static void
111 gnt_bindable_rebinding_activate(GntBindable *data, gpointer bindable)
112 {
113
114 GntTree * tree = GNT_TREE(data);
115
116 GntWidget *vbox = gnt_box_new(FALSE,TRUE);
117
118 GntWidget *label;
119 const char * widget_name = g_type_name(G_OBJECT_TYPE(bindable));
120 char * keys;
121
122 GntWidget *key_textview;
123
124 GntWidget *bind_button, *cancel_button;
125 GntWidget *button_box;
126
127 GntWidget *win = gnt_window_new();
128 GList * current_row_data,*itr;
129 char * tmp;
130
131 rebind_info.klass = GNT_BINDABLE_GET_CLASS(bindable);
132
133 current_row_data = gnt_tree_get_selection_text_list(tree);
134 rebind_info.name = g_strdup(g_list_nth_data(current_row_data,1));
135
136 keys = gnt_tree_get_selection_data(tree);
137 rebind_info.okeys = g_strdup(gnt_key_translate(keys));
138
139 rebind_info.params = NULL;
140
141 itr = current_row_data;
142 while(itr){
143 g_free(itr->data);
144 itr = itr->next;
145 }
146 g_list_free(current_row_data);
147
148 gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID);
149
150 gnt_box_set_title(GNT_BOX(win),"Key Capture");
151
152 tmp = g_strdup_printf("Type the new bindings for %s in a %s.",rebind_info.name,widget_name);
153 label = gnt_label_new(tmp);
154 g_free(tmp);
155 gnt_box_add_widget(GNT_BOX(vbox),label);
156
157 tmp = g_strdup_printf("KEY: \"%s\"",keys);
158 key_textview = gnt_text_view_new();
159 gnt_widget_set_size(key_textview,key_textview->priv.x,2);
160 gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(key_textview),tmp,GNT_TEXT_FLAG_NORMAL);
161 g_free(tmp);
162 gnt_widget_set_name(key_textview,"keystroke");
163 gnt_box_add_widget(GNT_BOX(vbox),key_textview);
164
165 g_signal_connect(G_OBJECT(win), "key_pressed", G_CALLBACK(gnt_bindable_rebinding_grab_key),key_textview);
166
167 button_box = gnt_box_new(FALSE,FALSE);
168
169 bind_button = gnt_button_new("BIND");
170 gnt_widget_set_name(bind_button,"bind");
171 gnt_box_add_widget(GNT_BOX(button_box), bind_button);
172
173 cancel_button = gnt_button_new("Cancel");
174 gnt_widget_set_name(cancel_button,"cancel");
175 gnt_box_add_widget(GNT_BOX(button_box),cancel_button);
176
177 g_signal_connect(G_OBJECT(bind_button), "activate", G_CALLBACK(gnt_bindable_rebinding_rebind),win);
178 g_signal_connect(G_OBJECT(cancel_button), "activate", G_CALLBACK(gnt_bindable_rebinding_cancel),win);
179
180
181 gnt_box_add_widget(GNT_BOX(vbox),button_box);
182
183 gnt_box_add_widget(GNT_BOX(win),vbox);
184 gnt_widget_show(win);
185
186 }
187
188 typedef struct {
189 GHashTable *hash;
190 GntTree *tree;
191 } BindingView;
192
193 static void
194 add_binding(gpointer key, gpointer value, gpointer data)
195 {
196 BindingView *bv = data;
197 GntBindableActionParam *act = value;
198 const char *name = g_hash_table_lookup(bv->hash, act->action);
199 if (name && *name) {
200 const char *k = gnt_key_lookup(key);
201 if (!k)
202 k = key;
203 gnt_tree_add_row_after(bv->tree, (gpointer)k,
204 gnt_tree_create_row(bv->tree, k, name), NULL, NULL);
205 }
206 }
207
208 static void
209 add_action(gpointer key, gpointer value, gpointer data)
210 {
211 BindingView *bv = data;
212 g_hash_table_insert(bv->hash, value, key);
213 }
29 214
30 static void 215 static void
31 gnt_bindable_class_init(GntBindableClass *klass) 216 gnt_bindable_class_init(GntBindableClass *klass)
32 { 217 {
33 parent_class = g_type_class_peek_parent(klass); 218 parent_class = g_type_class_peek_parent(klass);
249 { 434 {
250 g_list_free(param->list); /* XXX: There may be a leak here for string parameters */ 435 g_list_free(param->list); /* XXX: There may be a leak here for string parameters */
251 g_free(param); 436 g_free(param);
252 } 437 }
253 438
254 439 GntBindable * gnt_bindable_bindings_view(GntBindable *bind)
440 {
441 GntBindable *tree = GNT_BINDABLE(gnt_tree_new_with_columns(2));
442 GntBindableClass *klass = GNT_BINDABLE_CLASS(GNT_BINDABLE_GET_CLASS(bind));
443 GHashTable *hash = g_hash_table_new(g_direct_hash, g_direct_equal);
444 BindingView bv = {hash, GNT_TREE(tree)};
445
446 gnt_tree_set_compare_func(bv.tree, (GCompareFunc)g_utf8_collate);
447 g_hash_table_foreach(klass->actions, add_action, &bv);
448 g_hash_table_foreach(klass->bindings, add_binding, &bv);
449 if (GNT_TREE(tree)->list == NULL) {
450 gnt_widget_destroy(GNT_WIDGET(tree));
451 tree = NULL;
452 } else
453 gnt_tree_adjust_columns(bv.tree);
454 g_hash_table_destroy(hash);
455
456 return tree;
457 }
458
459 static void
460 reset_binding_window(GntBindableClass *window, gpointer k)
461 {
462 GntBindableClass *klass = GNT_BINDABLE_CLASS(k);
463 klass->help_window = NULL;
464 }
465
466 gboolean
467 gnt_bindable_build_help_window(GntBindable *bindable)
468 {
469
470 GntWidget *tree;
471 GntBindableClass *klass = GNT_BINDABLE_GET_CLASS(bindable);
472 char *title;
473
474 tree = GNT_WIDGET(gnt_bindable_bindings_view(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 g_signal_connect(G_OBJECT(tree), "activate", G_CALLBACK(gnt_bindable_rebinding_activate), bindable);
481 gnt_box_add_widget(GNT_BOX(klass->help_window), tree);
482 } else
483 gnt_box_add_widget(GNT_BOX(klass->help_window), gnt_label_new("This widget has no customizable bindings."));
484
485 g_signal_connect(G_OBJECT(klass->help_window), "destroy", G_CALLBACK(reset_binding_window), klass);
486 gnt_widget_show(GNT_WIDGET(klass->help_window));
487 g_free(title);
488
489 return TRUE;
490 }
491