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 WDialog *query_dlg;
242 WGroup *g;
243 GPtrArray *buttons = NULL;
244 WButton *button;
245 int win_width = 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_list ap;
259
260 buttons = g_ptr_array_sized_new ((guint) count);
261
262 va_start (ap, count);
263 for (i = 0; i < count; i++)
264 {
265 const char *cp = va_arg (ap, char *);
266
267 button = button_new (1, 1, B_USER + i, NORMAL_BUTTON, cp, NULL);
268 win_width += button_get_width (button) + 1;
269 g_ptr_array_add (buttons, button);
270 }
271 va_end (ap);
272 }
273
274 const int header_cols = str_term_width1 (header);
275
276
277 str_msg_term_size (text, &lines, &cols);
278 cols = 6 + MAX (win_width, MAX (header_cols, cols));
279 lines += 4 + (count > 0 ? 2 : 0);
280
281
282 query_dlg = dlg_create (TRUE, 0, 0, lines, cols, pos_flags, FALSE, query_colors,
283 query_default_callback, NULL, "[QueryBox]", header);
284 g = GROUP (query_dlg);
285
286 if (count > 0)
287 {
288 WButton *defbutton = NULL;
289
290 group_add_widget_autopos (g, label_new (2, 3, text), WPOS_KEEP_TOP | WPOS_CENTER_HORZ,
291 NULL);
292 group_add_widget (g, hline_new (lines - 4, -1, -1));
293
294 cols = (cols - win_width - 2) / 2 + 2;
295
296 for (i = 0; i < count; i++)
297 {
298 button = BUTTON (g_ptr_array_index (buttons, i));
299 WIDGET (button)->rect.y = lines - 3;
300 WIDGET (button)->rect.x = cols;
301 group_add_widget (g, button);
302
303 cols += button_get_width (button) + 1;
304
305 if (i == sel_pos)
306 defbutton = button;
307 }
308
309 g_ptr_array_free (buttons, FALSE);
310
311
312 send_message (query_dlg, NULL, MSG_RESIZE, 0, NULL);
313
314 if (defbutton != NULL)
315 widget_select (WIDGET (defbutton));
316
317
318 switch (dlg_run (query_dlg))
319 {
320 case B_CANCEL:
321 break;
322 default:
323 result = query_dlg->ret_value - B_USER;
324 }
325
326
327 widget_destroy (WIDGET (query_dlg));
328 }
329 else
330 {
331 group_add_widget_autopos (g, label_new (2, 3, text), WPOS_KEEP_TOP | WPOS_CENTER_HORZ,
332 NULL);
333 group_add_widget (g, button_new (0, 0, 0, HIDDEN_BUTTON, "-", NULL));
334 last_query_dlg = query_dlg;
335 }
336 sel_pos = 0;
337 return result;
338 }
339
340
341
342 void
343 query_set_sel (int new_sel)
344 {
345 sel_pos = new_sel;
346 }
347
348
349
350
351
352
353
354 WDialog *
355 create_message (int flags, const char *title, const char *text, ...)
356 {
357 va_list args;
358 WDialog *d;
359 char *p;
360
361 va_start (args, text);
362 p = g_strdup_vprintf (text, args);
363 va_end (args);
364
365 query_dialog (title, p, flags, 0);
366 d = last_query_dlg;
367
368
369 send_message (d, NULL, MSG_RESIZE, 0, NULL);
370
371 dlg_init (d);
372 g_free (p);
373
374 return d;
375 }
376
377
378
379
380 void
381 message (int flags, const char *title, const char *text, ...)
382 {
383 char *p;
384 va_list ap;
385
386 va_start (ap, text);
387 p = g_strdup_vprintf (text, ap);
388 va_end (ap);
389
390 if (title == MSG_ERROR)
391 title = _ ("Error");
392
393 #ifdef ENABLE_BACKGROUND
394 if (mc_global.we_are_background)
395 {
396 union
397 {
398 void *p;
399 void (*f) (int, int *, char *, const char *);
400 } func;
401
402 func.f = bg_message;
403
404 wtools_parent_call (func.p, NULL, 3, sizeof (flags), &flags, strlen (title), title,
405 strlen (p), p);
406 }
407 else
408 #endif
409 query_dialog (title, p, flags, 1, _ ("&OK"));
410
411 g_free (p);
412 }
413
414
415
416
417 gboolean
418 mc_error_message (GError **mcerror, int *code)
419 {
420 if (mcerror == NULL || *mcerror == NULL)
421 return FALSE;
422
423 if ((*mcerror)->code == 0)
424 message (D_ERROR, MSG_ERROR, "%s", (*mcerror)->message);
425 else
426 message (D_ERROR, MSG_ERROR, _ ("%s (%d)"), (*mcerror)->message, (*mcerror)->code);
427
428 if (code != NULL)
429 *code = (*mcerror)->code;
430
431 g_error_free (*mcerror);
432 *mcerror = NULL;
433
434 return TRUE;
435 }
436
437
438
439
440
441
442
443
444
445 char *
446 input_dialog_help (const char *header, const char *text, const char *help, const char *history_name,
447 const char *def_text, gboolean strip_password, 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 (
460 func.p, 7, strlen (header), header, strlen (text), text, strlen (help), help,
461 strlen (history_name), history_name, strlen (def_text), def_text, sizeof (gboolean),
462 strip_password, sizeof (input_complete_t), completion_flags);
463 }
464 else
465 #endif
466 return fg_input_dialog_help (header, text, help, history_name, def_text, strip_password,
467 completion_flags);
468 }
469
470
471
472
473 char *
474 input_dialog (const char *header, const char *text, const char *history_name, const char *def_text,
475 input_complete_t completion_flags)
476 {
477 return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text, FALSE,
478 completion_flags);
479 }
480
481
482
483 char *
484 input_expand_dialog (const char *header, const char *text, const char *history_name,
485 const char *def_text, input_complete_t completion_flags)
486 {
487 char *result;
488
489 result = input_dialog (header, text, history_name, def_text, completion_flags);
490 if (result)
491 {
492 char *expanded;
493
494 expanded = tilde_expand (result);
495 g_free (result);
496 return expanded;
497 }
498 return result;
499 }
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514 status_msg_t *
515 status_msg_create (const char *title, double delay, status_msg_cb init_cb,
516 status_msg_update_cb update_cb, status_msg_cb deinit_cb)
517 {
518 status_msg_t *sm;
519
520 sm = g_try_new (status_msg_t, 1);
521 status_msg_init (sm, title, delay, init_cb, update_cb, deinit_cb);
522
523 return sm;
524 }
525
526
527
528
529
530
531
532
533 void
534 status_msg_destroy (status_msg_t *sm)
535 {
536 status_msg_deinit (sm);
537 g_free (sm);
538 }
539
540
541
542
543
544
545
546
547
548
549
550
551
552 void
553 status_msg_init (status_msg_t *sm, const char *title, double delay, status_msg_cb init_cb,
554 status_msg_update_cb update_cb, status_msg_cb deinit_cb)
555 {
556 gint64 start;
557
558
559 mc_refresh ();
560
561 start = g_get_monotonic_time ();
562
563 sm->dlg = dlg_create (TRUE, 0, 0, 7, MIN (MAX (40, COLS / 2), COLS), WPOS_CENTER, FALSE,
564 dialog_colors, NULL, NULL, NULL, title);
565 sm->start = start;
566 sm->delay = (gint64) (delay * G_USEC_PER_SEC);
567 sm->block = FALSE;
568
569 sm->init = init_cb;
570 sm->update = update_cb;
571 sm->deinit = deinit_cb;
572
573 if (sm->init != NULL)
574 sm->init (sm);
575
576 if (mc_time_elapsed (&start, sm->delay))
577 {
578
579 dlg_init (sm->dlg);
580 }
581 }
582
583
584
585
586
587
588
589
590 void
591 status_msg_deinit (status_msg_t *sm)
592 {
593 if (sm == NULL)
594 return;
595
596 if (sm->deinit != NULL)
597 sm->deinit (sm);
598
599
600 dlg_run_done (sm->dlg);
601 widget_destroy (WIDGET (sm->dlg));
602 }
603
604
605
606
607
608
609
610
611
612
613 int
614 status_msg_common_update (status_msg_t *sm)
615 {
616 int c;
617 Gpm_Event event;
618
619 if (sm == NULL)
620 return B_ENTER;
621
622
623 if (sm->dlg == NULL)
624 return B_ENTER;
625
626 if (widget_get_state (WIDGET (sm->dlg), WST_CONSTRUCT))
627 {
628
629
630
631 gint64 start = sm->start;
632
633 if (mc_time_elapsed (&start, sm->delay))
634 dlg_init (sm->dlg);
635
636 return B_ENTER;
637 }
638
639 event.x = -1;
640 c = tty_get_event (&event, FALSE, sm->block);
641 if (c == EV_NONE)
642 return B_ENTER;
643
644
645
646 sm->dlg->ret_value = B_ENTER;
647 dlg_process_event (sm->dlg, c, &event);
648
649 return sm->dlg->ret_value;
650 }
651
652
653
654
655
656
657
658
659 void
660 simple_status_msg_init_cb (status_msg_t *sm)
661 {
662 simple_status_msg_t *ssm = SIMPLE_STATUS_MSG (sm);
663 Widget *wd = WIDGET (sm->dlg);
664 WGroup *wg = GROUP (sm->dlg);
665 WRect r;
666
667 const char *b_name = N_ ("&Abort");
668 int b_width;
669 int wd_width, y;
670 Widget *b;
671
672 #ifdef ENABLE_NLS
673 b_name = _ (b_name);
674 #endif
675
676 b_width = str_term_width1 (b_name) + 4;
677 wd_width = MAX (wd->rect.cols, b_width + 6);
678
679 y = 2;
680 ssm->label = label_new (y++, 3, NULL);
681 group_add_widget_autopos (wg, ssm->label, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
682 group_add_widget (wg, hline_new (y++, -1, -1));
683 b = WIDGET (button_new (y++, 3, B_CANCEL, NORMAL_BUTTON, b_name, NULL));
684 group_add_widget_autopos (wg, b, WPOS_KEEP_TOP | WPOS_CENTER_HORZ, NULL);
685
686 r = wd->rect;
687 r.lines = y + 2;
688 r.cols = wd_width;
689 widget_set_size_rect (wd, &r);
690 }
691
692