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 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 = 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 (
329 g,
330 label_new (dlg_height - 7, 5,
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