This source file includes following definitions.
- learn_button
- learn_move
- learn_check_key
- learn_callback
- init_learn
- learn_done
- learn_save
- learn_keys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include <config.h>
32
33 #include <stdlib.h>
34
35 #include "lib/global.h"
36
37 #include "lib/tty/tty.h"
38 #include "lib/tty/key.h"
39 #include "lib/mcconfig.h"
40 #include "lib/strutil.h"
41 #include "lib/terminal.h"
42 #include "lib/util.h"
43 #include "lib/widget.h"
44
45 #include "setup.h"
46 #include "learn.h"
47
48
49
50
51
52 #define UX 4
53 #define UY 2
54
55 #define ROWS 13
56 #define COLSHIFT 23
57
58
59
60 typedef struct
61 {
62 Widget *button;
63 Widget *label;
64 gboolean ok;
65 char *sequence;
66 } learnkey_t;
67
68
69
70
71
72 static WDialog *learn_dlg;
73 static const char *learn_title = N_ ("Learn keys");
74
75 static learnkey_t *learnkeys = NULL;
76 static int learn_total;
77 static int learnok;
78 static gboolean learnchanged = FALSE;
79
80
81
82
83
84 static int
85 learn_button (WButton *button, int action)
86 {
87 WDialog *d;
88 char *seq;
89
90 (void) button;
91
92 d = create_message (D_ERROR, _ ("Teach me a key"),
93 _ ("Please press the %s\n"
94 "and then wait until this message disappears.\n\n"
95 "Then, press it again to see if OK appears\n"
96 "next to its button.\n\n"
97 "If you want to escape, press a single Escape key\n"
98 "and wait as well."),
99 _ (key_name_conv_tab[action - B_USER].longname));
100 mc_refresh ();
101 if (learnkeys[action - B_USER].sequence != NULL)
102 MC_PTR_FREE (learnkeys[action - B_USER].sequence);
103
104 seq = learn_key ();
105 if (seq != NULL)
106 {
107
108
109
110 gboolean seq_ok = FALSE;
111
112 if (strcmp (seq, "\\e") != 0 && strcmp (seq, "\\e\\e") != 0 && strcmp (seq, "^m") != 0
113 && strcmp (seq, "^i") != 0 && (seq[1] != '\0' || *seq < ' ' || *seq > '~'))
114 {
115 learnchanged = TRUE;
116 learnkeys[action - B_USER].sequence = seq;
117 seq = convert_controls (seq);
118 seq_ok = define_sequence (key_name_conv_tab[action - B_USER].code, seq, MCKEY_NOACTION);
119 }
120
121 if (!seq_ok)
122 message (D_NORMAL, _ ("Warning"),
123 _ ("Cannot accept this key.\nYou have entered \"%s\""), seq);
124
125 g_free (seq);
126 }
127
128 dlg_run_done (d);
129 widget_destroy (WIDGET (d));
130
131 widget_select (learnkeys[action - B_USER].button);
132
133 return 0;
134 }
135
136
137
138 static gboolean
139 learn_move (gboolean right)
140 {
141 int i, totalcols;
142
143 totalcols = (learn_total - 1) / ROWS + 1;
144 for (i = 0; i < learn_total; i++)
145 if (learnkeys[i].button == WIDGET (GROUP (learn_dlg)->current->data))
146 {
147 if (right)
148 {
149 if (i < learn_total - ROWS)
150 i += ROWS;
151 else
152 i %= ROWS;
153 }
154 else
155 {
156 if (i / ROWS != 0)
157 i -= ROWS;
158 else if (i + (totalcols - 1) * ROWS >= learn_total)
159 i += (totalcols - 2) * ROWS;
160 else
161 i += (totalcols - 1) * ROWS;
162 }
163 widget_select (learnkeys[i].button);
164 return TRUE;
165 }
166
167 return FALSE;
168 }
169
170
171
172 static gboolean
173 learn_check_key (int c)
174 {
175 int i;
176
177 for (i = 0; i < learn_total; i++)
178 {
179 if (key_name_conv_tab[i].code != c || learnkeys[i].ok)
180 continue;
181
182 widget_select (learnkeys[i].button);
183
184 label_set_text (LABEL (learnkeys[i].label), _ ("OK"));
185 learnkeys[i].ok = TRUE;
186 learnok++;
187 if (learnok >= learn_total)
188 {
189 learn_dlg->ret_value = B_CANCEL;
190 if (learnchanged)
191 {
192 if (query_dialog (learn_title,
193 _ ("It seems that all your keys already\n"
194 "work fine. That's great."),
195 D_ERROR, 2, _ ("&Save"), _ ("&Discard"))
196 == 0)
197 learn_dlg->ret_value = B_ENTER;
198 }
199 else
200 {
201 message (D_ERROR, learn_title, "%s",
202 _ ("Great! You have a complete terminal database!\n"
203 "All your keys work well."));
204 }
205 dlg_close (learn_dlg);
206 }
207 return TRUE;
208 }
209
210 switch (c)
211 {
212 case KEY_LEFT:
213 case 'h':
214 return learn_move (FALSE);
215 case KEY_RIGHT:
216 case 'l':
217 return learn_move (TRUE);
218 case 'j':
219 group_select_next_widget (GROUP (learn_dlg));
220 return TRUE;
221 case 'k':
222 group_select_prev_widget (GROUP (learn_dlg));
223 return TRUE;
224 default:
225 break;
226 }
227
228
229
230 return (c < 255 && g_ascii_isalnum (c));
231 }
232
233
234
235 static cb_ret_t
236 learn_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
237 {
238 switch (msg)
239 {
240 case MSG_KEY:
241 return learn_check_key (parm) ? MSG_HANDLED : MSG_NOT_HANDLED;
242
243 default:
244 return dlg_default_callback (w, sender, msg, parm, data);
245 }
246 }
247
248
249
250 static void
251 init_learn (void)
252 {
253 WGroup *g;
254
255 const int dlg_width = 78;
256 const int dlg_height = 23;
257
258
259 WButton *bt0, *bt1;
260 const char *b0 = N_ ("&Save");
261 const char *b1 = N_ ("&Cancel");
262
263 int x, y, i;
264 const key_code_name_t *key;
265
266 #ifdef ENABLE_NLS
267 static gboolean i18n_flag = FALSE;
268 if (!i18n_flag)
269 {
270 learn_title = _ (learn_title);
271 i18n_flag = TRUE;
272 }
273
274 b0 = _ (b0);
275 b1 = _ (b1);
276 #endif
277
278 do_refresh ();
279
280 learn_dlg = dlg_create (TRUE, 0, 0, dlg_height, dlg_width, WPOS_CENTER, FALSE, dialog_colors,
281 learn_callback, NULL, "[Learn keys]", learn_title);
282 g = GROUP (learn_dlg);
283
284
285 for (key = key_name_conv_tab, learn_total = 0;
286 key->name != NULL && strcmp (key->name, "kpleft") != 0; key++, learn_total++)
287 ;
288
289 learnok = 0;
290 learnchanged = FALSE;
291
292 learnkeys = g_new (learnkey_t, learn_total);
293
294 x = UX;
295 y = UY;
296
297
298 for (i = 0; i < learn_total; i++)
299 {
300 char buffer[BUF_TINY];
301 const char *label;
302 int padding;
303
304 learnkeys[i].ok = FALSE;
305 learnkeys[i].sequence = NULL;
306
307 label = _ (key_name_conv_tab[i].longname);
308 padding = 16 - str_term_width1 (label);
309 padding = MAX (0, padding);
310 g_snprintf (buffer, sizeof (buffer), "%s%*s", label, padding, "");
311
312 learnkeys[i].button =
313 WIDGET (button_new (y, x, B_USER + i, NARROW_BUTTON, buffer, learn_button));
314 learnkeys[i].label = WIDGET (label_new (y, x + 19, NULL));
315 group_add_widget (g, learnkeys[i].button);
316 group_add_widget (g, learnkeys[i].label);
317
318 y++;
319 if (y == UY + ROWS)
320 {
321 x += COLSHIFT;
322 y = UY;
323 }
324 }
325
326 group_add_widget (g, hline_new (dlg_height - 8, -1, -1));
327 group_add_widget (
328 g,
329 label_new (dlg_height - 7, 5,
330 _ ("Press all the keys mentioned here. After you have done it, check\n"
331 "which keys are not marked with OK. Press space on the missing\n"
332 "key, or click with the mouse to define it. Move around with Tab.")));
333 group_add_widget (g, hline_new (dlg_height - 4, -1, -1));
334
335 bt0 = button_new (dlg_height - 3, 1, B_ENTER, DEFPUSH_BUTTON, b0, NULL);
336 bt1 = button_new (dlg_height - 3, 1, B_CANCEL, NORMAL_BUTTON, b1, NULL);
337
338 const int bw0 = button_get_width (bt0);
339 const int bw1 = button_get_width (bt1);
340
341 const int bx0 = (dlg_width - (bw0 + bw1 + 1)) / 2;
342 const int bx1 = bx0 + bw0 + 1;
343
344 WIDGET (bt0)->rect.x = bx0;
345 WIDGET (bt1)->rect.x = bx1;
346
347 group_add_widget (g, bt0);
348 group_add_widget (g, bt1);
349 }
350
351
352
353 static void
354 learn_done (void)
355 {
356 widget_destroy (WIDGET (learn_dlg));
357 repaint_screen ();
358 }
359
360
361
362 static void
363 learn_save (void)
364 {
365 int i;
366 char *section;
367 gboolean profile_changed = FALSE;
368
369 section = g_strconcat ("terminal:", getenv ("TERM"), (char *) NULL);
370
371 for (i = 0; i < learn_total; i++)
372 if (learnkeys[i].sequence != NULL)
373 {
374 char *esc_str;
375
376 esc_str = str_escape (learnkeys[i].sequence, -1, ";\\", TRUE);
377 mc_config_set_string_raw_value (mc_global.main_config, section,
378 key_name_conv_tab[i].name, esc_str);
379 g_free (esc_str);
380
381 profile_changed = TRUE;
382 }
383
384
385
386
387
388
389
390 if (profile_changed)
391 mc_config_save_file (mc_global.main_config, NULL);
392
393 g_free (section);
394 }
395
396
397
398
399
400 void
401 learn_keys (void)
402 {
403 gboolean save_old_esc_mode = old_esc_mode;
404 gboolean save_alternate_plus_minus = mc_global.tty.alternate_plus_minus;
405 int result;
406
407
408 old_esc_mode = 0;
409
410
411
412
413 mc_global.tty.alternate_plus_minus = TRUE;
414 application_keypad_mode ();
415
416 init_learn ();
417 result = dlg_run (learn_dlg);
418
419 old_esc_mode = save_old_esc_mode;
420 mc_global.tty.alternate_plus_minus = save_alternate_plus_minus;
421
422 if (!mc_global.tty.alternate_plus_minus)
423 numeric_keypad_mode ();
424
425 if (result == B_ENTER)
426 learn_save ();
427
428 learn_done ();
429 }
430
431