mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-22 03:02:06 +03:00
* dlg.h: Merge with ...
* dialog.h: ... this. Adjust all dependencies. * dlg.c: Merge with ... * dialog.c: ... this. * Makefile.am (SRCS): Remove dlg.h and dlg.c.
This commit is contained in:
parent
0ee63c1450
commit
98950838b4
@ -1,7 +1,7 @@
|
||||
#ifndef __EDIT_WIDGET_H
|
||||
#define __EDIT_WIDGET_H
|
||||
|
||||
#include "src/dlg.h" /* Widget */
|
||||
#include "src/dialog.h" /* Widget */
|
||||
|
||||
#define MAX_MACRO_LENGTH 1024
|
||||
#define N_LINE_CACHES 32
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "edit.h"
|
||||
#include "src/dlg.h" /* B_CANCEL */
|
||||
#include "src/dialog.h" /* B_CANCEL */
|
||||
#include "src/wtools.h" /* QuickDialog */
|
||||
|
||||
#define OPT_DLG_H 17
|
||||
|
@ -1,5 +1,11 @@
|
||||
2003-10-24 Pavel Roskin <proski@gnu.org>
|
||||
|
||||
* dlg.h: Merge with ...
|
||||
* dialog.h: ... this. Adjust all dependencies.
|
||||
* dlg.c: Merge with ...
|
||||
* dialog.c: ... this.
|
||||
* Makefile.am (SRCS): Remove dlg.h and dlg.c.
|
||||
|
||||
* dlg.h: Declare idle_hook here.
|
||||
|
||||
* dialog.c: Eliminate typedef Refresh, unneeded includes.
|
||||
|
@ -45,7 +45,7 @@ CHARSET_SRC = charsets.c charsets.h selcodepage.c selcodepage.h
|
||||
SRCS = achown.c achown.h background.c background.h boxes.c boxes.h \
|
||||
chmod.c chmod.h chown.c chown.h cmd.c cmd.h color.c color.h \
|
||||
command.c command.h complete.c complete.h cons.handler.c \
|
||||
cons.saver.h dialog.c dialog.h dir.c dir.h dlg.c dlg.h \
|
||||
cons.saver.h dialog.c dialog.h dir.c dir.h \
|
||||
eregex.h execute.c execute.h ext.c ext.h file.c filegui.c \
|
||||
filegui.h file.h filenot.c fileopctx.c fileopctx.h find.c \
|
||||
find.h findme.c findme.h fs.h fsusage.c fsusage.h \
|
||||
|
@ -31,9 +31,8 @@
|
||||
#include "tty.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "wtools.h" /* For init_box_colors() */
|
||||
#include "key.h" /* XCTRL and ALT macros */
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "wtools.h"
|
||||
|
||||
@ -45,7 +45,6 @@
|
||||
#ifdef WITH_BACKGROUND
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#include "dialog.h"
|
||||
#include "fileopctx.h"
|
||||
#include "key.h" /* For add_select_channel(), delete_select_channel() */
|
||||
#include "eregex.h"
|
||||
|
@ -31,9 +31,8 @@
|
||||
#include "tty.h"
|
||||
#include "win.h" /* Our window tools */
|
||||
#include "color.h" /* Color definitions */
|
||||
#include "dlg.h" /* The nice dialog manager */
|
||||
#include "dialog.h" /* The nice dialog manager */
|
||||
#include "widget.h" /* The widgets for the nice dialog manager */
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "wtools.h"
|
||||
#include "setup.h" /* For profile_name */
|
||||
#include "profile.h" /* Load/save user formats */
|
||||
|
@ -30,9 +30,8 @@
|
||||
#include "global.h"
|
||||
#include "tty.h" /* A_REVERSE */
|
||||
#include "color.h" /* dialog_colors */
|
||||
#include "dlg.h" /* add_widget() */
|
||||
#include "dialog.h" /* add_widget() */
|
||||
#include "widget.h" /* NORMAL_BUTTON */
|
||||
#include "dialog.h" /* do_refresh() */
|
||||
#include "wtools.h" /* message() */
|
||||
#include "panel.h" /* do_file_mark() */
|
||||
#include "main.h" /* update_panels() */
|
||||
|
@ -31,9 +31,8 @@
|
||||
#include "tty.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
|
||||
/* Needed for the extern declarations of integer parameters */
|
||||
#include "dir.h"
|
||||
|
@ -48,13 +48,12 @@
|
||||
#include "subshell.h" /* use_subshell */
|
||||
#include "cons.saver.h" /* console_flag */
|
||||
#include "tty.h" /* LINES */
|
||||
#include "dlg.h" /* Widget */
|
||||
#include "dialog.h" /* Widget */
|
||||
#include "view.h" /* view() */
|
||||
#include "wtools.h" /* message() */
|
||||
#include "widget.h" /* push_history() */
|
||||
#include "key.h" /* application_keypad_mode() */
|
||||
#include "win.h" /* do_enter_ca_mode() */
|
||||
#include "dialog.h" /* do_refresh() */
|
||||
#include "main.h" /* change_panel() */
|
||||
#include "panel.h" /* cpanel */
|
||||
#include "help.h" /* interactive_display() */
|
||||
|
@ -33,9 +33,8 @@
|
||||
#include "tty.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "wtools.h"
|
||||
#include "complete.h"
|
||||
#include "main.h"
|
||||
|
859
src/dialog.c
859
src/dialog.c
@ -1,5 +1,5 @@
|
||||
/* Dialog managing.
|
||||
Copyright (C) 1994 Miguel de Icaza.
|
||||
/* Dialog box features module for the Midnight Commander
|
||||
Copyright (C) 1994, 1995 Radek Doulik, Miguel de Icaza
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -13,15 +13,262 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "menu.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "mouse.h"
|
||||
#include "help.h"
|
||||
#include "key.h" /* For mi_getch() */
|
||||
#include "dialog.h"
|
||||
#include "key.h" /* we_are_background */
|
||||
#include "main.h" /* fast_refresh */
|
||||
#include "layout.h"
|
||||
#include "execute.h"
|
||||
#include "main.h"
|
||||
|
||||
#define waddc(w,y1,x1,c) move (w->y+y1, w->x+x1); addch (c)
|
||||
|
||||
/* Primitive way to check if the the current dialog is our dialog */
|
||||
/* This is needed by async routines like load_prompt */
|
||||
Dlg_head *current_dlg = 0;
|
||||
|
||||
/* A hook list for idle events */
|
||||
Hook *idle_hook = 0;
|
||||
|
||||
static void dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message,
|
||||
int reverse, int flags);
|
||||
|
||||
static void slow_box (Dlg_head *h, int y, int x, int ys, int xs)
|
||||
{
|
||||
move (h->y+y, h->x+x);
|
||||
hline (' ', xs);
|
||||
vline (' ', ys);
|
||||
move (h->y+y, h->x+x+xs-1);
|
||||
vline (' ', ys);
|
||||
move (h->y+y+ys-1, h->x+x);
|
||||
hline (' ', xs);
|
||||
}
|
||||
|
||||
/* draw box in window */
|
||||
void draw_box (Dlg_head *h, int y, int x, int ys, int xs)
|
||||
{
|
||||
if (slow_terminal){
|
||||
slow_box (h, y, x, ys, xs);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef HAVE_SLANG
|
||||
waddc (h, y, x, ACS_ULCORNER);
|
||||
hline (ACS_HLINE, xs - 2);
|
||||
waddc (h, y + ys - 1, x, ACS_LLCORNER);
|
||||
hline (ACS_HLINE, xs - 2);
|
||||
|
||||
waddc (h, y, x + xs - 1, ACS_URCORNER);
|
||||
waddc (h, y + ys - 1, x + xs - 1, ACS_LRCORNER);
|
||||
|
||||
move (h->y+y+1, h->x+x);
|
||||
vline (ACS_VLINE, ys - 2);
|
||||
move (h->y+y+1, h->x+x+xs-1);
|
||||
vline (ACS_VLINE, ys - 2);
|
||||
#else
|
||||
SLsmg_draw_box (h->y+y, h->x+x, ys, xs);
|
||||
#endif /* HAVE_SLANG */
|
||||
}
|
||||
|
||||
/* draw box in window */
|
||||
void draw_double_box (Dlg_head *h, int y, int x, int ys, int xs)
|
||||
{
|
||||
#ifndef HAVE_SLANG
|
||||
draw_box (h, y, x, ys, xs);
|
||||
#else
|
||||
SLsmg_draw_double_box (h->y+y, h->x+x, ys, xs);
|
||||
#endif /* HAVE_SLANG */
|
||||
}
|
||||
|
||||
void widget_erase (Widget *w)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < w->lines; y++){
|
||||
widget_move (w, y, 0);
|
||||
for (x = 0; x < w->cols; x++)
|
||||
addch (' ');
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_erase (Dlg_head *h)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < h->lines; y++){
|
||||
move (y+h->y, h->x); /* FIXME: should test if ERR */
|
||||
for (x = 0; x < h->cols; x++){
|
||||
addch (' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init_widget (Widget *w, int y, int x, int lines, int cols,
|
||||
callback_fn callback, mouse_h mouse_handler)
|
||||
{
|
||||
w->x = x;
|
||||
w->y = y;
|
||||
w->cols = cols;
|
||||
w->lines = lines;
|
||||
w->callback = callback;
|
||||
w->mouse = mouse_handler;
|
||||
w->parent = 0;
|
||||
|
||||
/* Almost all widgets want to put the cursor in a suitable place */
|
||||
w->options = W_WANT_CURSOR;
|
||||
}
|
||||
|
||||
/* Default callback for widgets */
|
||||
cb_ret_t
|
||||
default_proc (widget_msg_t msg, int parm)
|
||||
{
|
||||
switch (msg) {
|
||||
case WIDGET_INIT:
|
||||
case WIDGET_FOCUS:
|
||||
case WIDGET_UNFOCUS:
|
||||
case WIDGET_DRAW:
|
||||
case WIDGET_DESTROY:
|
||||
case WIDGET_CURSOR:
|
||||
case WIDGET_IDLE:
|
||||
return MSG_HANDLED;
|
||||
|
||||
default:
|
||||
return MSG_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean the dialog area, draw the frame and the title */
|
||||
void
|
||||
common_dialog_repaint (struct Dlg_head *h)
|
||||
{
|
||||
int space;
|
||||
|
||||
space = (h->flags & DLG_COMPACT) ? 0 : 1;
|
||||
|
||||
attrset (NORMALC);
|
||||
dlg_erase (h);
|
||||
draw_box (h, space, space, h->lines - 2 * space, h->cols - 2 * space);
|
||||
|
||||
if (h->title) {
|
||||
attrset (HOT_NORMALC);
|
||||
dlg_move (h, space, (h->cols - strlen (h->title)) / 2);
|
||||
addstr (h->title);
|
||||
}
|
||||
}
|
||||
|
||||
/* Default dialog callback */
|
||||
cb_ret_t default_dlg_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
||||
{
|
||||
if (msg == DLG_DRAW && h->color) {
|
||||
common_dialog_repaint (h);
|
||||
return MSG_HANDLED;
|
||||
}
|
||||
if (msg == DLG_IDLE){
|
||||
dlg_broadcast_msg_to (h, WIDGET_IDLE, 0, W_WANT_IDLE);
|
||||
return MSG_HANDLED;
|
||||
}
|
||||
return MSG_NOT_HANDLED;
|
||||
}
|
||||
|
||||
Dlg_head *
|
||||
create_dlg (int y1, int x1, int lines, int cols, const int *color_set,
|
||||
dlg_cb_fn callback, char *help_ctx, const char *title,
|
||||
int flags)
|
||||
{
|
||||
Dlg_head *new_d;
|
||||
|
||||
if (flags & DLG_CENTER) {
|
||||
y1 = (LINES - lines) / 2;
|
||||
x1 = (COLS - cols) / 2;
|
||||
}
|
||||
|
||||
if ((flags & DLG_TRYUP) && (y1 > 3))
|
||||
y1 -= 2;
|
||||
|
||||
new_d = g_new0 (Dlg_head, 1);
|
||||
new_d->color = color_set;
|
||||
new_d->help_ctx = help_ctx;
|
||||
new_d->callback = callback ? callback : default_dlg_callback;
|
||||
new_d->x = x1;
|
||||
new_d->y = y1;
|
||||
new_d->cols = cols;
|
||||
new_d->lines = lines;
|
||||
new_d->flags = flags;
|
||||
|
||||
/* Strip existing spaces, add one space before and after the title */
|
||||
if (title) {
|
||||
char *t;
|
||||
t = g_strstrip (g_strdup (title));
|
||||
new_d->title = g_strconcat (" ", t, " ", NULL);
|
||||
g_free (t);
|
||||
}
|
||||
|
||||
return (new_d);
|
||||
}
|
||||
|
||||
void
|
||||
set_idle_proc (Dlg_head *d, int enable)
|
||||
{
|
||||
if (enable)
|
||||
d->flags |= DLG_WANT_IDLE;
|
||||
else
|
||||
d->flags &= ~DLG_WANT_IDLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert widget to dialog before current widget. For dialogs populated
|
||||
* from the bottom, make the widget current. Return widget number.
|
||||
*/
|
||||
int
|
||||
add_widget (Dlg_head *h, void *w)
|
||||
{
|
||||
Widget *widget = (Widget *) w;
|
||||
|
||||
/* Don't accept 0 widgets, and running dialogs */
|
||||
if (!widget || h->running)
|
||||
abort ();
|
||||
|
||||
widget->x += h->x;
|
||||
widget->y += h->y;
|
||||
widget->parent = h;
|
||||
widget->dlg_id = h->count++;
|
||||
|
||||
if (h->current) {
|
||||
widget->next = h->current;
|
||||
widget->prev = h->current->prev;
|
||||
h->current->prev->next = widget;
|
||||
h->current->prev = widget;
|
||||
} else {
|
||||
widget->prev = widget;
|
||||
widget->next = widget;
|
||||
}
|
||||
|
||||
if ((h->flags & DLG_REVERSE) || !h->current)
|
||||
h->current = widget;
|
||||
|
||||
return widget->dlg_id;
|
||||
}
|
||||
|
||||
enum {
|
||||
REFRESH_COVERS_PART, /* If the refresh fn convers only a part */
|
||||
REFRESH_COVERS_ALL /* If the refresh fn convers all the screen */
|
||||
};
|
||||
|
||||
typedef void (*refresh_fn) (void *);
|
||||
|
||||
/* The refresh stack */
|
||||
struct Refresh {
|
||||
@ -33,7 +280,7 @@ struct Refresh {
|
||||
|
||||
static struct Refresh *refresh_list;
|
||||
|
||||
void
|
||||
static void
|
||||
push_refresh (refresh_fn new_refresh, void *parameter, int flags)
|
||||
{
|
||||
struct Refresh *new;
|
||||
@ -46,7 +293,7 @@ push_refresh (refresh_fn new_refresh, void *parameter, int flags)
|
||||
refresh_list = new;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
pop_refresh (void)
|
||||
{
|
||||
struct Refresh *old;
|
||||
@ -84,3 +331,601 @@ do_refresh (void)
|
||||
do_complete_refresh (refresh_list);
|
||||
}
|
||||
}
|
||||
|
||||
/* broadcast a message to all the widgets in a dialog that have
|
||||
* the options set to flags.
|
||||
*/
|
||||
static void
|
||||
dlg_broadcast_msg_to (Dlg_head *h, widget_msg_t message, int reverse,
|
||||
int flags)
|
||||
{
|
||||
Widget *p, *first, *wi;
|
||||
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
if (reverse)
|
||||
first = p = h->current->prev;
|
||||
else
|
||||
first = p = h->current->next;
|
||||
|
||||
do {
|
||||
wi = p;
|
||||
if (reverse)
|
||||
p = p->prev;
|
||||
else
|
||||
p = p->next;
|
||||
send_message (wi, message, 0);
|
||||
} while (first != p);
|
||||
}
|
||||
|
||||
/* broadcast a message to all the widgets in a dialog */
|
||||
void
|
||||
dlg_broadcast_msg (Dlg_head *h, widget_msg_t message, int reverse)
|
||||
{
|
||||
dlg_broadcast_msg_to (h, message, reverse, ~0);
|
||||
}
|
||||
|
||||
int dlg_focus (Dlg_head *h)
|
||||
{
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
if (send_message (h->current, WIDGET_FOCUS, 0)){
|
||||
(*h->callback) (h, DLG_FOCUS, 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dlg_unfocus (Dlg_head *h)
|
||||
{
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
if (send_message (h->current, WIDGET_UNFOCUS, 0)){
|
||||
(*h->callback) (h, DLG_UNFOCUS, 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
select_a_widget (Dlg_head *h, int down)
|
||||
{
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
do {
|
||||
if (down)
|
||||
h->current = h->current->next;
|
||||
else
|
||||
h->current = h->current->prev;
|
||||
} while (!dlg_focus (h));
|
||||
}
|
||||
|
||||
/* Return true if the windows overlap */
|
||||
int dlg_overlap (Widget *a, Widget *b)
|
||||
{
|
||||
if ((b->x >= a->x + a->cols)
|
||||
|| (a->x >= b->x + b->cols)
|
||||
|| (b->y >= a->y + a->lines)
|
||||
|| (a->y >= b->y + b->lines))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Find the widget with the given callback in the dialog h */
|
||||
Widget *
|
||||
find_widget_type (Dlg_head *h, void *callback)
|
||||
{
|
||||
Widget *w;
|
||||
Widget *item;
|
||||
int i;
|
||||
|
||||
if (!h)
|
||||
return 0;
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
w = 0;
|
||||
for (i = 0, item = h->current; i < h->count; i++, item = item->next) {
|
||||
if (item->callback == callback) {
|
||||
w = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
/* Find the widget with the given dialog id in the dialog h and select it */
|
||||
void
|
||||
dlg_select_by_id (Dlg_head *h, int id)
|
||||
{
|
||||
Widget *w, *w_found;
|
||||
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
w = h->current;
|
||||
w_found = NULL;
|
||||
|
||||
do {
|
||||
if (w->dlg_id == id) {
|
||||
w_found = w;
|
||||
break;
|
||||
}
|
||||
w = w->next;
|
||||
} while (w != h->current);
|
||||
|
||||
if (w_found)
|
||||
dlg_select_widget(h, w_found);
|
||||
}
|
||||
|
||||
void dlg_one_up (Dlg_head *h)
|
||||
{
|
||||
Widget *old;
|
||||
|
||||
old = h->current;
|
||||
|
||||
if (!old)
|
||||
return;
|
||||
|
||||
/* If it accepts unFOCUSion */
|
||||
if (!dlg_unfocus(h))
|
||||
return;
|
||||
|
||||
select_a_widget (h, 0);
|
||||
if (dlg_overlap (old, h->current)){
|
||||
send_message (h->current, WIDGET_DRAW, 0);
|
||||
send_message (h->current, WIDGET_FOCUS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_one_down (Dlg_head *h)
|
||||
{
|
||||
Widget *old;
|
||||
|
||||
old = h->current;
|
||||
if (!old)
|
||||
return;
|
||||
|
||||
if (!dlg_unfocus (h))
|
||||
return;
|
||||
|
||||
select_a_widget (h, 1);
|
||||
if (dlg_overlap (old, h->current)){
|
||||
send_message (h->current, WIDGET_DRAW, 0);
|
||||
send_message (h->current, WIDGET_FOCUS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int dlg_select_widget (Dlg_head *h, void *w)
|
||||
{
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
if (dlg_unfocus (h)){
|
||||
while (h->current != w)
|
||||
h->current = h->current->next;
|
||||
while (!dlg_focus (h))
|
||||
h->current = h->current->next;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define callback(h) (h->current->callback)
|
||||
|
||||
void update_cursor (Dlg_head *h)
|
||||
{
|
||||
if (!h->current)
|
||||
return;
|
||||
if (h->current->options & W_WANT_CURSOR)
|
||||
send_message (h->current, WIDGET_CURSOR, 0);
|
||||
else {
|
||||
Widget *p = h->current;
|
||||
|
||||
do {
|
||||
if (p->options & W_WANT_CURSOR)
|
||||
if ((*p->callback)(p, WIDGET_CURSOR, 0)){
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
} while (h->current != p);
|
||||
}
|
||||
}
|
||||
|
||||
/* Redraw the widgets in reverse order, leaving the current widget
|
||||
* as the last one
|
||||
*/
|
||||
void dlg_redraw (Dlg_head *h)
|
||||
{
|
||||
(h->callback)(h, DLG_DRAW, 0);
|
||||
|
||||
dlg_broadcast_msg (h, WIDGET_DRAW, 1);
|
||||
|
||||
update_cursor (h);
|
||||
}
|
||||
|
||||
static void
|
||||
dlg_refresh (void *parameter)
|
||||
{
|
||||
dlg_redraw ((Dlg_head *) parameter);
|
||||
}
|
||||
|
||||
void dlg_stop (Dlg_head *h)
|
||||
{
|
||||
h->running = 0;
|
||||
}
|
||||
|
||||
static inline void dialog_handle_key (Dlg_head *h, int d_key)
|
||||
{
|
||||
switch (d_key){
|
||||
case KEY_LEFT:
|
||||
case KEY_UP:
|
||||
dlg_one_up (h);
|
||||
break;
|
||||
|
||||
case KEY_RIGHT:
|
||||
case KEY_DOWN:
|
||||
dlg_one_down (h);
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
interactive_display (NULL, h->help_ctx);
|
||||
do_refresh ();
|
||||
break;
|
||||
|
||||
case XCTRL('z'):
|
||||
suspend_cmd ();
|
||||
/* Fall through */
|
||||
|
||||
case XCTRL('l'):
|
||||
#ifndef HAVE_SLANG
|
||||
/* Use this if the refreshes fail */
|
||||
clr_scr ();
|
||||
do_refresh ();
|
||||
#else
|
||||
touchwin (stdscr);
|
||||
#endif /* HAVE_SLANG */
|
||||
mc_refresh ();
|
||||
doupdate ();
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case KEY_ENTER:
|
||||
h->ret_value = B_ENTER;
|
||||
h->running = 0;
|
||||
break;
|
||||
|
||||
case ESC_CHAR:
|
||||
case KEY_F (10):
|
||||
case XCTRL ('c'):
|
||||
case XCTRL ('g'):
|
||||
h->ret_value = B_CANCEL;
|
||||
dlg_stop (h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dlg_try_hotkey (Dlg_head *h, int d_key)
|
||||
{
|
||||
Widget *hot_cur;
|
||||
Widget *previous;
|
||||
int handled, c;
|
||||
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Explanation: we don't send letter hotkeys to other widgets if
|
||||
* the currently selected widget is an input line
|
||||
*/
|
||||
|
||||
if (h->current->options & W_IS_INPUT) {
|
||||
if (d_key < 255 && isalpha (d_key))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If it's an alt key, send the message */
|
||||
c = d_key & ~ALT (0);
|
||||
if (d_key & ALT (0) && c < 255 && isalpha (c))
|
||||
d_key = tolower (c);
|
||||
|
||||
handled = 0;
|
||||
if (h->current->options & W_WANT_HOTKEY)
|
||||
handled = callback (h) (h->current, WIDGET_HOTKEY, d_key);
|
||||
|
||||
/* If not used, send hotkey to other widgets */
|
||||
if (handled)
|
||||
return handled;
|
||||
|
||||
hot_cur = h->current;
|
||||
|
||||
/* send it to all widgets */
|
||||
do {
|
||||
if (hot_cur->options & W_WANT_HOTKEY)
|
||||
handled |=
|
||||
(*hot_cur->callback) (hot_cur, WIDGET_HOTKEY, d_key);
|
||||
|
||||
if (!handled)
|
||||
hot_cur = hot_cur->next;
|
||||
} while (h->current != hot_cur && !handled);
|
||||
|
||||
if (!handled)
|
||||
return 0;
|
||||
|
||||
previous = h->current;
|
||||
if (!dlg_unfocus (h))
|
||||
return handled;
|
||||
|
||||
h->current = hot_cur;
|
||||
if (!dlg_focus (h)) {
|
||||
h->current = previous;
|
||||
dlg_focus (h);
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
static int
|
||||
dlg_key_event (Dlg_head *h, int d_key)
|
||||
{
|
||||
int handled;
|
||||
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
/* TAB used to cycle */
|
||||
if (!(h->flags & DLG_WANT_TAB)
|
||||
&& (d_key == '\t' || d_key == KEY_BTAB)) {
|
||||
if (d_key == '\t')
|
||||
dlg_one_down (h);
|
||||
else
|
||||
dlg_one_up (h);
|
||||
} else {
|
||||
|
||||
/* first can dlg_callback handle the key */
|
||||
handled = (*h->callback) (h, DLG_KEY, d_key);
|
||||
|
||||
/* next try the hotkey */
|
||||
if (!handled)
|
||||
handled = dlg_try_hotkey (h, d_key);
|
||||
|
||||
if (handled)
|
||||
(*h->callback) (h, DLG_HOTKEY_HANDLED, 0);
|
||||
|
||||
/* not used - then try widget_callback */
|
||||
if (!handled)
|
||||
handled = callback (h) (h->current, WIDGET_KEY, d_key);
|
||||
|
||||
/* not used- try to use the unhandled case */
|
||||
if (!handled)
|
||||
handled = (*h->callback) (h, DLG_UNHANDLED_KEY, d_key);
|
||||
|
||||
if (!handled)
|
||||
dialog_handle_key (h, d_key);
|
||||
(*h->callback) (h, DLG_POST_KEY, d_key);
|
||||
|
||||
return handled;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
|
||||
{
|
||||
Widget *item;
|
||||
Widget *starting_widget = h->current;
|
||||
Gpm_Event new_event;
|
||||
int x = event->x;
|
||||
int y = event->y;
|
||||
|
||||
item = starting_widget;
|
||||
do {
|
||||
Widget *widget = item;
|
||||
|
||||
item = item->next;
|
||||
|
||||
if (!((x > widget->x) && (x <= widget->x + widget->cols)
|
||||
&& (y > widget->y) && (y <= widget->y + widget->lines)))
|
||||
continue;
|
||||
|
||||
new_event = *event;
|
||||
new_event.x -= widget->x;
|
||||
new_event.y -= widget->y;
|
||||
|
||||
if (!widget->mouse)
|
||||
return MOU_NORMAL;
|
||||
|
||||
return (*widget->mouse) (&new_event, widget);
|
||||
} while (item != starting_widget);
|
||||
|
||||
return MOU_NORMAL;
|
||||
}
|
||||
|
||||
/* Run dialog routines */
|
||||
|
||||
/* Init the process */
|
||||
void init_dlg (Dlg_head *h)
|
||||
{
|
||||
int refresh_mode;
|
||||
|
||||
/* Initialize dialog manager and widgets */
|
||||
(*h->callback) (h, DLG_INIT, 0);
|
||||
dlg_broadcast_msg (h, WIDGET_INIT, 0);
|
||||
|
||||
if (h->x == 0 && h->y == 0 && h->cols == COLS && h->lines == LINES)
|
||||
refresh_mode = REFRESH_COVERS_ALL;
|
||||
else
|
||||
refresh_mode = REFRESH_COVERS_PART;
|
||||
|
||||
push_refresh (dlg_refresh, h, refresh_mode);
|
||||
h->refresh_pushed = 1;
|
||||
|
||||
h->previous_dialog = current_dlg;
|
||||
current_dlg = h;
|
||||
|
||||
/* Initialize the mouse status */
|
||||
h->mouse_status = MOU_NORMAL;
|
||||
|
||||
/* Select the first widget that takes focus */
|
||||
while (!dlg_focus (h) && h->current)
|
||||
h->current = h->current->next;
|
||||
|
||||
/* Redraw the screen */
|
||||
dlg_redraw (h);
|
||||
|
||||
h->ret_value = 0;
|
||||
h->running = 1;
|
||||
}
|
||||
|
||||
/* Shutdown the run_dlg */
|
||||
void dlg_run_done (Dlg_head *h)
|
||||
{
|
||||
if (h->current)
|
||||
(*h->callback) (h, DLG_END, 0);
|
||||
|
||||
current_dlg = (Dlg_head *) h->previous_dialog;
|
||||
}
|
||||
|
||||
void dlg_process_event (Dlg_head *h, int key, Gpm_Event *event)
|
||||
{
|
||||
if (key == EV_NONE){
|
||||
if (got_interrupt ())
|
||||
key = XCTRL('g');
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == EV_MOUSE)
|
||||
h->mouse_status = dlg_mouse_event (h, event);
|
||||
else
|
||||
dlg_key_event (h, key);
|
||||
}
|
||||
|
||||
static inline void
|
||||
frontend_run_dlg (Dlg_head *h)
|
||||
{
|
||||
int d_key;
|
||||
Gpm_Event event;
|
||||
|
||||
event.x = -1;
|
||||
while (h->running) {
|
||||
if (winch_flag)
|
||||
change_screen_size ();
|
||||
|
||||
if (is_idle ()) {
|
||||
if (idle_hook)
|
||||
execute_hooks (idle_hook);
|
||||
|
||||
while ((h->flags & DLG_WANT_IDLE) && is_idle ())
|
||||
(*h->callback) (h, DLG_IDLE, 0);
|
||||
|
||||
/* Allow terminating the dialog from the idle handler */
|
||||
if (!h->running)
|
||||
break;
|
||||
}
|
||||
|
||||
update_cursor (h);
|
||||
|
||||
/* Clear interrupt flag */
|
||||
got_interrupt ();
|
||||
d_key = get_event (&event, h->mouse_status == MOU_REPEAT, 1);
|
||||
|
||||
dlg_process_event (h, d_key, &event);
|
||||
|
||||
if (!h->running)
|
||||
(*h->callback) (h, DLG_VALIDATE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard run dialog routine
|
||||
* We have to keep this routine small so that we can duplicate it's
|
||||
* behavior on complex routines like the file routines, this way,
|
||||
* they can call the dlg_process_event without rewriting all the code
|
||||
*/
|
||||
int run_dlg (Dlg_head *h)
|
||||
{
|
||||
init_dlg (h);
|
||||
frontend_run_dlg (h);
|
||||
dlg_run_done (h);
|
||||
return h->ret_value;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_dlg (Dlg_head *h)
|
||||
{
|
||||
int i;
|
||||
Widget *c;
|
||||
|
||||
if (h->refresh_pushed)
|
||||
pop_refresh ();
|
||||
|
||||
dlg_broadcast_msg (h, WIDGET_DESTROY, 0);
|
||||
c = h->current;
|
||||
for (i = 0; i < h->count; i++) {
|
||||
c = c->next;
|
||||
if (h->current) {
|
||||
g_free (h->current);
|
||||
}
|
||||
h->current = c;
|
||||
}
|
||||
g_free (h->title);
|
||||
g_free (h);
|
||||
|
||||
do_refresh ();
|
||||
}
|
||||
|
||||
void widget_set_size (Widget *widget, int y, int x, int lines, int cols)
|
||||
{
|
||||
widget->x = x;
|
||||
widget->y = y;
|
||||
widget->cols = cols;
|
||||
widget->lines = lines;
|
||||
}
|
||||
|
||||
/* Replace widget old_w for widget new_w in the dialog h */
|
||||
void
|
||||
dlg_replace_widget (Dlg_head *h, Widget *old_w, Widget *new_w)
|
||||
{
|
||||
int should_focus = 0;
|
||||
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
if (old_w == h->current)
|
||||
should_focus = 1;
|
||||
|
||||
new_w->parent = h;
|
||||
new_w->dlg_id = old_w->dlg_id;
|
||||
|
||||
if (old_w == old_w->next) {
|
||||
/* just one widget */
|
||||
new_w->prev = new_w;
|
||||
new_w->next = new_w;
|
||||
} else {
|
||||
new_w->prev = old_w->prev;
|
||||
new_w->next = old_w->next;
|
||||
old_w->prev->next = new_w;
|
||||
old_w->next->prev = new_w;
|
||||
}
|
||||
|
||||
if (should_focus)
|
||||
h->current = new_w;
|
||||
|
||||
send_message (old_w, WIDGET_DESTROY, 0);
|
||||
send_message (new_w, WIDGET_INIT, 0);
|
||||
|
||||
if (should_focus) {
|
||||
if (!dlg_focus (h)) {
|
||||
select_a_widget (h, 1);
|
||||
}
|
||||
}
|
||||
|
||||
send_message (new_w, WIDGET_DRAW, 0);
|
||||
}
|
||||
|
238
src/dialog.h
238
src/dialog.h
@ -1,18 +1,232 @@
|
||||
#ifndef __DIALOG_H
|
||||
#define __DIALOG_H
|
||||
/* Dialog box features module for the Midnight Commander
|
||||
Copyright (C) 1994, 1995 Radek Doulik, Miguel de Icaza
|
||||
|
||||
/* We search under the stack until we find a refresh function that covers */
|
||||
/* the complete screen, and from this point we go up refreshing the */
|
||||
/* individual regions */
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
enum {
|
||||
REFRESH_COVERS_PART, /* If the refresh fn convers only a part */
|
||||
REFRESH_COVERS_ALL /* If the refresh fn convers all the screen */
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef MC_DLG_H
|
||||
#define MC_DLG_H
|
||||
#include "mouse.h"
|
||||
|
||||
/* Color constants */
|
||||
#define FOCUSC h->color[1]
|
||||
#define NORMALC h->color[0]
|
||||
#define HOT_NORMALC h->color[2]
|
||||
#define HOT_FOCUSC h->color[3]
|
||||
|
||||
/* Common return values */
|
||||
#define B_EXIT 0
|
||||
#define B_CANCEL 1
|
||||
#define B_ENTER 2
|
||||
#define B_HELP 3
|
||||
#define B_USER 100
|
||||
|
||||
/* Widget messages */
|
||||
typedef enum {
|
||||
WIDGET_INIT, /* Initialize widget */
|
||||
WIDGET_FOCUS, /* Draw widget in focused state */
|
||||
WIDGET_UNFOCUS, /* Draw widget in unfocused state */
|
||||
WIDGET_DRAW, /* Sent to widget to draw themselves */
|
||||
WIDGET_KEY, /* Sent to widgets on key press */
|
||||
WIDGET_HOTKEY, /* Sent to widget to catch preprocess key */
|
||||
WIDGET_DESTROY, /* Sent to widget at destruction time */
|
||||
WIDGET_CURSOR, /* Sent to widget to position the cursor */
|
||||
WIDGET_IDLE, /* Send to widgets with options & W_WANT_IDLE*/
|
||||
} widget_msg_t;
|
||||
|
||||
typedef enum {
|
||||
MSG_NOT_HANDLED,
|
||||
MSG_HANDLED
|
||||
} cb_ret_t;
|
||||
|
||||
/* Widgets are expected to answer to the following messages:
|
||||
|
||||
WIDGET_FOCUS: 1 if the accept the focus, 0 if they do not.
|
||||
WIDGET_UNFOCUS: 1 if they accept to release the focus, 0 if they don't.
|
||||
WIDGET_KEY: 1 if they actually used the key, 0 if not.
|
||||
WIDGET_HOTKEY: 1 if they actually used the key, 0 if not.
|
||||
*/
|
||||
|
||||
/* Dialog messages */
|
||||
typedef enum {
|
||||
DLG_KEY, /* Key before sending to widget */
|
||||
DLG_INIT, /* Initialize dialog */
|
||||
DLG_END, /* Shut down dialog */
|
||||
DLG_ACTION, /* State of check- and radioboxes has changed */
|
||||
DLG_DRAW, /* Draw dialog on screen */
|
||||
DLG_FOCUS, /* A widget has got focus */
|
||||
DLG_UNFOCUS, /* A widget has been unfocused */
|
||||
DLG_RESIZE, /* Window size has changed */
|
||||
DLG_POST_KEY, /* The key has been handled */
|
||||
DLG_IDLE, /* The idle state is active */
|
||||
DLG_UNHANDLED_KEY, /* Key that no widget handled */
|
||||
DLG_HOTKEY_HANDLED, /* A widget has got the hotkey */
|
||||
DLG_VALIDATE /* Dialog is to be closed */
|
||||
} dlg_msg_t;
|
||||
|
||||
|
||||
/* Dialog callback */
|
||||
struct Dlg_head;
|
||||
typedef cb_ret_t (*dlg_cb_fn)(struct Dlg_head *h, dlg_msg_t msg, int parm);
|
||||
|
||||
typedef struct Dlg_head {
|
||||
|
||||
/* Set by the user */
|
||||
int flags; /* User flags */
|
||||
char *help_ctx; /* Name of the help entry */
|
||||
const int *color; /* Color set */
|
||||
char *title; /* Title of the dialog */
|
||||
|
||||
/* Set and received by the user */
|
||||
int ret_value; /* Result of run_dlg() */
|
||||
|
||||
/* Geometry */
|
||||
int x, y; /* Position relative to screen origin */
|
||||
int cols, lines; /* Width and height of the window */
|
||||
|
||||
/* Internal flags */
|
||||
int running;
|
||||
int mouse_status; /* For the autorepeat status of the mouse */
|
||||
int refresh_pushed; /* Did the dialog actually run? */
|
||||
|
||||
/* Internal variables */
|
||||
int count; /* Number of widgets */
|
||||
struct Widget *current; /* Curently active widget */
|
||||
dlg_cb_fn callback;
|
||||
void *previous_dialog; /* Pointer to the previously running Dlg_head */
|
||||
|
||||
} Dlg_head;
|
||||
|
||||
|
||||
typedef struct Widget Widget;
|
||||
|
||||
/* Widget callback */
|
||||
typedef cb_ret_t (*callback_fn) (Widget *widget, widget_msg_t msg, int parm);
|
||||
|
||||
/* Every Widget must have this as it's first element */
|
||||
struct Widget {
|
||||
int x, y;
|
||||
int cols, lines;
|
||||
int options;
|
||||
int dlg_id; /* Number of the widget, starting with 0 */
|
||||
struct Widget *next;
|
||||
struct Widget *prev;
|
||||
callback_fn callback; /* The callback function */
|
||||
mouse_h mouse;
|
||||
struct Dlg_head *parent;
|
||||
};
|
||||
|
||||
typedef void (*refresh_fn) (void *);
|
||||
void push_refresh (refresh_fn new_refresh, void *parameter, int flags);
|
||||
void pop_refresh (void);
|
||||
/* The options for the widgets */
|
||||
#define W_WANT_HOTKEY 2
|
||||
#define W_WANT_CURSOR 4
|
||||
#define W_WANT_IDLE 8
|
||||
#define W_IS_INPUT 16
|
||||
|
||||
/* draw box in window */
|
||||
void draw_box (Dlg_head *h, int y, int x, int ys, int xs);
|
||||
|
||||
/* doubled line if possible */
|
||||
void draw_double_box (Dlg_head *h, int y, int x, int ys, int xs);
|
||||
|
||||
/* Creates a dialog head */
|
||||
Dlg_head *create_dlg (int y1, int x1, int lines, int cols,
|
||||
const int *color_set, dlg_cb_fn callback,
|
||||
char *help_ctx, const char *title, int flags);
|
||||
|
||||
|
||||
/* The flags: */
|
||||
#define DLG_REVERSE 32 /* Tab order is opposite to the add order */
|
||||
#define DLG_WANT_TAB 16 /* Should the tab key be sent to the dialog? */
|
||||
#define DLG_WANT_IDLE 8 /* Dialog wants idle events */
|
||||
#define DLG_COMPACT 4 /* Suppress spaces around the frame */
|
||||
#define DLG_TRYUP 2 /* Try to move two lines up the dialog */
|
||||
#define DLG_CENTER 1 /* Center the dialog */
|
||||
#define DLG_NONE 0 /* No options */
|
||||
|
||||
int add_widget (Dlg_head *dest, void *Widget);
|
||||
|
||||
/* Runs dialog d */
|
||||
int run_dlg (Dlg_head *d);
|
||||
|
||||
void dlg_run_done (Dlg_head *h);
|
||||
void dlg_process_event (Dlg_head *h, int key, Gpm_Event *event);
|
||||
void init_dlg (Dlg_head *h);
|
||||
|
||||
/* To activate/deactivate the idle message generation */
|
||||
void set_idle_proc (Dlg_head *d, int enable);
|
||||
|
||||
void dlg_redraw (Dlg_head *h);
|
||||
void destroy_dlg (Dlg_head *h);
|
||||
|
||||
void widget_set_size (Widget *widget, int x1, int y1, int x2, int y2);
|
||||
|
||||
void dlg_broadcast_msg (Dlg_head *h, widget_msg_t message, int reverse);
|
||||
|
||||
void init_widget (Widget *w, int y, int x, int lines, int cols,
|
||||
callback_fn callback, mouse_h mouse_handler);
|
||||
|
||||
/* Default callback for dialogs */
|
||||
cb_ret_t default_dlg_callback (Dlg_head *h, dlg_msg_t msg, int parm);
|
||||
|
||||
/* Default callback for widgets */
|
||||
cb_ret_t default_proc (widget_msg_t msg, int parm);
|
||||
|
||||
/* Default paint routine for dialogs */
|
||||
void common_dialog_repaint (struct Dlg_head *h);
|
||||
|
||||
#define widget_move(w, _y, _x) move(((Widget *)(w))->y + _y, \
|
||||
((Widget *)(w))->x + _x)
|
||||
#define dlg_move(h, _y, _x) move(((Dlg_head *)(h))->y + _y, \
|
||||
((Dlg_head *)(h))->x + _x)
|
||||
|
||||
extern Dlg_head *current_dlg;
|
||||
|
||||
/* A hook list for idle events */
|
||||
extern Hook *idle_hook;
|
||||
|
||||
static inline cb_ret_t
|
||||
send_message (Widget *w, widget_msg_t msg, int parm)
|
||||
{
|
||||
return (*(w->callback)) (w, msg, parm);
|
||||
}
|
||||
|
||||
void dlg_replace_widget (Dlg_head *h, Widget *old, Widget *new);
|
||||
int dlg_overlap (Widget *a, Widget *b);
|
||||
void widget_erase (Widget *);
|
||||
void dlg_erase (Dlg_head *h);
|
||||
void dlg_stop (Dlg_head *h);
|
||||
|
||||
/* Widget selection */
|
||||
int dlg_select_widget (Dlg_head *h, void *widget);
|
||||
void dlg_one_up (Dlg_head *h);
|
||||
void dlg_one_down (Dlg_head *h);
|
||||
int dlg_focus (Dlg_head *h);
|
||||
Widget *find_widget_type (Dlg_head *h, void *callback);
|
||||
void dlg_select_by_id (Dlg_head *h, int id);
|
||||
|
||||
/* Redraw all dialogs */
|
||||
void do_refresh (void);
|
||||
|
||||
#endif /* __DIALOG_H */
|
||||
/* Sets/clear the specified flag in the options field */
|
||||
#define widget_option(w,f,i) \
|
||||
w.options = ((i) ? (w.options | (f)) : (w.options & (~(f))))
|
||||
|
||||
#define widget_want_cursor(w,i) widget_option(w, W_WANT_CURSOR, i)
|
||||
#define widget_want_hotkey(w,i) widget_option(w, W_WANT_HOTKEY, i)
|
||||
|
||||
/* Used in load_prompt() */
|
||||
void update_cursor (Dlg_head *h);
|
||||
|
||||
#endif /* MC_DLG_H */
|
||||
|
863
src/dlg.c
863
src/dlg.c
@ -1,863 +0,0 @@
|
||||
/* Dlg box features module for the Midnight Commander
|
||||
Copyright (C) 1994, 1995 Radek Doulik, Miguel de Icaza
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "menu.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "mouse.h"
|
||||
#include "help.h"
|
||||
#include "key.h" /* For mi_getch() */
|
||||
#include "dlg.h"
|
||||
#include "dialog.h" /* For push_refresh() and pop_refresh() */
|
||||
#include "layout.h"
|
||||
#include "execute.h"
|
||||
#include "main.h"
|
||||
|
||||
#define waddc(w,y1,x1,c) move (w->y+y1, w->x+x1); addch (c)
|
||||
|
||||
/* Primitive way to check if the the current dialog is our dialog */
|
||||
/* This is needed by async routines like load_prompt */
|
||||
Dlg_head *current_dlg = 0;
|
||||
|
||||
/* A hook list for idle events */
|
||||
Hook *idle_hook = 0;
|
||||
|
||||
static void dlg_broadcast_msg_to (Dlg_head * h, widget_msg_t message,
|
||||
int reverse, int flags);
|
||||
|
||||
static void slow_box (Dlg_head *h, int y, int x, int ys, int xs)
|
||||
{
|
||||
move (h->y+y, h->x+x);
|
||||
hline (' ', xs);
|
||||
vline (' ', ys);
|
||||
move (h->y+y, h->x+x+xs-1);
|
||||
vline (' ', ys);
|
||||
move (h->y+y+ys-1, h->x+x);
|
||||
hline (' ', xs);
|
||||
}
|
||||
|
||||
/* draw box in window */
|
||||
void draw_box (Dlg_head *h, int y, int x, int ys, int xs)
|
||||
{
|
||||
if (slow_terminal){
|
||||
slow_box (h, y, x, ys, xs);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef HAVE_SLANG
|
||||
waddc (h, y, x, ACS_ULCORNER);
|
||||
hline (ACS_HLINE, xs - 2);
|
||||
waddc (h, y + ys - 1, x, ACS_LLCORNER);
|
||||
hline (ACS_HLINE, xs - 2);
|
||||
|
||||
waddc (h, y, x + xs - 1, ACS_URCORNER);
|
||||
waddc (h, y + ys - 1, x + xs - 1, ACS_LRCORNER);
|
||||
|
||||
move (h->y+y+1, h->x+x);
|
||||
vline (ACS_VLINE, ys - 2);
|
||||
move (h->y+y+1, h->x+x+xs-1);
|
||||
vline (ACS_VLINE, ys - 2);
|
||||
#else
|
||||
SLsmg_draw_box (h->y+y, h->x+x, ys, xs);
|
||||
#endif /* HAVE_SLANG */
|
||||
}
|
||||
|
||||
/* draw box in window */
|
||||
void draw_double_box (Dlg_head *h, int y, int x, int ys, int xs)
|
||||
{
|
||||
#ifndef HAVE_SLANG
|
||||
draw_box (h, y, x, ys, xs);
|
||||
#else
|
||||
SLsmg_draw_double_box (h->y+y, h->x+x, ys, xs);
|
||||
#endif /* HAVE_SLANG */
|
||||
}
|
||||
|
||||
void widget_erase (Widget *w)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < w->lines; y++){
|
||||
widget_move (w, y, 0);
|
||||
for (x = 0; x < w->cols; x++)
|
||||
addch (' ');
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_erase (Dlg_head *h)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < h->lines; y++){
|
||||
move (y+h->y, h->x); /* FIXME: should test if ERR */
|
||||
for (x = 0; x < h->cols; x++){
|
||||
addch (' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
init_widget (Widget *w, int y, int x, int lines, int cols,
|
||||
callback_fn callback, mouse_h mouse_handler)
|
||||
{
|
||||
w->x = x;
|
||||
w->y = y;
|
||||
w->cols = cols;
|
||||
w->lines = lines;
|
||||
w->callback = callback;
|
||||
w->mouse = mouse_handler;
|
||||
w->parent = 0;
|
||||
|
||||
/* Almost all widgets want to put the cursor in a suitable place */
|
||||
w->options = W_WANT_CURSOR;
|
||||
}
|
||||
|
||||
/* Default callback for widgets */
|
||||
cb_ret_t
|
||||
default_proc (widget_msg_t msg, int parm)
|
||||
{
|
||||
switch (msg) {
|
||||
case WIDGET_INIT:
|
||||
case WIDGET_FOCUS:
|
||||
case WIDGET_UNFOCUS:
|
||||
case WIDGET_DRAW:
|
||||
case WIDGET_DESTROY:
|
||||
case WIDGET_CURSOR:
|
||||
case WIDGET_IDLE:
|
||||
return MSG_HANDLED;
|
||||
|
||||
default:
|
||||
return MSG_NOT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean the dialog area, draw the frame and the title */
|
||||
void
|
||||
common_dialog_repaint (struct Dlg_head *h)
|
||||
{
|
||||
int space;
|
||||
|
||||
space = (h->flags & DLG_COMPACT) ? 0 : 1;
|
||||
|
||||
attrset (NORMALC);
|
||||
dlg_erase (h);
|
||||
draw_box (h, space, space, h->lines - 2 * space, h->cols - 2 * space);
|
||||
|
||||
if (h->title) {
|
||||
attrset (HOT_NORMALC);
|
||||
dlg_move (h, space, (h->cols - strlen (h->title)) / 2);
|
||||
addstr (h->title);
|
||||
}
|
||||
}
|
||||
|
||||
/* Default dialog callback */
|
||||
cb_ret_t default_dlg_callback (Dlg_head *h, dlg_msg_t msg, int parm)
|
||||
{
|
||||
if (msg == DLG_DRAW && h->color) {
|
||||
common_dialog_repaint (h);
|
||||
return MSG_HANDLED;
|
||||
}
|
||||
if (msg == DLG_IDLE){
|
||||
dlg_broadcast_msg_to (h, WIDGET_IDLE, 0, W_WANT_IDLE);
|
||||
return MSG_HANDLED;
|
||||
}
|
||||
return MSG_NOT_HANDLED;
|
||||
}
|
||||
|
||||
Dlg_head *
|
||||
create_dlg (int y1, int x1, int lines, int cols, const int *color_set,
|
||||
dlg_cb_fn callback, char *help_ctx, const char *title,
|
||||
int flags)
|
||||
{
|
||||
Dlg_head *new_d;
|
||||
|
||||
if (flags & DLG_CENTER) {
|
||||
y1 = (LINES - lines) / 2;
|
||||
x1 = (COLS - cols) / 2;
|
||||
}
|
||||
|
||||
if ((flags & DLG_TRYUP) && (y1 > 3))
|
||||
y1 -= 2;
|
||||
|
||||
new_d = g_new0 (Dlg_head, 1);
|
||||
new_d->color = color_set;
|
||||
new_d->help_ctx = help_ctx;
|
||||
new_d->callback = callback ? callback : default_dlg_callback;
|
||||
new_d->x = x1;
|
||||
new_d->y = y1;
|
||||
new_d->cols = cols;
|
||||
new_d->lines = lines;
|
||||
new_d->flags = flags;
|
||||
|
||||
/* Strip existing spaces, add one space before and after the title */
|
||||
if (title) {
|
||||
char *t;
|
||||
t = g_strstrip (g_strdup (title));
|
||||
new_d->title = g_strconcat (" ", t, " ", NULL);
|
||||
g_free (t);
|
||||
}
|
||||
|
||||
return (new_d);
|
||||
}
|
||||
|
||||
void
|
||||
set_idle_proc (Dlg_head *d, int enable)
|
||||
{
|
||||
if (enable)
|
||||
d->flags |= DLG_WANT_IDLE;
|
||||
else
|
||||
d->flags &= ~DLG_WANT_IDLE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert widget to dialog before current widget. For dialogs populated
|
||||
* from the bottom, make the widget current. Return widget number.
|
||||
*/
|
||||
int
|
||||
add_widget (Dlg_head *h, void *w)
|
||||
{
|
||||
Widget *widget = (Widget *) w;
|
||||
|
||||
/* Don't accept 0 widgets, and running dialogs */
|
||||
if (!widget || h->running)
|
||||
abort ();
|
||||
|
||||
widget->x += h->x;
|
||||
widget->y += h->y;
|
||||
widget->parent = h;
|
||||
widget->dlg_id = h->count++;
|
||||
|
||||
if (h->current) {
|
||||
widget->next = h->current;
|
||||
widget->prev = h->current->prev;
|
||||
h->current->prev->next = widget;
|
||||
h->current->prev = widget;
|
||||
} else {
|
||||
widget->prev = widget;
|
||||
widget->next = widget;
|
||||
}
|
||||
|
||||
if ((h->flags & DLG_REVERSE) || !h->current)
|
||||
h->current = widget;
|
||||
|
||||
return widget->dlg_id;
|
||||
}
|
||||
|
||||
/* broadcast a message to all the widgets in a dialog that have
|
||||
* the options set to flags.
|
||||
*/
|
||||
static void
|
||||
dlg_broadcast_msg_to (Dlg_head *h, widget_msg_t message, int reverse,
|
||||
int flags)
|
||||
{
|
||||
Widget *p, *first, *wi;
|
||||
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
if (reverse)
|
||||
first = p = h->current->prev;
|
||||
else
|
||||
first = p = h->current->next;
|
||||
|
||||
do {
|
||||
wi = p;
|
||||
if (reverse)
|
||||
p = p->prev;
|
||||
else
|
||||
p = p->next;
|
||||
send_message (wi, message, 0);
|
||||
} while (first != p);
|
||||
}
|
||||
|
||||
/* broadcast a message to all the widgets in a dialog */
|
||||
void
|
||||
dlg_broadcast_msg (Dlg_head *h, widget_msg_t message, int reverse)
|
||||
{
|
||||
dlg_broadcast_msg_to (h, message, reverse, ~0);
|
||||
}
|
||||
|
||||
int dlg_focus (Dlg_head *h)
|
||||
{
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
if (send_message (h->current, WIDGET_FOCUS, 0)){
|
||||
(*h->callback) (h, DLG_FOCUS, 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dlg_unfocus (Dlg_head *h)
|
||||
{
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
if (send_message (h->current, WIDGET_UNFOCUS, 0)){
|
||||
(*h->callback) (h, DLG_UNFOCUS, 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
select_a_widget (Dlg_head *h, int down)
|
||||
{
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
do {
|
||||
if (down)
|
||||
h->current = h->current->next;
|
||||
else
|
||||
h->current = h->current->prev;
|
||||
} while (!dlg_focus (h));
|
||||
}
|
||||
|
||||
/* Return true if the windows overlap */
|
||||
int dlg_overlap (Widget *a, Widget *b)
|
||||
{
|
||||
if ((b->x >= a->x + a->cols)
|
||||
|| (a->x >= b->x + b->cols)
|
||||
|| (b->y >= a->y + a->lines)
|
||||
|| (a->y >= b->y + b->lines))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Find the widget with the given callback in the dialog h */
|
||||
Widget *
|
||||
find_widget_type (Dlg_head *h, void *callback)
|
||||
{
|
||||
Widget *w;
|
||||
Widget *item;
|
||||
int i;
|
||||
|
||||
if (!h)
|
||||
return 0;
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
w = 0;
|
||||
for (i = 0, item = h->current; i < h->count; i++, item = item->next) {
|
||||
if (item->callback == callback) {
|
||||
w = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
/* Find the widget with the given dialog id in the dialog h and select it */
|
||||
void
|
||||
dlg_select_by_id (Dlg_head *h, int id)
|
||||
{
|
||||
Widget *w, *w_found;
|
||||
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
w = h->current;
|
||||
w_found = NULL;
|
||||
|
||||
do {
|
||||
if (w->dlg_id == id) {
|
||||
w_found = w;
|
||||
break;
|
||||
}
|
||||
w = w->next;
|
||||
} while (w != h->current);
|
||||
|
||||
if (w_found)
|
||||
dlg_select_widget(h, w_found);
|
||||
}
|
||||
|
||||
void dlg_one_up (Dlg_head *h)
|
||||
{
|
||||
Widget *old;
|
||||
|
||||
old = h->current;
|
||||
|
||||
if (!old)
|
||||
return;
|
||||
|
||||
/* If it accepts unFOCUSion */
|
||||
if (!dlg_unfocus(h))
|
||||
return;
|
||||
|
||||
select_a_widget (h, 0);
|
||||
if (dlg_overlap (old, h->current)){
|
||||
send_message (h->current, WIDGET_DRAW, 0);
|
||||
send_message (h->current, WIDGET_FOCUS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void dlg_one_down (Dlg_head *h)
|
||||
{
|
||||
Widget *old;
|
||||
|
||||
old = h->current;
|
||||
if (!old)
|
||||
return;
|
||||
|
||||
if (!dlg_unfocus (h))
|
||||
return;
|
||||
|
||||
select_a_widget (h, 1);
|
||||
if (dlg_overlap (old, h->current)){
|
||||
send_message (h->current, WIDGET_DRAW, 0);
|
||||
send_message (h->current, WIDGET_FOCUS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int dlg_select_widget (Dlg_head *h, void *w)
|
||||
{
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
if (dlg_unfocus (h)){
|
||||
while (h->current != w)
|
||||
h->current = h->current->next;
|
||||
while (!dlg_focus (h))
|
||||
h->current = h->current->next;
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define callback(h) (h->current->callback)
|
||||
|
||||
void update_cursor (Dlg_head *h)
|
||||
{
|
||||
if (!h->current)
|
||||
return;
|
||||
if (h->current->options & W_WANT_CURSOR)
|
||||
send_message (h->current, WIDGET_CURSOR, 0);
|
||||
else {
|
||||
Widget *p = h->current;
|
||||
|
||||
do {
|
||||
if (p->options & W_WANT_CURSOR)
|
||||
if ((*p->callback)(p, WIDGET_CURSOR, 0)){
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
} while (h->current != p);
|
||||
}
|
||||
}
|
||||
|
||||
/* Redraw the widgets in reverse order, leaving the current widget
|
||||
* as the last one
|
||||
*/
|
||||
void dlg_redraw (Dlg_head *h)
|
||||
{
|
||||
(h->callback)(h, DLG_DRAW, 0);
|
||||
|
||||
dlg_broadcast_msg (h, WIDGET_DRAW, 1);
|
||||
|
||||
update_cursor (h);
|
||||
}
|
||||
|
||||
static void
|
||||
dlg_refresh (void *parameter)
|
||||
{
|
||||
dlg_redraw ((Dlg_head *) parameter);
|
||||
}
|
||||
|
||||
void dlg_stop (Dlg_head *h)
|
||||
{
|
||||
h->running = 0;
|
||||
}
|
||||
|
||||
static inline void dialog_handle_key (Dlg_head *h, int d_key)
|
||||
{
|
||||
switch (d_key){
|
||||
case KEY_LEFT:
|
||||
case KEY_UP:
|
||||
dlg_one_up (h);
|
||||
break;
|
||||
|
||||
case KEY_RIGHT:
|
||||
case KEY_DOWN:
|
||||
dlg_one_down (h);
|
||||
break;
|
||||
|
||||
case KEY_F(1):
|
||||
interactive_display (NULL, h->help_ctx);
|
||||
do_refresh ();
|
||||
break;
|
||||
|
||||
case XCTRL('z'):
|
||||
suspend_cmd ();
|
||||
/* Fall through */
|
||||
|
||||
case XCTRL('l'):
|
||||
#ifndef HAVE_SLANG
|
||||
/* Use this if the refreshes fail */
|
||||
clr_scr ();
|
||||
do_refresh ();
|
||||
#else
|
||||
touchwin (stdscr);
|
||||
#endif /* HAVE_SLANG */
|
||||
mc_refresh ();
|
||||
doupdate ();
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case KEY_ENTER:
|
||||
h->ret_value = B_ENTER;
|
||||
h->running = 0;
|
||||
break;
|
||||
|
||||
case ESC_CHAR:
|
||||
case KEY_F (10):
|
||||
case XCTRL ('c'):
|
||||
case XCTRL ('g'):
|
||||
h->ret_value = B_CANCEL;
|
||||
dlg_stop (h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dlg_try_hotkey (Dlg_head *h, int d_key)
|
||||
{
|
||||
Widget *hot_cur;
|
||||
Widget *previous;
|
||||
int handled, c;
|
||||
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Explanation: we don't send letter hotkeys to other widgets if
|
||||
* the currently selected widget is an input line
|
||||
*/
|
||||
|
||||
if (h->current->options & W_IS_INPUT) {
|
||||
if (d_key < 255 && isalpha (d_key))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If it's an alt key, send the message */
|
||||
c = d_key & ~ALT (0);
|
||||
if (d_key & ALT (0) && c < 255 && isalpha (c))
|
||||
d_key = tolower (c);
|
||||
|
||||
handled = 0;
|
||||
if (h->current->options & W_WANT_HOTKEY)
|
||||
handled = callback (h) (h->current, WIDGET_HOTKEY, d_key);
|
||||
|
||||
/* If not used, send hotkey to other widgets */
|
||||
if (handled)
|
||||
return handled;
|
||||
|
||||
hot_cur = h->current;
|
||||
|
||||
/* send it to all widgets */
|
||||
do {
|
||||
if (hot_cur->options & W_WANT_HOTKEY)
|
||||
handled |=
|
||||
(*hot_cur->callback) (hot_cur, WIDGET_HOTKEY, d_key);
|
||||
|
||||
if (!handled)
|
||||
hot_cur = hot_cur->next;
|
||||
} while (h->current != hot_cur && !handled);
|
||||
|
||||
if (!handled)
|
||||
return 0;
|
||||
|
||||
previous = h->current;
|
||||
if (!dlg_unfocus (h))
|
||||
return handled;
|
||||
|
||||
h->current = hot_cur;
|
||||
if (!dlg_focus (h)) {
|
||||
h->current = previous;
|
||||
dlg_focus (h);
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
static int
|
||||
dlg_key_event (Dlg_head *h, int d_key)
|
||||
{
|
||||
int handled;
|
||||
|
||||
if (!h->current)
|
||||
return 0;
|
||||
|
||||
/* TAB used to cycle */
|
||||
if (!(h->flags & DLG_WANT_TAB)
|
||||
&& (d_key == '\t' || d_key == KEY_BTAB)) {
|
||||
if (d_key == '\t')
|
||||
dlg_one_down (h);
|
||||
else
|
||||
dlg_one_up (h);
|
||||
} else {
|
||||
|
||||
/* first can dlg_callback handle the key */
|
||||
handled = (*h->callback) (h, DLG_KEY, d_key);
|
||||
|
||||
/* next try the hotkey */
|
||||
if (!handled)
|
||||
handled = dlg_try_hotkey (h, d_key);
|
||||
|
||||
if (handled)
|
||||
(*h->callback) (h, DLG_HOTKEY_HANDLED, 0);
|
||||
|
||||
/* not used - then try widget_callback */
|
||||
if (!handled)
|
||||
handled = callback (h) (h->current, WIDGET_KEY, d_key);
|
||||
|
||||
/* not used- try to use the unhandled case */
|
||||
if (!handled)
|
||||
handled = (*h->callback) (h, DLG_UNHANDLED_KEY, d_key);
|
||||
|
||||
if (!handled)
|
||||
dialog_handle_key (h, d_key);
|
||||
(*h->callback) (h, DLG_POST_KEY, d_key);
|
||||
|
||||
return handled;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dlg_mouse_event (Dlg_head * h, Gpm_Event * event)
|
||||
{
|
||||
Widget *item;
|
||||
Widget *starting_widget = h->current;
|
||||
Gpm_Event new_event;
|
||||
int x = event->x;
|
||||
int y = event->y;
|
||||
|
||||
item = starting_widget;
|
||||
do {
|
||||
Widget *widget = item;
|
||||
|
||||
item = item->next;
|
||||
|
||||
if (!((x > widget->x) && (x <= widget->x + widget->cols)
|
||||
&& (y > widget->y) && (y <= widget->y + widget->lines)))
|
||||
continue;
|
||||
|
||||
new_event = *event;
|
||||
new_event.x -= widget->x;
|
||||
new_event.y -= widget->y;
|
||||
|
||||
if (!widget->mouse)
|
||||
return MOU_NORMAL;
|
||||
|
||||
return (*widget->mouse) (&new_event, widget);
|
||||
} while (item != starting_widget);
|
||||
|
||||
return MOU_NORMAL;
|
||||
}
|
||||
|
||||
/* Run dialog routines */
|
||||
|
||||
/* Init the process */
|
||||
void init_dlg (Dlg_head *h)
|
||||
{
|
||||
int refresh_mode;
|
||||
|
||||
/* Initialize dialog manager and widgets */
|
||||
(*h->callback) (h, DLG_INIT, 0);
|
||||
dlg_broadcast_msg (h, WIDGET_INIT, 0);
|
||||
|
||||
if (h->x == 0 && h->y == 0 && h->cols == COLS && h->lines == LINES)
|
||||
refresh_mode = REFRESH_COVERS_ALL;
|
||||
else
|
||||
refresh_mode = REFRESH_COVERS_PART;
|
||||
|
||||
push_refresh (dlg_refresh, h, refresh_mode);
|
||||
h->refresh_pushed = 1;
|
||||
|
||||
h->previous_dialog = current_dlg;
|
||||
current_dlg = h;
|
||||
|
||||
/* Initialize the mouse status */
|
||||
h->mouse_status = MOU_NORMAL;
|
||||
|
||||
/* Select the first widget that takes focus */
|
||||
while (!dlg_focus (h) && h->current)
|
||||
h->current = h->current->next;
|
||||
|
||||
/* Redraw the screen */
|
||||
dlg_redraw (h);
|
||||
|
||||
h->ret_value = 0;
|
||||
h->running = 1;
|
||||
}
|
||||
|
||||
/* Shutdown the run_dlg */
|
||||
void dlg_run_done (Dlg_head *h)
|
||||
{
|
||||
if (h->current)
|
||||
(*h->callback) (h, DLG_END, 0);
|
||||
|
||||
current_dlg = (Dlg_head *) h->previous_dialog;
|
||||
}
|
||||
|
||||
void dlg_process_event (Dlg_head *h, int key, Gpm_Event *event)
|
||||
{
|
||||
if (key == EV_NONE){
|
||||
if (got_interrupt ())
|
||||
key = XCTRL('g');
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == EV_MOUSE)
|
||||
h->mouse_status = dlg_mouse_event (h, event);
|
||||
else
|
||||
dlg_key_event (h, key);
|
||||
}
|
||||
|
||||
static inline void
|
||||
frontend_run_dlg (Dlg_head *h)
|
||||
{
|
||||
int d_key;
|
||||
Gpm_Event event;
|
||||
|
||||
event.x = -1;
|
||||
while (h->running) {
|
||||
if (winch_flag)
|
||||
change_screen_size ();
|
||||
|
||||
if (is_idle ()) {
|
||||
if (idle_hook)
|
||||
execute_hooks (idle_hook);
|
||||
|
||||
while ((h->flags & DLG_WANT_IDLE) && is_idle ())
|
||||
(*h->callback) (h, DLG_IDLE, 0);
|
||||
|
||||
/* Allow terminating the dialog from the idle handler */
|
||||
if (!h->running)
|
||||
break;
|
||||
}
|
||||
|
||||
update_cursor (h);
|
||||
|
||||
/* Clear interrupt flag */
|
||||
got_interrupt ();
|
||||
d_key = get_event (&event, h->mouse_status == MOU_REPEAT, 1);
|
||||
|
||||
dlg_process_event (h, d_key, &event);
|
||||
|
||||
if (!h->running)
|
||||
(*h->callback) (h, DLG_VALIDATE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Standard run dialog routine
|
||||
* We have to keep this routine small so that we can duplicate it's
|
||||
* behavior on complex routines like the file routines, this way,
|
||||
* they can call the dlg_process_event without rewriting all the code
|
||||
*/
|
||||
int run_dlg (Dlg_head *h)
|
||||
{
|
||||
init_dlg (h);
|
||||
frontend_run_dlg (h);
|
||||
dlg_run_done (h);
|
||||
return h->ret_value;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_dlg (Dlg_head *h)
|
||||
{
|
||||
int i;
|
||||
Widget *c;
|
||||
|
||||
if (h->refresh_pushed)
|
||||
pop_refresh ();
|
||||
|
||||
dlg_broadcast_msg (h, WIDGET_DESTROY, 0);
|
||||
c = h->current;
|
||||
for (i = 0; i < h->count; i++) {
|
||||
c = c->next;
|
||||
if (h->current) {
|
||||
g_free (h->current);
|
||||
}
|
||||
h->current = c;
|
||||
}
|
||||
g_free (h->title);
|
||||
g_free (h);
|
||||
|
||||
do_refresh ();
|
||||
}
|
||||
|
||||
void widget_set_size (Widget *widget, int y, int x, int lines, int cols)
|
||||
{
|
||||
widget->x = x;
|
||||
widget->y = y;
|
||||
widget->cols = cols;
|
||||
widget->lines = lines;
|
||||
}
|
||||
|
||||
/* Replace widget old_w for widget new_w in the dialog h */
|
||||
void
|
||||
dlg_replace_widget (Dlg_head *h, Widget *old_w, Widget *new_w)
|
||||
{
|
||||
int should_focus = 0;
|
||||
|
||||
if (!h->current)
|
||||
return;
|
||||
|
||||
if (old_w == h->current)
|
||||
should_focus = 1;
|
||||
|
||||
new_w->parent = h;
|
||||
new_w->dlg_id = old_w->dlg_id;
|
||||
|
||||
if (old_w == old_w->next) {
|
||||
/* just one widget */
|
||||
new_w->prev = new_w;
|
||||
new_w->next = new_w;
|
||||
} else {
|
||||
new_w->prev = old_w->prev;
|
||||
new_w->next = old_w->next;
|
||||
old_w->prev->next = new_w;
|
||||
old_w->next->prev = new_w;
|
||||
}
|
||||
|
||||
if (should_focus)
|
||||
h->current = new_w;
|
||||
|
||||
send_message (old_w, WIDGET_DESTROY, 0);
|
||||
send_message (new_w, WIDGET_INIT, 0);
|
||||
|
||||
if (should_focus) {
|
||||
if (!dlg_focus (h)) {
|
||||
select_a_widget (h, 1);
|
||||
}
|
||||
}
|
||||
|
||||
send_message (new_w, WIDGET_DRAW, 0);
|
||||
}
|
211
src/dlg.h
211
src/dlg.h
@ -1,211 +0,0 @@
|
||||
#ifndef MC_DLG_H
|
||||
#define MC_DLG_H
|
||||
#include "mouse.h"
|
||||
|
||||
/* Color constants */
|
||||
#define FOCUSC h->color[1]
|
||||
#define NORMALC h->color[0]
|
||||
#define HOT_NORMALC h->color[2]
|
||||
#define HOT_FOCUSC h->color[3]
|
||||
|
||||
/* Common return values */
|
||||
#define B_EXIT 0
|
||||
#define B_CANCEL 1
|
||||
#define B_ENTER 2
|
||||
#define B_HELP 3
|
||||
#define B_USER 100
|
||||
|
||||
/* Widget messages */
|
||||
typedef enum {
|
||||
WIDGET_INIT, /* Initialize widget */
|
||||
WIDGET_FOCUS, /* Draw widget in focused state */
|
||||
WIDGET_UNFOCUS, /* Draw widget in unfocused state */
|
||||
WIDGET_DRAW, /* Sent to widget to draw themselves */
|
||||
WIDGET_KEY, /* Sent to widgets on key press */
|
||||
WIDGET_HOTKEY, /* Sent to widget to catch preprocess key */
|
||||
WIDGET_DESTROY, /* Sent to widget at destruction time */
|
||||
WIDGET_CURSOR, /* Sent to widget to position the cursor */
|
||||
WIDGET_IDLE, /* Send to widgets with options & W_WANT_IDLE*/
|
||||
} widget_msg_t;
|
||||
|
||||
typedef enum {
|
||||
MSG_NOT_HANDLED,
|
||||
MSG_HANDLED
|
||||
} cb_ret_t;
|
||||
|
||||
/* Widgets are expected to answer to the following messages:
|
||||
|
||||
WIDGET_FOCUS: 1 if the accept the focus, 0 if they do not.
|
||||
WIDGET_UNFOCUS: 1 if they accept to release the focus, 0 if they don't.
|
||||
WIDGET_KEY: 1 if they actually used the key, 0 if not.
|
||||
WIDGET_HOTKEY: 1 if they actually used the key, 0 if not.
|
||||
*/
|
||||
|
||||
/* Dialog messages */
|
||||
typedef enum {
|
||||
DLG_KEY, /* Key before sending to widget */
|
||||
DLG_INIT, /* Initialize dialog */
|
||||
DLG_END, /* Shut down dialog */
|
||||
DLG_ACTION, /* State of check- and radioboxes has changed */
|
||||
DLG_DRAW, /* Draw dialog on screen */
|
||||
DLG_FOCUS, /* A widget has got focus */
|
||||
DLG_UNFOCUS, /* A widget has been unfocused */
|
||||
DLG_RESIZE, /* Window size has changed */
|
||||
DLG_POST_KEY, /* The key has been handled */
|
||||
DLG_IDLE, /* The idle state is active */
|
||||
DLG_UNHANDLED_KEY, /* Key that no widget handled */
|
||||
DLG_HOTKEY_HANDLED, /* A widget has got the hotkey */
|
||||
DLG_VALIDATE /* Dialog is to be closed */
|
||||
} dlg_msg_t;
|
||||
|
||||
|
||||
/* Dialog callback */
|
||||
struct Dlg_head;
|
||||
typedef cb_ret_t (*dlg_cb_fn)(struct Dlg_head *h, dlg_msg_t msg, int parm);
|
||||
|
||||
typedef struct Dlg_head {
|
||||
|
||||
/* Set by the user */
|
||||
int flags; /* User flags */
|
||||
char *help_ctx; /* Name of the help entry */
|
||||
const int *color; /* Color set */
|
||||
char *title; /* Title of the dialog */
|
||||
|
||||
/* Set and received by the user */
|
||||
int ret_value; /* Result of run_dlg() */
|
||||
|
||||
/* Geometry */
|
||||
int x, y; /* Position relative to screen origin */
|
||||
int cols, lines; /* Width and height of the window */
|
||||
|
||||
/* Internal flags */
|
||||
int running;
|
||||
int mouse_status; /* For the autorepeat status of the mouse */
|
||||
int refresh_pushed; /* Did the dialog actually run? */
|
||||
|
||||
/* Internal variables */
|
||||
int count; /* Number of widgets */
|
||||
struct Widget *current; /* Curently active widget */
|
||||
dlg_cb_fn callback;
|
||||
void *previous_dialog; /* Pointer to the previously running Dlg_head */
|
||||
|
||||
} Dlg_head;
|
||||
|
||||
|
||||
typedef struct Widget Widget;
|
||||
|
||||
/* Widget callback */
|
||||
typedef cb_ret_t (*callback_fn) (Widget *widget, widget_msg_t msg, int parm);
|
||||
|
||||
/* Every Widget must have this as it's first element */
|
||||
struct Widget {
|
||||
int x, y;
|
||||
int cols, lines;
|
||||
int options;
|
||||
int dlg_id; /* Number of the widget, starting with 0 */
|
||||
struct Widget *next;
|
||||
struct Widget *prev;
|
||||
callback_fn callback; /* The callback function */
|
||||
mouse_h mouse;
|
||||
struct Dlg_head *parent;
|
||||
};
|
||||
|
||||
/* The options for the widgets */
|
||||
#define W_WANT_HOTKEY 2
|
||||
#define W_WANT_CURSOR 4
|
||||
#define W_WANT_IDLE 8
|
||||
#define W_IS_INPUT 16
|
||||
|
||||
/* draw box in window */
|
||||
void draw_box (Dlg_head *h, int y, int x, int ys, int xs);
|
||||
|
||||
/* doubled line if possible */
|
||||
void draw_double_box (Dlg_head *h, int y, int x, int ys, int xs);
|
||||
|
||||
/* Creates a dialog head */
|
||||
Dlg_head *create_dlg (int y1, int x1, int lines, int cols,
|
||||
const int *color_set, dlg_cb_fn callback,
|
||||
char *help_ctx, const char *title, int flags);
|
||||
|
||||
|
||||
/* The flags: */
|
||||
#define DLG_REVERSE 32 /* Tab order is opposite to the add order */
|
||||
#define DLG_WANT_TAB 16 /* Should the tab key be sent to the dialog? */
|
||||
#define DLG_WANT_IDLE 8 /* Dialog wants idle events */
|
||||
#define DLG_COMPACT 4 /* Suppress spaces around the frame */
|
||||
#define DLG_TRYUP 2 /* Try to move two lines up the dialog */
|
||||
#define DLG_CENTER 1 /* Center the dialog */
|
||||
#define DLG_NONE 0 /* No options */
|
||||
|
||||
int add_widget (Dlg_head *dest, void *Widget);
|
||||
|
||||
/* Runs dialog d */
|
||||
int run_dlg (Dlg_head *d);
|
||||
|
||||
void dlg_run_done (Dlg_head *h);
|
||||
void dlg_process_event (Dlg_head *h, int key, Gpm_Event *event);
|
||||
void init_dlg (Dlg_head *h);
|
||||
|
||||
/* To activate/deactivate the idle message generation */
|
||||
void set_idle_proc (Dlg_head *d, int enable);
|
||||
|
||||
void dlg_redraw (Dlg_head *h);
|
||||
void destroy_dlg (Dlg_head *h);
|
||||
|
||||
void widget_set_size (Widget *widget, int x1, int y1, int x2, int y2);
|
||||
|
||||
void dlg_broadcast_msg (Dlg_head *h, widget_msg_t message, int reverse);
|
||||
|
||||
void init_widget (Widget *w, int y, int x, int lines, int cols,
|
||||
callback_fn callback, mouse_h mouse_handler);
|
||||
|
||||
/* Default callback for dialogs */
|
||||
cb_ret_t default_dlg_callback (Dlg_head *h, dlg_msg_t msg, int parm);
|
||||
|
||||
/* Default callback for widgets */
|
||||
cb_ret_t default_proc (widget_msg_t msg, int parm);
|
||||
|
||||
/* Default paint routine for dialogs */
|
||||
void common_dialog_repaint (struct Dlg_head *h);
|
||||
|
||||
#define widget_move(w, _y, _x) move(((Widget *)(w))->y + _y, \
|
||||
((Widget *)(w))->x + _x)
|
||||
#define dlg_move(h, _y, _x) move(((Dlg_head *)(h))->y + _y, \
|
||||
((Dlg_head *)(h))->x + _x)
|
||||
|
||||
extern Dlg_head *current_dlg;
|
||||
|
||||
/* A hook list for idle events */
|
||||
extern Hook *idle_hook;
|
||||
|
||||
static inline cb_ret_t
|
||||
send_message (Widget *w, widget_msg_t msg, int parm)
|
||||
{
|
||||
return (*(w->callback)) (w, msg, parm);
|
||||
}
|
||||
|
||||
void dlg_replace_widget (Dlg_head *h, Widget *old, Widget *new);
|
||||
int dlg_overlap (Widget *a, Widget *b);
|
||||
void widget_erase (Widget *);
|
||||
void dlg_erase (Dlg_head *h);
|
||||
void dlg_stop (Dlg_head *h);
|
||||
|
||||
/* Widget selection */
|
||||
int dlg_select_widget (Dlg_head *h, void *widget);
|
||||
void dlg_one_up (Dlg_head *h);
|
||||
void dlg_one_down (Dlg_head *h);
|
||||
int dlg_focus (Dlg_head *h);
|
||||
Widget *find_widget_type (Dlg_head *h, void *callback);
|
||||
void dlg_select_by_id (Dlg_head *h, int id);
|
||||
|
||||
/* Sets/clear the specified flag in the options field */
|
||||
#define widget_option(w,f,i) \
|
||||
w.options = ((i) ? (w.options | (f)) : (w.options & (~(f))))
|
||||
|
||||
#define widget_want_cursor(w,i) widget_option(w, W_WANT_CURSOR, i)
|
||||
#define widget_want_hotkey(w,i) widget_option(w, W_WANT_HOTKEY, i)
|
||||
|
||||
/* Used in load_prompt() */
|
||||
void update_cursor (Dlg_head *h);
|
||||
|
||||
#endif /* MC_DLG_H */
|
@ -71,12 +71,10 @@
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "eregex.h"
|
||||
#include "dialog.h"
|
||||
#include "setup.h"
|
||||
/* Needed by query_replace */
|
||||
#include "color.h"
|
||||
#include "win.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#define WANT_WIDGETS
|
||||
#include "main.h" /* WANT_WIDGETS-> we get the the_hint def */
|
||||
|
@ -73,9 +73,8 @@
|
||||
|
||||
#include "global.h"
|
||||
#include "setup.h" /* verbose */
|
||||
#include "dialog.h" /* do_refresh */
|
||||
#include "dialog.h" /* do_refresh() */
|
||||
#include "color.h" /* dialog_colors */
|
||||
#include "dlg.h" /* B_ENTER */
|
||||
#include "background.h" /* message_3s */
|
||||
#include "widget.h" /* WLabel */
|
||||
#define WANT_WIDGETS
|
||||
|
@ -32,10 +32,9 @@
|
||||
#include "find.h"
|
||||
|
||||
/* Dialog manager and widgets */
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "dir.h"
|
||||
#include "panel.h" /* current_panel */
|
||||
#include "main.h" /* do_cd, try_to_select */
|
||||
|
@ -45,12 +45,11 @@
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "color.h"
|
||||
#include "dialog.h"
|
||||
#include "win.h"
|
||||
#include "mouse.h"
|
||||
#include "key.h" /* For mi_getch() */
|
||||
#include "key.h" /* For mi_getch() */
|
||||
#include "help.h"
|
||||
#include "dlg.h" /* For Dlg_head */
|
||||
#include "dialog.h" /* For Dlg_head */
|
||||
#include "widget.h" /* For Widget */
|
||||
#include "wtools.h" /* For common_dialog_repaint() */
|
||||
|
||||
|
@ -39,9 +39,8 @@
|
||||
#include "global.h"
|
||||
#include "tty.h" /* COLS */
|
||||
#include "color.h" /* dialog_colors */
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h" /* do_refresh() */
|
||||
#include "setup.h" /* For profile_bname */
|
||||
#include "profile.h" /* Load/save directories hotlist */
|
||||
#include "wtools.h" /* QuickDialog */
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "tty.h"
|
||||
#include "mouse.h" /* Gpm_Event */
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "info.h"
|
||||
#include "dir.h" /* required by panel */
|
||||
#include "panel.h" /* for the panel structure */
|
||||
|
@ -45,10 +45,9 @@
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "key.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "command.h"
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "profile.h" /* For sync_profiles() */
|
||||
#include "mouse.h"
|
||||
#define WANT_WIDGETS
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __LAYOUT_H
|
||||
#define __LAYOUT_H
|
||||
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
|
||||
void layout_cmd (void);
|
||||
void init_curses (void);
|
||||
|
@ -32,9 +32,8 @@
|
||||
#include "tty.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "profile.h" /* Save profile */
|
||||
#include "key.h"
|
||||
#include "setup.h"
|
||||
|
@ -35,9 +35,8 @@
|
||||
#include "tty.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "wtools.h"
|
||||
|
||||
/* Needed for the extern declarations of integer parameters */
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __MENU_H
|
||||
#define __MENU_H
|
||||
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
|
||||
typedef void (*callfn) (void);
|
||||
|
@ -30,10 +30,9 @@
|
||||
#include "tty.h"
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "setup.h" /* For save_setup() */
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "main.h"
|
||||
#include "profile.h" /* For sync_profiles */
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __PANEL_H
|
||||
|
||||
#include "dir.h" /* dir_list */
|
||||
#include "dlg.h" /* Widget */
|
||||
#include "dialog.h" /* Widget */
|
||||
|
||||
#define selection(p) (&(p->dir.list[p->selected]))
|
||||
#define other_panel get_other_panel()
|
||||
|
@ -33,9 +33,8 @@
|
||||
#include "tty.h" /* attrset() */
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "wtools.h" /* For common_dialog_repaint() */
|
||||
#include "setup.h" /* For profile_bname */
|
||||
#include "profile.h" /* Load/save directories panelize */
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "wtools.h"
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "color.h"
|
||||
#include "wtools.h" /* message() */
|
||||
#include "dir.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "panel.h"
|
||||
#include "mouse.h"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __TREE_H
|
||||
#define __TREE_H
|
||||
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
|
||||
struct WTree;
|
||||
typedef struct WTree WTree;
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "dialog.h"
|
||||
#include "color.h"
|
||||
#include "dir.h"
|
||||
#include "panel.h"
|
||||
@ -38,7 +37,7 @@
|
||||
#include "edit/edit-widget.h" /* WEdit */
|
||||
|
||||
/* For the simple listbox manager */
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "wtools.h"
|
||||
|
||||
|
@ -39,10 +39,9 @@
|
||||
#include "global.h"
|
||||
#include "tty.h"
|
||||
#include "cmd.h" /* For view_other_cmd */
|
||||
#include "dlg.h" /* Needed by widget.h */
|
||||
#include "dialog.h" /* Needed by widget.h */
|
||||
#include "widget.h" /* Needed for buttonbar_new */
|
||||
#include "color.h"
|
||||
#include "dialog.h"
|
||||
#include "mouse.h"
|
||||
#include "help.h"
|
||||
#include "key.h" /* For mi_getch() */
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "tty.h"
|
||||
#include "color.h"
|
||||
#include "mouse.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "win.h"
|
||||
#include "complete.h"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __WIDGET_H
|
||||
#define __WIDGET_H
|
||||
|
||||
#include "dlg.h" /* Widget */
|
||||
#include "dialog.h" /* Widget */
|
||||
|
||||
#define C_BOOL 1
|
||||
#define C_CHANGE 2
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "tty.h"
|
||||
#include "color.h"
|
||||
#include "mouse.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "win.h"
|
||||
#include "key.h" /* XCTRL and ALT macros */
|
||||
|
@ -38,12 +38,11 @@
|
||||
#include "win.h"
|
||||
#include "color.h"
|
||||
#include "mouse.h"
|
||||
#include "dlg.h"
|
||||
#include "dialog.h"
|
||||
#include "widget.h"
|
||||
#include "menu.h"
|
||||
#include "wtools.h"
|
||||
#include "key.h" /* For mi_getch() */
|
||||
#include "dialog.h" /* For do_refresh() */
|
||||
#include "complete.h" /* INPUT_COMPLETE_CD */
|
||||
|
||||
/* }}} */
|
||||
|
Loading…
Reference in New Issue
Block a user