This source file includes following definitions.
- query_default_callback
- bg_message
- fg_input_dialog_help
- wtools_parent_call
- wtools_parent_call_string
- query_dialog
- query_set_sel
- create_message
- message
- mc_error_message
- input_dialog_help
- input_dialog
- input_expand_dialog
- status_msg_create
- status_msg_destroy
- status_msg_init
- status_msg_deinit
- status_msg_common_update
- simple_status_msg_init_cb
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
32
33
34 #include <config.h>
35
36 #include <stdarg.h>
37 #include <stdlib.h>
38
39 #include "lib/global.h"
40 #include "lib/tty/tty.h"
41 #include "lib/tty/key.h"
42 #include "lib/strutil.h"
43 #include "lib/util.h"
44 #include "lib/widget.h"
45 #include "lib/event.h"
46
47
48
49
50
51
52
53
54
55
56
57 static WDialog *last_query_dlg;
58
59 static int sel_pos = 0;
60
61
62
63
64
65
66
67 static cb_ret_t
68 query_default_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
69 {
70 WDialog *h = DIALOG (w);
71
72 switch (msg)
73 {
74 case MSG_RESIZE:
75 if ((w->pos_flags & WPOS_CENTER) == 0)
76 {
77 WDialog *prev_dlg = NULL;
78 int ypos, xpos;
79 WRect r;
80
81
82 if (top_dlg != NULL)
83 {
84 if (top_dlg->data != (void *) h)
85 prev_dlg = DIALOG (top_dlg->data);
86 else
87 {
88 GList *p;
89
90
91
92 p = g_list_next (top_dlg);
93 if (p != NULL)
94 prev_dlg = DIALOG (p->data);
95 }
96 }
97
98
99 if (prev_dlg == NULL || (WIDGET (prev_dlg)->pos_flags & WPOS_FULLSCREEN) != 0)
100 ypos = LINES / 3 - (w->rect.lines - 3) / 2;
101 else
102 ypos = WIDGET (prev_dlg)->rect.y + 2;
103
104
105 if (ypos + w->rect.lines < LINES / 2)
106 w->pos_flags |= WPOS_CENTER;
107
108 xpos = COLS / 2 - w->rect.cols / 2;
109
110
111 rect_init (&r, ypos, xpos, w->rect.lines, w->rect.cols);
112
113 return dlg_default_callback (w, NULL, MSG_RESIZE, 0, &r);
114 }
115 MC_FALLTHROUGH;
116
117 default:
118 return dlg_default_callback (w, sender, msg, parm, data);
119 }
120 }
121
122
123
124
125 #ifdef ENABLE_BACKGROUND
126 static void
127 bg_message (int dummy, int *flags, char *title, const char *text)
128 {
129 (void) dummy;
130 title = g_strconcat (_ ("Background process:"), " ", title, (char *) NULL);
131 query_dialog (title, text, *flags, 1, _ ("&OK"));
132 g_free (title);
133 }
134 #endif
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149 static char *
150 fg_input_dialog_help (const char *header, const char *text, const char *help,
151 const char *history_name, const char *def_text, gboolean strip_password,
152 input_complete_t completion_flags)
153 {
154 char *p_text;
155 char histname[BUF_TINY] = "inp|";
156 gboolean is_passwd = FALSE;
157 char *my_str = NULL;
158
159
160 p_text = g_strstrip (g_strdup (text));
161
162
163 if (history_name != NULL && *history_name != '\0')
164 g_strlcpy (histname + 3, history_name, sizeof (histname) - 3);
165
166
167
168 if (def_text == INPUT_PASSWORD)
169 {
170 is_passwd = TRUE;
171 histname[3] = '\0';
172 def_text = "";
173 }
174
175 quick_widget_t quick_widgets[] = {
176 QUICK_LABELED_INPUT (p_text, input_label_above, def_text, histname, &my_str, NULL,
177 is_passwd, strip_password, completion_flags),
178 QUICK_BUTTONS_OK_CANCEL,
179 QUICK_END,
180 };
181
182 WRect r = { -1, -1, 0, COLS / 2 };
183
184 quick_dialog_t qdlg = {
185 .rect = r,
186 .title = header,
187 .help = help,
188 .widgets = quick_widgets,
189 .callback = NULL,
190 .mouse_callback = NULL,
191 };
192
193 const int ret = quick_dialog (&qdlg);
194
195 g_free (p_text);
196
197 return (ret != B_CANCEL) ? my_str : NULL;
198 }
199
200
201
202 #ifdef ENABLE_BACKGROUND
203 static int
204 wtools_parent_call (void *routine, gpointer ctx, int argc, ...)
205 {
206 ev_background_parent_call_t event_data;
207
208 event_data.routine = routine;
209 event_data.ctx = ctx;
210 event_data.argc = argc;
211 va_start (event_data.ap, argc);
212 mc_event_raise (MCEVENT_GROUP_CORE, "background_parent_call", (gpointer) &event_data);
213 va_end (event_data.ap);
214 return event_data.ret.i;
215 }
216
217
218
219 static char *
220 wtools_parent_call_string (void *routine, int argc, ...)
221 {
222 ev_background_parent_call_t event_data;
223
224 event_data.routine = routine;
225 event_data.argc = argc;
226 va_start (event_data.ap, argc);
227 mc_event_raise (MCEVENT_GROUP_CORE, "background_parent_call_string", (gpointer) &event_data);
228 va_end (event_data.ap);
229 return event_data.ret.s;
230 }
231 #endif
232
233
234
235
236
237
238 int
239 query_dialog (const char *header, const char *text, int flags, int count, ...)
240 {
241 va_list ap;
242 WDialog *query_dlg;
243 WGroup *g;
244 WButton *button;
245 int win_len = 0;
246 int i;
247 int result = -1;
248 int cols, lines;
249 const int *query_colors = (flags & D_ERROR) != 0 ? alarm_colors : dialog_colors;
250 widget_pos_flags_t pos_flags =
251 (flags & D_CENTER) != 0 ? (WPOS_CENTER | WPOS_TRYUP) : WPOS_KEEP_DEFAULT;
252
253 if (header == MSG_ERROR)
254 header = _ ("Error");
255
256 if (count > 0)
257 {
258 va_start (ap, count);
259 for (i = 0; i < count; i++)
260 {
261 char *cp = va_arg (ap, char *);
262
263 win_len += str_term_width1 (cp) + 6;
264 if (strchr (cp, '&') != NULL)
265 win_len--;
266 }
267 va_end (ap);
268 }
269
270
271 str_msg_term_size (text, &lines, &cols);
272 cols = 6 + MAX (win_len, MAX (str_term_width1 (header), cols));
273 lines += 4 + (count > 0 ? 2 : 0);
274
275
276 query_dlg = dlg_create (TRUE, 0, 0, lines, cols, pos_flags, FALSE, query_colors,
277 query_default_callback, NULL, "[QueryBox]", header);
278 g = GROUP (query_dlg);
279
280 if (count > 0)
281 {
282 WButton *defbutton = NULL;
283
284 group_add_widget_autopos (g, label_new (2, 3, text), WPOS_KEEP_TOP | WPOS_CENTER_HORZ,
285 NULL);
286 group_add_widget (g, hline_new (lines - 4, -1, -1));
287
288 cols = (cols - win_len - 2) / 2 + 2;
289 va_start (ap, count);
290 for (i = 0; i < count; i++)
291 {
292 int xpos;
293 char *cur_name;
294
295 cur_name = va_arg (ap, char *);
296 xpos = str_term_width1 (cur_name) + 6;
297 if (strchr (cur_name, '&') != NULL)
298 xpos--;
299
300 button = button_new (lines - 3, cols, B_USER + i, NORMAL_BUTTON, cur_name, NULL);
301 group_add_widget (g, button);
302 cols += xpos;
303 if (i == sel_pos)
304 defbutton = button;
305 }
306 va_end (ap);
307
308
309 send_message (query_dlg, NULL, MSG_RESIZE, 0, NULL);
310
311 if (defbutton != NULL)
312 widget_select (WIDGET (defbutton));
313
314
315 switch (dlg_run (query_dlg))
316 {
317 case B_CANCEL:
318 break;
319 default:
320 result = query_dlg->ret_value - B_USER;
321 }
322
323
324 widget_destroy (WIDGET (query_dlg));
325 }
326 else
327 {
328 group_add_widget_autopos (g, label_new (2, 3, text), WPOS_KEEP_TOP | WPOS_CENTER_HORZ,
329 NULL);
330 group_add_widget (g, button_new (0, 0, 0, HIDDEN_BUTTON, "-", NULL));
331 last_query_dlg = query_dlg;
332 }
333 sel_pos = 0;
334 return result;
335 }
336
337
338
339 void
340 query_set_sel (int new_sel)
341 {
342 sel_pos = new_sel;
343 }
344
345
346
347
348
349
350
351 WDialog *
352 create_message (int flags, const char *title, const char *text, ...)
353 {
354 va_list args;
355 WDialog *d;
356 char *p;
357
358 va_start (args, text);
359 p = g_strdup_vprintf (text, args);
360 va_end (args);
361
362 query_dialog (title, p, flags, 0);
363 d = last_query_dlg;
364
365
366 send_message (d, NULL, MSG_RESIZE, 0, NULL);
367
368 dlg_init (d);
369 g_free (p);
370
371 return d;
372 }
373
374
375
376
377 void
378 message (int flags, const char *title, const char *text, ...)
379 {
380 char *p;
381 va_list ap;
382
383 va_start (ap, text);
384 p = g_strdup_vprintf (text, ap);
385 va_end (ap);
386
387 if (title == MSG_ERROR)
388 title = _ ("Error");
389
390 #ifdef ENABLE_BACKGROUND
391 if (mc_global.we_are_background)
392 {
393 union
394 {
395 void *p;
396 void (*f) (int, int *, char *, const char *);
397 } func;
398
399 func.f = bg_message;
400
401 wtools_parent_call (func.p, NULL, 3, sizeof (flags), &flags, strlen (title), title,
402 strlen (p), p);
403 }
404 else
405 #endif
406 query_dialog (title, p, flags, 1, _ ("&OK"));
407
408 g_free (p);
409 }
410
411
412
413
414 gboolean
415 mc_error_message (GError **mcerror, int *code)
416 {
417 if (mcerror == NULL || *mcerror == NULL)
418 return FALSE;
419
420 if ((*mcerror)->code == 0)
421 message (D_ERROR, MSG_ERROR, "%s", (*mcerror)->message);
422 else
423 message (D_ERROR, MSG_ERROR, _ ("%s (%d)"), (*mcerror)->message, (*mcerror)->code);
424
425 if (code != NULL)
426 *code = (*mcerror)->code;
427
428 g_error_free (*mcerror);
429 *mcerror = NULL;
430
431 return TRUE;
432 }
433
434
435
436
437
438
439
440
441
442 char *
443 input_dialog_help (const char *header, const char *text, const char *help, const char *history_name,
444 const char *def_text, gboolean strip_password, input_complete_t completion_flags)
445 {
446 #ifdef ENABLE_BACKGROUND
447 if (mc_global.we_are_background)
448 {
449 union
450 {
451 void *p;
452 char *(*f) (const char *, const char *, const char *, const char *, const char *,
453 gboolean, input_complete_t);
454 } func;
455 func.f = fg_input_dialog_help;
456 return wtools_parent_call_string (
457 func.p, 7, strlen (header), header, strlen (text), text, strlen (help), help,
458 strlen (history_name), history_name, strlen (def_text), def_text, sizeof (gboolean),
459 strip_password, sizeof (input_complete_t), completion_flags);
460 }
461 else
462 #endif
463 return fg_input_dialog_help (header, text, help, history_name, def_text, strip_password,
464 completion_flags);
465 }
466
467
468
469
470 char *
471 input_dialog (const char *header, const char *text, const char *history_name, const char *def_text,
472 input_complete_t completion_flags)
473 {
474 return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text, FALSE,
475 completion_flags);
476 }
477
478
479
480 char *
481 input_expand_dialog (const char *header, const char *text, const char *history_name,
482 const char *def_text, input_complete_t completion_flags)
483 {
484 char *result;
485
486 result = input_dialog (header, text, history_name, def_text, completion_flags);
487 if (result)
488 {
489 char *expanded;
490
491 expanded = tilde_expand (result);
492 g_free (result);
493 return expanded;
494 }
495 return result;
496 }
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511 status_msg_t *
512 status_msg_create (const char *title, double delay, status_msg_cb init_cb,
513 status_msg_update_cb update_cb, status_msg_cb deinit_cb)
514 {
515 status_msg_t *sm;
516
517 sm = g_try_new (status_msg_t, 1);
518 status_msg_init (sm, title, delay, init_cb, update_cb, deinit_cb);
519
520 return sm;
521 }
522
523
524
525
526
527
528
529
530 void
531 status_msg_destroy (status_msg_t *sm)
532 {
533 status_msg_deinit (sm);
534 g_free (sm);
535 }
536
537
538
539
540
541
542
543
544
545
546
547
548
549 void
550 status_msg_init (status_msg_t *sm, const char *title, double delay, status_msg_cb init_cb,
551 status_msg_update_cb update_cb, status_msg_cb deinit_cb)
552 {
553 gint64 start;
554
555
556 mc_refresh ();
557
558 start = g_get_monotonic_time ();
559
560 sm->dlg = dlg_create (TRUE, 0, 0, 7, MIN (MAX (40, COLS / 2), COLS), WPOS_CENTER, FALSE,
561 dialog_colors, NULL, NULL, NULL, title);
562 sm->start = start;
563 sm->delay = (gint64) (delay * G_USEC_PER_SEC);
564 sm->block = FALSE;
565
566 sm->init = init_cb;
567 sm->update = update_cb;
568 sm->deinit = deinit_cb;
569
570 if (sm->init != NULL)
571 sm->init (sm);
572
573 if (mc_time_elapsed (&start, sm->delay))
574 {
575
576 dlg_init (sm->dlg);
577 }
578 }
579
580
581
582
583
584
585
586
587 void
588 status_msg_deinit (status_msg_t *sm)
589 {
590 if (sm == NULL)
591 return;
592
593 if (sm->deinit != NULL)
594 sm->deinit (sm);
595
596
597 dlg_run_done (sm->dlg);
598 widget_destroy (WIDGET (sm->dlg));
599 }
600
601
602
603
604
605
606
607
608
609
610 int
611 status_msg_common_update (status_msg_t *sm)
612 {
613 int c;
614 Gpm_Event event;
615
616 if (sm == NULL)
617 return B_ENTER;
618
619
620 if (sm->dlg == NULL)
621 return B_ENTER;
622
623 if (widget_get_state (WIDGET (sm->dlg), WST_CONSTRUCT))
624 {
625
626
627
628 gint64 start = sm->start;
629
630 if (mc_time_elapsed (&start, sm->delay))
631 dlg_init (sm->dlg);
632
633 return B_ENTER;
634 }
635
636 event.x = -1;
637 c = tty_get_event (&event, FALSE, sm->block);
638 if (c == EV_NONE)
639 return B_ENTER;
640
641
642
643 sm->dlg->ret_value = B_ENTER;
644 dlg_process_event (sm->dlg, c, &event);
645
646 return sm->dlg->ret_value;
647 }
648
649
650
651
652
653
654
655
656 void
657 simple_status_msg_init_cb (status_msg_t *sm)
658 {
659 simple_status_msg_t *ssm = SIMPLE_STATUS_MSG (sm);
660 Widget *wd = WIDGET (sm->dlg);
661 WGroup *wg = GROUP (sm->dlg);
662 WRect r;
663
664 const char *b_name = N_ ("&Abort");
665 int b_width;
666 int wd_width, y;
667 Widget *b;
668
669 #ifdef ENABLE_NLS
670 b_name = _ (b_name);
671 #endif
672
673 b_width = str_term_width1 (b_name) + 4;
674 wd_width = MAX (wd->rect.cols, b_width + 6);
675
676 y = 2;
677 ssm->label = label_new (y++, 3, NULL);
678 group_add_widget_autopos (wg, ssm->label, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
679 group_add_widget (wg, hline_new (y++, -1, -1));
680 b = WIDGET (button_new (y++, 3, B_CANCEL, NORMAL_BUTTON, b_name, NULL));
681 group_add_widget_autopos (wg, b, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
682
683 r = wd->rect;
684 r.lines = y + 2;
685 r.cols = wd_width;
686 widget_set_size_rect (wd, &r);
687 }
688
689