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, _("Warning"), _("Cannot accept this key.\nYou have entered \"%s\""),
122 seq);
123
124 g_free (seq);
125 }
126
127 dlg_run_done (d);
128 widget_destroy (WIDGET (d));
129
130 widget_select (learnkeys[action - B_USER].button);
131
132 return 0;
133 }
134
135
136
137 static gboolean
138 learn_move (gboolean right)
139 {
140 int i, totalcols;
141
142 totalcols = (learn_total - 1) / ROWS + 1;
143 for (i = 0; i < learn_total; i++)
144 if (learnkeys[i].button == WIDGET (GROUP (learn_dlg)->current->data))
145 {
146 if (right)
147 {
148 if (i < learn_total - ROWS)
149 i += ROWS;
150 else
151 i %= ROWS;
152 }
153 else
154 {
155 if (i / ROWS != 0)
156 i -= ROWS;
157 else if (i + (totalcols - 1) * ROWS >= learn_total)
158 i += (totalcols - 2) * ROWS;
159 else
160 i += (totalcols - 1) * ROWS;
161 }
162 widget_select (learnkeys[i].button);
163 return TRUE;
164 }
165
166 return FALSE;
167 }
168
169
170
171 static gboolean
172 learn_check_key (int c)
173 {
174 int i;
175
176 for (i = 0; i < learn_total; i++)
177 {
178 if (key_name_conv_tab[i].code != c || learnkeys[i].ok)
179 continue;
180
181 widget_select (learnkeys[i].button);
182
183 label_set_text (LABEL (learnkeys[i].label), _("OK"));
184 learnkeys[i].ok = TRUE;
185 learnok++;
186 if (learnok >= learn_total)
187 {
188 learn_dlg->ret_value = B_CANCEL;
189 if (learnchanged)
190 {
191 if (query_dialog (learn_title,
192 _
193 ("It seems that all your keys already\n"
194 "work fine. That's great."), D_ERROR, 2,
195 _("&Save"), _("&Discard")) == 0)
196 learn_dlg->ret_value = B_ENTER;
197 }
198 else
199 {
200 message (D_ERROR, learn_title, "%s",
201 _
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 int bx0, bx1;
260 const char *b0 = N_("&Save");
261 const char *b1 = N_("&Cancel");
262 int bl0, bl1;
263
264 int x, y, i;
265 const key_code_name_t *key;
266
267 #ifdef ENABLE_NLS
268 static gboolean i18n_flag = FALSE;
269 if (!i18n_flag)
270 {
271 learn_title = _(learn_title);
272 i18n_flag = TRUE;
273 }
274
275 b0 = _(b0);
276 b1 = _(b1);
277 #endif
278
279 do_refresh ();
280
281 learn_dlg =
282 dlg_create (TRUE, 0, 0, dlg_height, dlg_width, WPOS_CENTER, FALSE, dialog_colors,
283 learn_callback, NULL, "[Learn keys]", learn_title);
284 g = GROUP (learn_dlg);
285
286
287 for (key = key_name_conv_tab, learn_total = 0;
288 key->name != NULL && strcmp (key->name, "kpleft") != 0; key++, learn_total++)
289 ;
290
291 learnok = 0;
292 learnchanged = FALSE;
293
294 learnkeys = g_new (learnkey_t, learn_total);
295
296 x = UX;
297 y = UY;
298
299
300 for (i = 0; i < learn_total; i++)
301 {
302 char buffer[BUF_TINY];
303 const char *label;
304 int padding;
305
306 learnkeys[i].ok = FALSE;
307 learnkeys[i].sequence = NULL;
308
309 label = _(key_name_conv_tab[i].longname);
310 padding = 16 - str_term_width1 (label);
311 padding = MAX (0, padding);
312 g_snprintf (buffer, sizeof (buffer), "%s%*s", label, padding, "");
313
314 learnkeys[i].button =
315 WIDGET (button_new (y, x, B_USER + i, NARROW_BUTTON, buffer, learn_button));
316 learnkeys[i].label = WIDGET (label_new (y, x + 19, NULL));
317 group_add_widget (g, learnkeys[i].button);
318 group_add_widget (g, learnkeys[i].label);
319
320 y++;
321 if (y == UY + ROWS)
322 {
323 x += COLSHIFT;
324 y = UY;
325 }
326 }
327
328 group_add_widget (g, hline_new (dlg_height - 8, -1, -1));
329 group_add_widget (g, label_new (dlg_height - 7, 5,
330 _
331 ("Press all the keys mentioned here. After you have done it, check\n"
332 "which keys are not marked with OK. Press space on the missing\n"
333 "key, or click with the mouse to define it. Move around with Tab.")));
334 group_add_widget (g, hline_new (dlg_height - 4, -1, -1));
335
336 bl0 = str_term_width1 (b0) + 5;
337 bl1 = str_term_width1 (b1) + 3;
338 bx0 = (dlg_width - (bl0 + bl1 + 1)) / 2;
339 bx1 = bx0 + bl0 + 1;
340 group_add_widget (g, button_new (dlg_height - 3, bx0, B_ENTER, DEFPUSH_BUTTON, b0, NULL));
341 group_add_widget (g, button_new (dlg_height - 3, bx1, B_CANCEL, NORMAL_BUTTON, b1, NULL));
342 }
343
344
345
346 static void
347 learn_done (void)
348 {
349 widget_destroy (WIDGET (learn_dlg));
350 repaint_screen ();
351 }
352
353
354
355 static void
356 learn_save (void)
357 {
358 int i;
359 char *section;
360 gboolean profile_changed = FALSE;
361
362 section = g_strconcat ("terminal:", getenv ("TERM"), (char *) NULL);
363
364 for (i = 0; i < learn_total; i++)
365 if (learnkeys[i].sequence != NULL)
366 {
367 char *esc_str;
368
369 esc_str = str_escape (learnkeys[i].sequence, -1, ";\\", TRUE);
370 mc_config_set_string_raw_value (mc_global.main_config, section,
371 key_name_conv_tab[i].name, esc_str);
372 g_free (esc_str);
373
374 profile_changed = TRUE;
375 }
376
377
378
379
380
381
382
383 if (profile_changed)
384 mc_config_save_file (mc_global.main_config, NULL);
385
386 g_free (section);
387 }
388
389
390
391
392
393 void
394 learn_keys (void)
395 {
396 gboolean save_old_esc_mode = old_esc_mode;
397 gboolean save_alternate_plus_minus = mc_global.tty.alternate_plus_minus;
398 int result;
399
400
401 old_esc_mode = 0;
402
403
404
405
406 mc_global.tty.alternate_plus_minus = TRUE;
407 application_keypad_mode ();
408
409 init_learn ();
410 result = dlg_run (learn_dlg);
411
412 old_esc_mode = save_old_esc_mode;
413 mc_global.tty.alternate_plus_minus = save_alternate_plus_minus;
414
415 if (!mc_global.tty.alternate_plus_minus)
416 numeric_keypad_mode ();
417
418 if (result == B_ENTER)
419 learn_save ();
420
421 learn_done ();
422 }
423
424