Mercurial > pidgin
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 |