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