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