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