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