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 = _ ("&Save");
261 const char *b1 = _ ("&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 #endif
274
275 do_refresh ();
276
277 learn_dlg = dlg_create (TRUE, 0, 0, dlg_height, dlg_width, WPOS_CENTER, FALSE, dialog_colors,
278 learn_callback, NULL, "[Learn keys]", learn_title);
279 g = GROUP (learn_dlg);
280
281
282 for (key = key_name_conv_tab, learn_total = 0;
283 key->name != NULL && strcmp (key->name, "kpleft") != 0; key++, learn_total++)
284 ;
285
286 learnok = 0;
287 learnchanged = FALSE;
288
289 learnkeys = g_new (learnkey_t, learn_total);
290
291 x = UX;
292 y = UY;
293
294
295 for (i = 0; i < learn_total; i++)
296 {
297 char buffer[BUF_TINY];
298 const char *label;
299 int padding;
300
301 learnkeys[i].ok = FALSE;
302 learnkeys[i].sequence = NULL;
303
304 label = _ (key_name_conv_tab[i].longname);
305 padding = 16 - str_term_width1 (label);
306 padding = MAX (0, padding);
307 g_snprintf (buffer, sizeof (buffer), "%s%*s", label, padding, "");
308
309 learnkeys[i].button =
310 WIDGET (button_new (y, x, B_USER + i, NARROW_BUTTON, buffer, learn_button));
311 learnkeys[i].label = WIDGET (label_new (y, x + 19, NULL));
312 group_add_widget (g, learnkeys[i].button);
313 group_add_widget (g, learnkeys[i].label);
314
315 y++;
316 if (y == UY + ROWS)
317 {
318 x += COLSHIFT;
319 y = UY;
320 }
321 }
322
323 group_add_widget (g, hline_new (dlg_height - 8, -1, -1));
324 group_add_widget (
325 g,
326 label_new (dlg_height - 7, 5,
327 _ ("Press all the keys mentioned here. After you have done it, check\n"
328 "which keys are not marked with OK. Press space on the missing\n"
329 "key, or click with the mouse to define it. Move around with Tab.")));
330 group_add_widget (g, hline_new (dlg_height - 4, -1, -1));
331
332 bt0 = button_new (dlg_height - 3, 1, B_ENTER, DEFPUSH_BUTTON, b0, NULL);
333 bt1 = button_new (dlg_height - 3, 1, B_CANCEL, NORMAL_BUTTON, b1, NULL);
334
335 const int bw0 = button_get_width (bt0);
336 const int bw1 = button_get_width (bt1);
337
338 const int bx0 = (dlg_width - (bw0 + bw1 + 1)) / 2;
339 const int bx1 = bx0 + bw0 + 1;
340
341 WIDGET (bt0)->rect.x = bx0;
342 WIDGET (bt1)->rect.x = bx1;
343
344 group_add_widget (g, bt0);
345 group_add_widget (g, bt1);
346 }
347
348
349
350 static void
351 learn_done (void)
352 {
353 widget_destroy (WIDGET (learn_dlg));
354 repaint_screen ();
355 }
356
357
358
359 static void
360 learn_save (void)
361 {
362 int i;
363 char *section;
364 gboolean profile_changed = FALSE;
365
366 section = g_strconcat ("terminal:", getenv ("TERM"), (char *) NULL);
367
368 for (i = 0; i < learn_total; i++)
369 if (learnkeys[i].sequence != NULL)
370 {
371 char *esc_str;
372
373 esc_str = str_escape (learnkeys[i].sequence, -1, ";\\", TRUE);
374 mc_config_set_string_raw_value (mc_global.main_config, section,
375 key_name_conv_tab[i].name, esc_str);
376 g_free (esc_str);
377
378 profile_changed = TRUE;
379 }
380
381
382
383
384
385
386
387 if (profile_changed)
388 mc_config_save_file (mc_global.main_config, NULL);
389
390 g_free (section);
391 }
392
393
394
395
396
397 void
398 learn_keys (void)
399 {
400 gboolean save_old_esc_mode = old_esc_mode;
401 gboolean save_alternate_plus_minus = mc_global.tty.alternate_plus_minus;
402 int result;
403
404
405 old_esc_mode = 0;
406
407
408
409
410 mc_global.tty.alternate_plus_minus = TRUE;
411 application_keypad_mode ();
412
413 init_learn ();
414 result = dlg_run (learn_dlg);
415
416 old_esc_mode = save_old_esc_mode;
417 mc_global.tty.alternate_plus_minus = save_alternate_plus_minus;
418
419 if (!mc_global.tty.alternate_plus_minus)
420 numeric_keypad_mode ();
421
422 if (result == B_ENTER)
423 learn_save ();
424
425 learn_done ();
426 }
427
428