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[64] = "inp|";
156 gboolean is_passwd = FALSE;
157 char *my_str = NULL;
158 int ret;
159
160
161 p_text = g_strstrip (g_strdup (text));
162
163
164 if (history_name != NULL && *history_name != '\0')
165 g_strlcpy (histname + 3, history_name, sizeof (histname) - 3);
166
167
168
169 if (def_text == INPUT_PASSWORD)
170 {
171 is_passwd = TRUE;
172 histname[3] = '\0';
173 def_text = "";
174 }
175
176 {
177 quick_widget_t quick_widgets[] = {
178
179 QUICK_LABELED_INPUT (p_text, input_label_above, def_text, histname, &my_str,
180 NULL, is_passwd, strip_password, completion_flags),
181 QUICK_BUTTONS_OK_CANCEL,
182 QUICK_END
183
184 };
185
186 WRect r = { -1, -1, 0, COLS / 2 };
187
188 quick_dialog_t qdlg = {
189 r, header, help,
190 quick_widgets, NULL, NULL
191 };
192
193 ret = quick_dialog (&qdlg);
194 }
195
196 g_free (p_text);
197
198 return (ret != B_CANCEL) ? my_str : NULL;
199 }
200
201
202
203 #ifdef ENABLE_BACKGROUND
204 static int
205 wtools_parent_call (void *routine, gpointer ctx, int argc, ...)
206 {
207 ev_background_parent_call_t event_data;
208
209 event_data.routine = routine;
210 event_data.ctx = ctx;
211 event_data.argc = argc;
212 va_start (event_data.ap, argc);
213 mc_event_raise (MCEVENT_GROUP_CORE, "background_parent_call", (gpointer) & event_data);
214 va_end (event_data.ap);
215 return event_data.ret.i;
216 }
217
218
219
220 static char *
221 wtools_parent_call_string (void *routine, int argc, ...)
222 {
223 ev_background_parent_call_t event_data;
224
225 event_data.routine = routine;
226 event_data.argc = argc;
227 va_start (event_data.ap, argc);
228 mc_event_raise (MCEVENT_GROUP_CORE, "background_parent_call_string", (gpointer) & event_data);
229 va_end (event_data.ap);
230 return event_data.ret.s;
231 }
232 #endif
233
234
235
236
237
238
239 int
240 query_dialog (const char *header, const char *text, int flags, int count, ...)
241 {
242 va_list ap;
243 WDialog *query_dlg;
244 WGroup *g;
245 WButton *button;
246 int win_len = 0;
247 int i;
248 int result = -1;
249 int cols, lines;
250 const int *query_colors = (flags & D_ERROR) != 0 ? alarm_colors : dialog_colors;
251 widget_pos_flags_t pos_flags =
252 (flags & D_CENTER) != 0 ? (WPOS_CENTER | WPOS_TRYUP) : WPOS_KEEP_DEFAULT;
253
254 if (header == MSG_ERROR)
255 header = _("Error");
256
257 if (count > 0)
258 {
259 va_start (ap, count);
260 for (i = 0; i < count; i++)
261 {
262 char *cp = va_arg (ap, char *);
263
264 win_len += str_term_width1 (cp) + 6;
265 if (strchr (cp, '&') != NULL)
266 win_len--;
267 }
268 va_end (ap);
269 }
270
271
272 str_msg_term_size (text, &lines, &cols);
273 cols = 6 + MAX (win_len, MAX (str_term_width1 (header), cols));
274 lines += 4 + (count > 0 ? 2 : 0);
275
276
277 query_dlg =
278 dlg_create (TRUE, 0, 0, lines, cols, pos_flags, FALSE, query_colors, query_default_callback,
279 NULL, "[QueryBox]", header);
280 g = GROUP (query_dlg);
281
282 if (count > 0)
283 {
284 WButton *defbutton = NULL;
285
286 group_add_widget_autopos (g, label_new (2, 3, text), WPOS_KEEP_TOP | WPOS_CENTER_HORZ,
287 NULL);
288 group_add_widget (g, hline_new (lines - 4, -1, -1));
289
290 cols = (cols - win_len - 2) / 2 + 2;
291 va_start (ap, count);
292 for (i = 0; i < count; i++)
293 {
294 int xpos;
295 char *cur_name;
296
297 cur_name = va_arg (ap, char *);
298 xpos = str_term_width1 (cur_name) + 6;
299 if (strchr (cur_name, '&') != NULL)
300 xpos--;
301
302 button = button_new (lines - 3, cols, B_USER + i, NORMAL_BUTTON, cur_name, NULL);
303 group_add_widget (g, button);
304 cols += xpos;
305 if (i == sel_pos)
306 defbutton = button;
307 }
308 va_end (ap);
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,
446 const char *history_name, const char *def_text, gboolean strip_password,
447 input_complete_t completion_flags)
448 {
449 #ifdef ENABLE_BACKGROUND
450 if (mc_global.we_are_background)
451 {
452 union
453 {
454 void *p;
455 char *(*f) (const char *, const char *, const char *, const char *, const char *,
456 gboolean, input_complete_t);
457 } func;
458 func.f = fg_input_dialog_help;
459 return wtools_parent_call_string (func.p, 7,
460 strlen (header), header, strlen (text),
461 text, strlen (help), help,
462 strlen (history_name), history_name,
463 strlen (def_text), def_text,
464 sizeof (gboolean), strip_password,
465 sizeof (input_complete_t), completion_flags);
466 }
467 else
468 #endif
469 return fg_input_dialog_help (header, text, help, history_name, def_text, strip_password,
470 completion_flags);
471 }
472
473
474
475
476 char *
477 input_dialog (const char *header, const char *text, const char *history_name, const char *def_text,
478 input_complete_t completion_flags)
479 {
480 return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text, FALSE,
481 completion_flags);
482 }
483
484
485
486 char *
487 input_expand_dialog (const char *header, const char *text,
488 const char *history_name, const char *def_text,
489 input_complete_t completion_flags)
490 {
491 char *result;
492
493 result = input_dialog (header, text, history_name, def_text, completion_flags);
494 if (result)
495 {
496 char *expanded;
497
498 expanded = tilde_expand (result);
499 g_free (result);
500 return expanded;
501 }
502 return result;
503 }
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518 status_msg_t *
519 status_msg_create (const char *title, double delay, status_msg_cb init_cb,
520 status_msg_update_cb update_cb, status_msg_cb deinit_cb)
521 {
522 status_msg_t *sm;
523
524 sm = g_try_new (status_msg_t, 1);
525 status_msg_init (sm, title, delay, init_cb, update_cb, deinit_cb);
526
527 return sm;
528 }
529
530
531
532
533
534
535
536
537 void
538 status_msg_destroy (status_msg_t *sm)
539 {
540 status_msg_deinit (sm);
541 g_free (sm);
542 }
543
544
545
546
547
548
549
550
551
552
553
554
555
556 void
557 status_msg_init (status_msg_t *sm, const char *title, double delay, status_msg_cb init_cb,
558 status_msg_update_cb update_cb, status_msg_cb deinit_cb)
559 {
560 gint64 start;
561
562
563 mc_refresh ();
564
565 start = g_get_monotonic_time ();
566
567 sm->dlg = dlg_create (TRUE, 0, 0, 7, MIN (MAX (40, COLS / 2), COLS), WPOS_CENTER, FALSE,
568 dialog_colors, NULL, NULL, NULL, title);
569 sm->start = start;
570 sm->delay = (gint64) (delay * G_USEC_PER_SEC);
571 sm->block = FALSE;
572
573 sm->init = init_cb;
574 sm->update = update_cb;
575 sm->deinit = deinit_cb;
576
577 if (sm->init != NULL)
578 sm->init (sm);
579
580 if (mc_time_elapsed (&start, sm->delay))
581 {
582
583 dlg_init (sm->dlg);
584 }
585 }
586
587
588
589
590
591
592
593
594 void
595 status_msg_deinit (status_msg_t *sm)
596 {
597 if (sm == NULL)
598 return;
599
600 if (sm->deinit != NULL)
601 sm->deinit (sm);
602
603
604 dlg_run_done (sm->dlg);
605 widget_destroy (WIDGET (sm->dlg));
606 }
607
608
609
610
611
612
613
614
615
616
617 int
618 status_msg_common_update (status_msg_t *sm)
619 {
620 int c;
621 Gpm_Event event;
622
623 if (sm == NULL)
624 return B_ENTER;
625
626
627 if (sm->dlg == NULL)
628 return B_ENTER;
629
630 if (widget_get_state (WIDGET (sm->dlg), WST_CONSTRUCT))
631 {
632
633
634
635 gint64 start = sm->start;
636
637 if (mc_time_elapsed (&start, sm->delay))
638 dlg_init (sm->dlg);
639
640 return B_ENTER;
641 }
642
643 event.x = -1;
644 c = tty_get_event (&event, FALSE, sm->block);
645 if (c == EV_NONE)
646 return B_ENTER;
647
648
649
650 sm->dlg->ret_value = B_ENTER;
651 dlg_process_event (sm->dlg, c, &event);
652
653 return sm->dlg->ret_value;
654 }
655
656
657
658
659
660
661
662
663 void
664 simple_status_msg_init_cb (status_msg_t *sm)
665 {
666 simple_status_msg_t *ssm = SIMPLE_STATUS_MSG (sm);
667 Widget *wd = WIDGET (sm->dlg);
668 WGroup *wg = GROUP (sm->dlg);
669 WRect r;
670
671 const char *b_name = N_("&Abort");
672 int b_width;
673 int wd_width, y;
674 Widget *b;
675
676 #ifdef ENABLE_NLS
677 b_name = _(b_name);
678 #endif
679
680 b_width = str_term_width1 (b_name) + 4;
681 wd_width = MAX (wd->rect.cols, b_width + 6);
682
683 y = 2;
684 ssm->label = label_new (y++, 3, NULL);
685 group_add_widget_autopos (wg, ssm->label, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
686 group_add_widget (wg, hline_new (y++, -1, -1));
687 b = WIDGET (button_new (y++, 3, B_CANCEL, NORMAL_BUTTON, b_name, NULL));
688 group_add_widget_autopos (wg, b, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
689
690 r = wd->rect;
691 r.lines = y + 2;
692 r.cols = wd_width;
693 widget_set_size_rect (wd, &r);
694 }
695
696