2011-10-15 14:56:47 +04:00
|
|
|
/*
|
|
|
|
Dialog box features module for the Midnight Commander
|
|
|
|
|
2024-01-01 09:46:17 +03:00
|
|
|
Copyright (C) 1994-2024
|
2014-02-12 10:33:10 +04:00
|
|
|
Free Software Foundation, Inc.
|
2011-10-15 14:56:47 +04:00
|
|
|
|
|
|
|
This file is part of the Midnight Commander.
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander 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 3 of the License,
|
|
|
|
or (at your option) any later version.
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
The Midnight Commander is distributed in the hope that it will be useful,
|
1998-02-27 07:54:42 +03:00
|
|
|
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
|
2011-10-15 14:56:47 +04:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2003-10-25 03:20:30 +04:00
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2009-02-05 21:28:18 +03:00
|
|
|
/** \file dialog.c
|
|
|
|
* \brief Source: dialog box features module
|
|
|
|
*/
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <config.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
|
2003-10-25 03:20:30 +04:00
|
|
|
#include <ctype.h>
|
2011-05-02 13:44:47 +04:00
|
|
|
#include <errno.h>
|
2009-02-27 14:54:26 +03:00
|
|
|
#include <stdlib.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2011-05-02 13:44:47 +04:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
|
2010-01-20 18:11:52 +03:00
|
|
|
#include "lib/global.h"
|
2009-05-08 14:01:05 +04:00
|
|
|
|
2010-01-08 17:47:19 +03:00
|
|
|
#include "lib/tty/tty.h"
|
2010-01-21 16:06:15 +03:00
|
|
|
#include "lib/skin.h"
|
2010-01-08 17:47:19 +03:00
|
|
|
#include "lib/tty/key.h"
|
2010-01-21 15:17:26 +03:00
|
|
|
#include "lib/strutil.h"
|
2011-05-02 13:44:47 +04:00
|
|
|
#include "lib/fileloc.h" /* MC_HISTORY_FILE */
|
2011-02-17 15:02:31 +03:00
|
|
|
#include "lib/event.h" /* mc_event_raise() */
|
2018-09-03 14:25:30 +03:00
|
|
|
#include "lib/util.h" /* MC_PTR_FREE */
|
2019-07-28 15:24:00 +03:00
|
|
|
#include "lib/mcconfig.h" /* num_history_items_recorded */
|
2010-04-18 14:58:18 +04:00
|
|
|
|
2016-03-06 09:44:16 +03:00
|
|
|
#include "lib/widget.h"
|
|
|
|
#include "lib/widget/mouse.h"
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
|
2009-05-30 21:39:02 +04:00
|
|
|
/* Color styles for normal and error dialogs */
|
2010-10-12 13:33:09 +04:00
|
|
|
dlg_colors_t dialog_colors;
|
|
|
|
dlg_colors_t alarm_colors;
|
2014-02-08 19:37:11 +04:00
|
|
|
dlg_colors_t listbox_colors;
|
2009-05-30 21:39:02 +04:00
|
|
|
|
2003-10-25 03:20:30 +04:00
|
|
|
/* A hook list for idle events */
|
2010-11-09 11:08:20 +03:00
|
|
|
hook_t *idle_hook = NULL;
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2009-04-03 19:29:20 +04:00
|
|
|
/* left click outside of dialog closes it */
|
2016-11-25 10:39:08 +03:00
|
|
|
gboolean mouse_close_dialog = FALSE;
|
2009-04-03 19:29:20 +04:00
|
|
|
|
2011-07-14 21:34:55 +04:00
|
|
|
const global_keymap_t *dialog_map = NULL;
|
2011-02-16 18:19:48 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** file scope macro definitions ****************************************************************/
|
2009-10-30 14:50:04 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** file scope type declarations ****************************************************************/
|
2009-10-30 14:50:04 +03:00
|
|
|
|
Update template for .c files.
Add section for forward declarations of local functions. This section is
located before file scope variables because functions can be used in
strucutres (see find.c for example):
/*** forward declarations (file scope functions) *************************************************/
/* button callbacks */
static int start_stop (WButton * button, int action);
static int find_do_view_file (WButton * button, int action);
static int find_do_edit_file (WButton * button, int action);
/*** file scope variables ************************************************************************/
static struct
{
...
bcback_fn callback;
} fbuts[] =
{
...
{ B_STOP, NORMAL_BUTTON, N_("S&uspend"), 0, 0, NULL, start_stop },
...
{ B_VIEW, NORMAL_BUTTON, N_("&View - F3"), 0, 0, NULL, find_do_view_file },
{ B_VIEW, NORMAL_BUTTON, N_("&Edit - F4"), 0, 0, NULL, find_do_edit_file }
};
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2023-02-24 09:27:11 +03:00
|
|
|
/*** forward declarations (file scope functions) *************************************************/
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** file scope variables ************************************************************************/
|
2010-09-01 14:28:10 +04:00
|
|
|
|
2016-06-18 20:29:46 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** file scope functions ************************************************************************/
|
2011-07-18 13:27:01 +04:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2019-11-17 17:58:52 +03:00
|
|
|
static const int *
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_default_get_colors (const Widget *w)
|
2019-11-17 17:58:52 +03:00
|
|
|
{
|
|
|
|
return CONST_DIALOG (w)->colors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2011-05-03 17:24:56 +04:00
|
|
|
/**
|
2023-10-29 15:05:12 +03:00
|
|
|
* Read histories from the ${XDG_DATA_HOME}/mc/history file
|
2011-05-03 17:24:56 +04:00
|
|
|
*/
|
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_read_history (WDialog *h)
|
2011-05-03 17:24:56 +04:00
|
|
|
{
|
|
|
|
char *profile;
|
|
|
|
ev_history_load_save_t event_data;
|
|
|
|
|
|
|
|
if (num_history_items_recorded == 0) /* this is how to disable */
|
|
|
|
return;
|
|
|
|
|
2011-11-24 02:28:07 +04:00
|
|
|
profile = mc_config_get_full_path (MC_HISTORY_FILE);
|
2012-07-28 14:19:27 +04:00
|
|
|
event_data.cfg = mc_config_init (profile, TRUE);
|
2011-05-03 17:24:56 +04:00
|
|
|
event_data.receiver = NULL;
|
|
|
|
|
|
|
|
/* create all histories in dialog */
|
|
|
|
mc_event_raise (h->event_group, MCEVENT_HISTORY_LOAD, &event_data);
|
|
|
|
|
|
|
|
mc_config_deinit (event_data.cfg);
|
|
|
|
g_free (profile);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
static void
|
|
|
|
refresh_cmd (void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_SLANG
|
|
|
|
tty_touch_screen ();
|
|
|
|
mc_refresh ();
|
|
|
|
#else
|
|
|
|
/* Use this if the refreshes fail */
|
2020-10-31 14:26:10 +03:00
|
|
|
tty_clear_screen ();
|
2010-11-10 14:09:42 +03:00
|
|
|
repaint_screen ();
|
|
|
|
#endif /* HAVE_SLANG */
|
2009-05-30 21:39:02 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2023-12-09 17:25:48 +03:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_help (const WDialog *h)
|
2023-12-09 17:25:48 +03:00
|
|
|
{
|
|
|
|
ev_help_t event_data = { NULL, h->help_ctx };
|
|
|
|
|
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "help", &event_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
static cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_execute_cmd (WDialog *h, long command)
|
2009-10-30 14:50:04 +03:00
|
|
|
{
|
2016-09-27 16:16:38 +03:00
|
|
|
WGroup *g = GROUP (h);
|
2010-11-10 14:09:42 +03:00
|
|
|
cb_ret_t ret = MSG_HANDLED;
|
2019-03-06 14:29:49 +03:00
|
|
|
|
|
|
|
if (send_message (h, NULL, MSG_ACTION, command, NULL) == MSG_HANDLED)
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
switch (command)
|
|
|
|
{
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Ok:
|
2010-11-10 14:09:42 +03:00
|
|
|
h->ret_value = B_ENTER;
|
2023-04-15 10:17:41 +03:00
|
|
|
dlg_close (h);
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Cancel:
|
2010-11-10 14:09:42 +03:00
|
|
|
h->ret_value = B_CANCEL;
|
2023-04-15 10:17:41 +03:00
|
|
|
dlg_close (h);
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
|
|
|
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Up:
|
|
|
|
case CK_Left:
|
2016-09-27 16:16:38 +03:00
|
|
|
group_select_prev_widget (g);
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Down:
|
|
|
|
case CK_Right:
|
2016-09-27 16:16:38 +03:00
|
|
|
group_select_next_widget (g);
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
|
|
|
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Help:
|
2023-12-09 17:25:48 +03:00
|
|
|
dlg_help (h);
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
|
|
|
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Suspend:
|
2011-02-18 15:13:44 +03:00
|
|
|
mc_event_raise (MCEVENT_GROUP_CORE, "suspend", NULL);
|
2010-11-10 14:09:42 +03:00
|
|
|
refresh_cmd ();
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_Refresh:
|
2010-11-10 14:09:42 +03:00
|
|
|
refresh_cmd ();
|
|
|
|
break;
|
|
|
|
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_ScreenList:
|
2016-04-16 11:12:49 +03:00
|
|
|
if (!widget_get_state (WIDGET (h), WST_MODAL))
|
2010-11-10 14:09:42 +03:00
|
|
|
dialog_switch_list ();
|
|
|
|
else
|
|
|
|
ret = MSG_NOT_HANDLED;
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_ScreenNext:
|
2016-04-16 11:12:49 +03:00
|
|
|
if (!widget_get_state (WIDGET (h), WST_MODAL))
|
2010-11-10 14:09:42 +03:00
|
|
|
dialog_switch_next ();
|
|
|
|
else
|
|
|
|
ret = MSG_NOT_HANDLED;
|
|
|
|
break;
|
2011-01-21 11:47:27 +03:00
|
|
|
case CK_ScreenPrev:
|
2016-04-16 11:12:49 +03:00
|
|
|
if (!widget_get_state (WIDGET (h), WST_MODAL))
|
2010-11-10 14:09:42 +03:00
|
|
|
dialog_switch_prev ();
|
|
|
|
else
|
|
|
|
ret = MSG_NOT_HANDLED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = MSG_NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2009-10-30 14:50:04 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_handle_key (WDialog *h, int d_key)
|
2003-10-25 03:20:30 +04:00
|
|
|
{
|
2015-11-21 18:15:11 +03:00
|
|
|
long command;
|
2011-10-27 14:58:54 +04:00
|
|
|
|
2017-03-08 14:41:35 +03:00
|
|
|
command = widget_lookup_key (WIDGET (h), d_key);
|
2020-11-05 18:46:08 +03:00
|
|
|
if (command == CK_IgnoreKey)
|
|
|
|
command = keybind_lookup_keymap_command (dialog_map, d_key);
|
2019-03-06 14:29:49 +03:00
|
|
|
if (command != CK_IgnoreKey)
|
|
|
|
return dlg_execute_cmd (h, command);
|
2011-10-27 14:58:54 +04:00
|
|
|
|
|
|
|
return MSG_NOT_HANDLED;
|
2003-10-25 03:20:30 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2003-10-25 03:20:30 +04:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_key_event (WDialog *h, int d_key)
|
2003-10-25 03:20:30 +04:00
|
|
|
{
|
2019-09-11 14:25:58 +03:00
|
|
|
Widget *w = WIDGET (h);
|
2016-09-27 13:53:17 +03:00
|
|
|
WGroup *g = GROUP (h);
|
2010-11-10 14:09:42 +03:00
|
|
|
cb_ret_t handled;
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g->widgets == NULL)
|
2010-04-06 11:16:11 +04:00
|
|
|
return;
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2016-09-27 13:53:17 +03:00
|
|
|
if (g->current == NULL)
|
|
|
|
g->current = g->widgets;
|
2010-04-05 20:59:21 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* TAB used to cycle */
|
2019-09-11 14:25:58 +03:00
|
|
|
if (!widget_get_options (w, WOP_WANT_TAB))
|
2010-04-05 20:59:21 +04:00
|
|
|
{
|
2010-11-10 14:09:42 +03:00
|
|
|
if (d_key == '\t')
|
|
|
|
{
|
2016-09-27 16:16:38 +03:00
|
|
|
group_select_next_widget (g);
|
2010-11-10 14:09:42 +03:00
|
|
|
return;
|
|
|
|
}
|
Handle newline and tab with shift/ctrl modifiers correctly.
MC already has its own half-ready trick: when pasting with Shift-Insert,
using the X11 extension, the newline ("Enter" as mc calls it) with the
Shift modifier pressed gets converted to a "Return", and in the editor
the Return character inserts a non-indenting newline. This makes pasting
better in terminals not supporting bracketed paste, however, it has some
problems that this commit addresses:
* Shift+newline gets this special treatment, but Ctrl+newline gets
dropped. Hence e.g. when pasting in Gnome-terminal with Ctrl+Shift+V
all the newlines will be missing. This commit adds the same
non-indenting newline behavior to Ctrl+Newline and Ctrl+Shift+Newline.
* The code forgets about Tab that also needs special treatment:
- Most terminals send \e[Z on Shift+Tab, this is not handled by MC
at all, moreover it causes a hang for about a second. This commit
teaches this sequence to MC. This is especially useful when no X11
is available, because there Ctrl+Tab is identical to Tab, so the
backwards tab feature is not available. With this commit Shift+Tab
becomes a backwards tab too on all terminals that emit \e[Z.
- When pasting to the editor, Shift+Tab, Ctrl+Tab and Ctrl+Shift+Tab
should all insert a tab for the same reason mentioned at the newline.
- It would look inconsistent in the keymap files to have logical code
such as "backtab" instead of "shift-tab" and friends, hence get rid
of KEY_BTAB and use KEY_M_SHIFT | '\t' instead.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
2013-10-01 14:09:14 +04:00
|
|
|
else if ((d_key & ~(KEY_M_SHIFT | KEY_M_CTRL)) == '\t')
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2016-09-27 16:16:38 +03:00
|
|
|
group_select_prev_widget (g);
|
2010-11-10 14:09:42 +03:00
|
|
|
return;
|
|
|
|
}
|
2010-04-05 20:59:21 +04:00
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2016-11-22 14:44:08 +03:00
|
|
|
/* first can dlalog handle the key itself */
|
2012-09-28 15:05:43 +04:00
|
|
|
handled = send_message (h, NULL, MSG_KEY, d_key, NULL);
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
if (handled == MSG_NOT_HANDLED)
|
2019-09-11 14:25:58 +03:00
|
|
|
handled = group_default_callback (w, NULL, MSG_KEY, d_key, NULL);
|
2010-04-05 20:59:21 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (handled == MSG_NOT_HANDLED)
|
|
|
|
handled = dlg_handle_key (h, d_key);
|
2010-04-06 11:16:11 +04:00
|
|
|
|
2013-10-10 16:21:26 +04:00
|
|
|
(void) handled;
|
2012-09-28 15:05:43 +04:00
|
|
|
send_message (h, NULL, MSG_POST_KEY, d_key, NULL);
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-11-15 09:33:34 +03:00
|
|
|
static int
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_handle_mouse_event (Widget *w, Gpm_Event *event)
|
2016-11-15 09:33:34 +03:00
|
|
|
{
|
|
|
|
if (w->mouse_callback != NULL)
|
|
|
|
{
|
|
|
|
int mou;
|
|
|
|
|
|
|
|
mou = mouse_handle_event (w, event);
|
|
|
|
if (mou != MOU_UNHANDLED)
|
|
|
|
return mou;
|
|
|
|
}
|
|
|
|
|
|
|
|
return group_handle_mouse_event (w, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
frontend_dlg_run (WDialog *h)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2016-04-10 20:02:59 +03:00
|
|
|
Widget *wh = WIDGET (h);
|
2010-11-10 14:09:42 +03:00
|
|
|
Gpm_Event event;
|
|
|
|
|
|
|
|
event.x = -1;
|
|
|
|
|
|
|
|
/* close opened editors, viewers, etc */
|
2016-04-16 11:12:49 +03:00
|
|
|
if (!widget_get_state (wh, WST_MODAL) && mc_global.midnight_shutdown)
|
2010-04-06 11:16:11 +04:00
|
|
|
{
|
2012-09-28 15:05:43 +04:00
|
|
|
send_message (h, NULL, MSG_VALIDATE, 0, NULL);
|
2010-11-10 14:09:42 +03:00
|
|
|
return;
|
|
|
|
}
|
2010-04-05 20:59:21 +04:00
|
|
|
|
2016-04-10 20:02:59 +03:00
|
|
|
while (widget_get_state (wh, WST_ACTIVE))
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
int d_key;
|
|
|
|
|
2019-08-17 17:55:50 +03:00
|
|
|
if (tty_got_winch ())
|
2011-02-18 14:30:15 +03:00
|
|
|
dialog_change_screen_size ();
|
2010-04-05 20:59:21 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (is_idle ())
|
2010-04-05 20:59:21 +04:00
|
|
|
{
|
2010-11-10 14:09:42 +03:00
|
|
|
if (idle_hook)
|
|
|
|
execute_hooks (idle_hook);
|
2010-04-05 20:59:21 +04:00
|
|
|
|
2016-04-10 20:02:59 +03:00
|
|
|
while (widget_get_state (wh, WST_IDLE) && is_idle ())
|
|
|
|
send_message (wh, NULL, MSG_IDLE, 0, NULL);
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
/* Allow terminating the dialog from the idle handler */
|
2016-04-10 20:02:59 +03:00
|
|
|
if (!widget_get_state (wh, WST_ACTIVE))
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
2010-04-05 20:59:21 +04:00
|
|
|
}
|
|
|
|
|
2016-09-30 11:03:57 +03:00
|
|
|
widget_update_cursor (wh);
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
/* Clear interrupt flag */
|
|
|
|
tty_got_interrupt ();
|
2016-11-15 09:33:34 +03:00
|
|
|
d_key = tty_get_event (&event, GROUP (h)->mouse_status == MOU_REPEAT, TRUE);
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
dlg_process_event (h, d_key, &event);
|
|
|
|
|
2016-04-10 20:02:59 +03:00
|
|
|
if (widget_get_state (wh, WST_CLOSED))
|
2012-09-28 15:05:43 +04:00
|
|
|
send_message (h, NULL, MSG_VALIDATE, 0, NULL);
|
2010-04-06 11:16:11 +04:00
|
|
|
}
|
2003-10-25 03:20:30 +04:00
|
|
|
}
|
|
|
|
|
2020-10-31 19:32:29 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_default_destroy (Widget *w)
|
2020-10-31 19:32:29 +03:00
|
|
|
{
|
|
|
|
WDialog *h = DIALOG (w);
|
|
|
|
|
|
|
|
/* if some widgets have history, save all histories at one moment here */
|
|
|
|
dlg_save_history (h);
|
|
|
|
group_default_callback (w, NULL, MSG_DESTROY, 0, NULL);
|
2023-03-11 21:59:47 +03:00
|
|
|
send_message (w, NULL, MSG_DESTROY, 0, NULL);
|
2020-10-31 19:32:29 +03:00
|
|
|
mc_event_group_del (h->event_group);
|
|
|
|
g_free (h->event_group);
|
|
|
|
g_free (h);
|
|
|
|
|
|
|
|
do_refresh ();
|
|
|
|
}
|
|
|
|
|
2016-10-13 10:15:03 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/*** public functions ****************************************************************************/
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** Default dialog callback */
|
|
|
|
|
|
|
|
cb_ret_t
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_default_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
|
2003-11-27 11:59:54 +03:00
|
|
|
{
|
2010-11-10 14:09:42 +03:00
|
|
|
switch (msg)
|
2010-04-05 20:59:21 +04:00
|
|
|
{
|
2021-01-01 13:49:26 +03:00
|
|
|
case MSG_INIT:
|
|
|
|
/* nothing to init in dialog itself */
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
case MSG_IDLE:
|
2016-04-10 12:35:43 +03:00
|
|
|
/* we don't want endless loop */
|
|
|
|
widget_idle (w, FALSE);
|
2010-11-10 14:09:42 +03:00
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2021-01-01 13:49:26 +03:00
|
|
|
case MSG_DESTROY:
|
|
|
|
/* nothing to deinit in dialog itself */
|
|
|
|
return MSG_HANDLED;
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
default:
|
2016-09-28 14:34:08 +03:00
|
|
|
return group_default_callback (w, sender, msg, parm, data);
|
2010-04-05 20:59:21 +04:00
|
|
|
}
|
2003-11-27 11:59:54 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2016-11-15 09:33:34 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_default_mouse_callback (Widget *w, mouse_msg_t msg, mouse_event_t *event)
|
2016-11-15 09:33:34 +03:00
|
|
|
{
|
|
|
|
switch (msg)
|
|
|
|
{
|
|
|
|
case MSG_MOUSE_CLICK:
|
2022-05-01 10:43:33 +03:00
|
|
|
if (event->y < 0 || event->y >= w->rect.lines || event->x < 0 || event->x >= w->rect.cols)
|
2016-11-15 09:33:34 +03:00
|
|
|
{
|
|
|
|
DIALOG (w)->ret_value = B_CANCEL;
|
2023-04-15 10:17:41 +03:00
|
|
|
dlg_close (DIALOG (w));
|
2016-11-15 09:33:34 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* return MOU_UNHANDLED */
|
|
|
|
event->result.abort = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2012-09-28 11:18:45 +04:00
|
|
|
WDialog *
|
2016-05-08 21:10:05 +03:00
|
|
|
dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flags_t pos_flags,
|
|
|
|
gboolean compact, const int *colors, widget_cb_fn callback,
|
|
|
|
widget_mouse_cb_fn mouse_callback, const char *help_ctx, const char *title)
|
2003-10-25 03:20:30 +04:00
|
|
|
{
|
2022-05-21 19:30:17 +03:00
|
|
|
WRect r = { y1, x1, lines, cols };
|
2012-09-28 11:18:45 +04:00
|
|
|
WDialog *new_d;
|
2012-06-20 12:05:13 +04:00
|
|
|
Widget *w;
|
2016-10-16 11:01:30 +03:00
|
|
|
WGroup *g;
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2012-09-28 11:18:45 +04:00
|
|
|
new_d = g_new0 (WDialog, 1);
|
2012-06-20 12:05:13 +04:00
|
|
|
w = WIDGET (new_d);
|
2016-10-16 11:01:30 +03:00
|
|
|
g = GROUP (new_d);
|
2022-05-21 19:37:31 +03:00
|
|
|
widget_adjust_position (pos_flags, &r);
|
2022-05-21 19:30:17 +03:00
|
|
|
group_init (g, &r, callback != NULL ? callback : dlg_default_callback,
|
2016-11-15 09:33:34 +03:00
|
|
|
mouse_callback != NULL ? mouse_callback : dlg_default_mouse_callback);
|
2016-09-28 14:34:08 +03:00
|
|
|
|
2016-08-09 10:04:46 +03:00
|
|
|
w->pos_flags = pos_flags;
|
2016-06-07 15:03:20 +03:00
|
|
|
w->options |= WOP_SELECTABLE | WOP_TOP_SELECT;
|
2019-12-19 16:47:05 +03:00
|
|
|
w->state |= WST_FOCUSED;
|
2016-10-30 12:40:20 +03:00
|
|
|
/* Temporary hack: dialog doesn't have an owner, own itself. */
|
|
|
|
w->owner = g;
|
2012-06-20 12:05:13 +04:00
|
|
|
|
2017-03-08 14:41:35 +03:00
|
|
|
w->keymap = dialog_map;
|
|
|
|
|
2016-11-15 09:33:34 +03:00
|
|
|
w->mouse_handler = dlg_handle_mouse_event;
|
|
|
|
w->mouse.forced_capture = mouse_close_dialog && (w->pos_flags & WPOS_FULLSCREEN) == 0;
|
|
|
|
|
2020-10-31 19:32:29 +03:00
|
|
|
w->destroy = dlg_default_destroy;
|
2019-11-17 17:58:52 +03:00
|
|
|
w->get_colors = dlg_default_get_colors;
|
|
|
|
|
|
|
|
new_d->colors = colors;
|
2010-11-10 14:09:42 +03:00
|
|
|
new_d->help_ctx = help_ctx;
|
2016-05-08 21:10:05 +03:00
|
|
|
new_d->compact = compact;
|
2023-02-23 11:53:17 +03:00
|
|
|
new_d->data.p = NULL;
|
2010-06-29 11:20:48 +04:00
|
|
|
|
2016-10-16 11:01:30 +03:00
|
|
|
if (modal)
|
|
|
|
{
|
|
|
|
w->state |= WST_MODAL;
|
|
|
|
|
2022-05-01 10:43:33 +03:00
|
|
|
new_d->bg =
|
|
|
|
WIDGET (frame_new (0, 0, w->rect.lines, w->rect.cols, title, FALSE, new_d->compact));
|
2016-10-16 19:45:50 +03:00
|
|
|
group_add_widget (g, new_d->bg);
|
|
|
|
frame_set_title (FRAME (new_d->bg), title);
|
2016-10-16 11:01:30 +03:00
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2013-08-13 10:58:10 +04:00
|
|
|
/* unique name of event group for this dialog */
|
2011-05-01 15:42:17 +04:00
|
|
|
new_d->event_group = g_strdup_printf ("%s_%p", MCEVENT_GROUP_DIALOG, (void *) new_d);
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
return new_d;
|
2003-10-25 03:20:30 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-11-08 12:43:37 +03:00
|
|
|
void
|
2010-11-10 14:09:42 +03:00
|
|
|
dlg_set_default_colors (void)
|
2003-10-25 03:20:30 +04:00
|
|
|
{
|
2010-11-10 14:09:42 +03:00
|
|
|
dialog_colors[DLG_COLOR_NORMAL] = COLOR_NORMAL;
|
|
|
|
dialog_colors[DLG_COLOR_FOCUS] = COLOR_FOCUS;
|
|
|
|
dialog_colors[DLG_COLOR_HOT_NORMAL] = COLOR_HOT_NORMAL;
|
|
|
|
dialog_colors[DLG_COLOR_HOT_FOCUS] = COLOR_HOT_FOCUS;
|
|
|
|
dialog_colors[DLG_COLOR_TITLE] = COLOR_TITLE;
|
2010-06-05 18:48:06 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
alarm_colors[DLG_COLOR_NORMAL] = ERROR_COLOR;
|
|
|
|
alarm_colors[DLG_COLOR_FOCUS] = ERROR_FOCUS;
|
|
|
|
alarm_colors[DLG_COLOR_HOT_NORMAL] = ERROR_HOT_NORMAL;
|
|
|
|
alarm_colors[DLG_COLOR_HOT_FOCUS] = ERROR_HOT_FOCUS;
|
|
|
|
alarm_colors[DLG_COLOR_TITLE] = ERROR_TITLE;
|
2014-02-08 19:37:11 +04:00
|
|
|
|
|
|
|
listbox_colors[DLG_COLOR_NORMAL] = PMENU_ENTRY_COLOR;
|
|
|
|
listbox_colors[DLG_COLOR_FOCUS] = PMENU_SELECTED_COLOR;
|
|
|
|
listbox_colors[DLG_COLOR_HOT_NORMAL] = PMENU_ENTRY_COLOR;
|
|
|
|
listbox_colors[DLG_COLOR_HOT_FOCUS] = PMENU_SELECTED_COLOR;
|
|
|
|
listbox_colors[DLG_COLOR_TITLE] = PMENU_TITLE_COLOR;
|
2003-10-25 03:20:30 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_close (WDialog *h)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2016-04-10 20:02:59 +03:00
|
|
|
widget_set_state (WIDGET (h), WST_CLOSED, TRUE);
|
2003-10-25 03:20:30 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** Init the process */
|
|
|
|
|
2009-11-08 12:43:37 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_init (WDialog *h)
|
2003-10-25 03:20:30 +04:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
WGroup *g = GROUP (h);
|
2016-04-10 20:02:59 +03:00
|
|
|
Widget *wh = WIDGET (h);
|
|
|
|
|
2016-04-16 11:12:49 +03:00
|
|
|
if (top_dlg != NULL && widget_get_state (WIDGET (top_dlg->data), WST_MODAL))
|
|
|
|
widget_set_state (wh, WST_MODAL, TRUE);
|
2009-11-19 11:34:20 +03:00
|
|
|
|
2009-10-30 14:50:04 +03:00
|
|
|
/* add dialog to the stack */
|
2010-04-18 14:26:28 +04:00
|
|
|
top_dlg = g_list_prepend (top_dlg, h);
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2009-10-30 14:50:04 +03:00
|
|
|
/* Initialize dialog manager and widgets */
|
2016-04-10 20:02:59 +03:00
|
|
|
if (widget_get_state (wh, WST_CONSTRUCT))
|
2010-04-18 14:58:18 +04:00
|
|
|
{
|
2016-04-16 11:12:49 +03:00
|
|
|
if (!widget_get_state (wh, WST_MODAL))
|
2010-04-18 14:58:18 +04:00
|
|
|
dialog_switch_add (h);
|
|
|
|
|
2012-09-28 15:05:43 +04:00
|
|
|
send_message (h, NULL, MSG_INIT, 0, NULL);
|
2016-09-28 14:34:08 +03:00
|
|
|
group_default_callback (wh, NULL, MSG_INIT, 0, NULL);
|
2011-05-03 17:24:56 +04:00
|
|
|
dlg_read_history (h);
|
2010-04-18 14:58:18 +04:00
|
|
|
}
|
|
|
|
|
2016-07-16 21:00:28 +03:00
|
|
|
/* Select the first widget that takes focus */
|
2019-08-11 14:37:43 +03:00
|
|
|
while (g->current != NULL && !widget_is_focusable (g->current->data))
|
2016-09-27 16:16:38 +03:00
|
|
|
group_set_current_widget_next (g);
|
2012-04-08 16:29:46 +04:00
|
|
|
|
2016-07-16 21:00:28 +03:00
|
|
|
widget_set_state (wh, WST_ACTIVE, TRUE);
|
2023-01-01 16:09:07 +03:00
|
|
|
widget_draw (wh);
|
2011-04-17 14:21:17 +04:00
|
|
|
|
2003-10-25 03:20:30 +04:00
|
|
|
h->ret_value = 0;
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2009-11-08 12:43:37 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_process_event (WDialog *h, int key, Gpm_Event *event)
|
2010-04-06 11:16:11 +04:00
|
|
|
{
|
2019-03-06 14:29:49 +03:00
|
|
|
switch (key)
|
2010-04-06 11:16:11 +04:00
|
|
|
{
|
2019-03-06 14:29:49 +03:00
|
|
|
case EV_NONE:
|
2010-04-06 11:16:11 +04:00
|
|
|
if (tty_got_interrupt ())
|
2019-03-06 14:29:49 +03:00
|
|
|
dlg_execute_cmd (h, CK_Cancel);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EV_MOUSE:
|
2016-11-15 09:33:34 +03:00
|
|
|
{
|
|
|
|
Widget *w = WIDGET (h);
|
|
|
|
|
|
|
|
GROUP (h)->mouse_status = w->mouse_handler (w, event);
|
|
|
|
break;
|
|
|
|
}
|
2019-03-06 14:29:49 +03:00
|
|
|
|
|
|
|
default:
|
2010-04-06 11:16:11 +04:00
|
|
|
dlg_key_event (h, key);
|
2019-03-06 14:29:49 +03:00
|
|
|
break;
|
|
|
|
}
|
2003-10-25 03:20:30 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2013-06-24 11:40:53 +04:00
|
|
|
/** Shutdown the dlg_run */
|
2003-10-25 03:20:30 +04:00
|
|
|
|
2009-10-30 14:50:04 +03:00
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_run_done (WDialog *h)
|
2009-10-30 14:50:04 +03:00
|
|
|
{
|
2010-09-20 13:58:17 +04:00
|
|
|
top_dlg = g_list_remove (top_dlg, h);
|
|
|
|
|
2016-04-10 20:02:59 +03:00
|
|
|
if (widget_get_state (WIDGET (h), WST_CLOSED))
|
2010-04-18 14:58:18 +04:00
|
|
|
{
|
2016-09-27 13:53:17 +03:00
|
|
|
send_message (h, GROUP (h)->current == NULL ? NULL : WIDGET (GROUP (h)->current->data),
|
|
|
|
MSG_END, 0, NULL);
|
2016-04-16 11:12:49 +03:00
|
|
|
if (!widget_get_state (WIDGET (h), WST_MODAL))
|
2010-04-18 14:58:18 +04:00
|
|
|
dialog_switch_remove (h);
|
|
|
|
}
|
2009-10-30 14:50:04 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Standard run dialog routine
|
2003-10-25 03:20:30 +04:00
|
|
|
* 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
|
|
|
|
*/
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2010-04-06 11:16:11 +04:00
|
|
|
int
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_run (WDialog *h)
|
2003-10-25 03:20:30 +04:00
|
|
|
{
|
2013-06-24 11:40:53 +04:00
|
|
|
dlg_init (h);
|
|
|
|
frontend_dlg_run (h);
|
2003-10-25 03:20:30 +04:00
|
|
|
dlg_run_done (h);
|
|
|
|
return h->ret_value;
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2011-05-02 13:44:47 +04:00
|
|
|
/**
|
2023-10-29 15:05:12 +03:00
|
|
|
* Write history to the ${XDG_DATA_HOME}/mc/history file
|
2011-05-02 13:44:47 +04:00
|
|
|
*/
|
|
|
|
void
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_save_history (WDialog *h)
|
2011-05-02 13:44:47 +04:00
|
|
|
{
|
|
|
|
char *profile;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (num_history_items_recorded == 0) /* this is how to disable */
|
|
|
|
return;
|
|
|
|
|
2011-11-24 02:28:07 +04:00
|
|
|
profile = mc_config_get_full_path (MC_HISTORY_FILE);
|
2011-05-02 13:44:47 +04:00
|
|
|
i = open (profile, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
|
|
|
|
if (i != -1)
|
|
|
|
close (i);
|
|
|
|
|
|
|
|
/* Make sure the history is only readable by the user */
|
|
|
|
if (chmod (profile, S_IRUSR | S_IWUSR) != -1 || errno == ENOENT)
|
|
|
|
{
|
|
|
|
ev_history_load_save_t event_data;
|
|
|
|
|
2012-07-28 14:19:27 +04:00
|
|
|
event_data.cfg = mc_config_init (profile, FALSE);
|
2011-05-02 13:44:47 +04:00
|
|
|
event_data.receiver = NULL;
|
|
|
|
|
|
|
|
/* get all histories in dialog */
|
|
|
|
mc_event_raise (h->event_group, MCEVENT_HISTORY_SAVE, &event_data);
|
|
|
|
|
|
|
|
mc_config_save_file (event_data.cfg, NULL);
|
|
|
|
mc_config_deinit (event_data.cfg);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (profile);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
2010-04-18 14:23:06 +04:00
|
|
|
char *
|
2024-06-01 21:12:14 +03:00
|
|
|
dlg_get_title (const WDialog *h, size_t len)
|
2010-04-18 14:23:06 +04:00
|
|
|
{
|
|
|
|
char *t;
|
|
|
|
|
|
|
|
if (h == NULL)
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
if (h->get_title != NULL)
|
|
|
|
t = h->get_title (h, len);
|
|
|
|
else
|
|
|
|
t = g_strdup ("");
|
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|