2011-10-15 14:56:47 +04:00
|
|
|
/*
|
|
|
|
User Menu implementation
|
|
|
|
|
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
|
|
|
|
2013-04-14 17:38:37 +04:00
|
|
|
Written by:
|
|
|
|
Slava Zanko <slavazanko@gmail.com>, 2013
|
2013-08-16 10:36:43 +04:00
|
|
|
Andrew Borodin <aborodin@vmail.ru>, 2013
|
2013-04-14 17:38:37 +04:00
|
|
|
|
2011-10-15 14:56:47 +04:00
|
|
|
This file is part of the Midnight Commander.
|
2010-06-10 13:42:37 +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.
|
2010-06-10 13:42:37 +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/>.
|
|
|
|
*/
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-22 17:15:28 +03:00
|
|
|
/** \file usermenu.c
|
2009-02-05 21:28:18 +03:00
|
|
|
* \brief Source: user menu implementation
|
|
|
|
*/
|
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <config.h>
|
2005-02-08 12:04:03 +03:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
#include <ctype.h>
|
|
|
|
#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>
|
2001-09-03 09:07:40 +04:00
|
|
|
|
2010-01-20 18:11:52 +03:00
|
|
|
#include "lib/global.h"
|
2016-03-13 09:02:56 +03:00
|
|
|
#include "lib/fileloc.h"
|
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"
|
|
|
|
#include "lib/search.h"
|
2011-02-15 16:44:17 +03:00
|
|
|
#include "lib/vfs/vfs.h"
|
2010-01-21 15:17:26 +03:00
|
|
|
#include "lib/strutil.h"
|
2010-11-11 16:58:29 +03:00
|
|
|
#include "lib/util.h"
|
2010-01-21 15:17:26 +03:00
|
|
|
|
2023-03-11 10:01:04 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
|
|
|
#include "src/editor/edit.h" /* WEdit */
|
|
|
|
#endif
|
2010-06-10 13:42:37 +04:00
|
|
|
#include "src/viewer/mcviewer.h" /* for default_* externs */
|
2010-01-21 15:17:26 +03:00
|
|
|
|
2021-10-31 09:49:45 +03:00
|
|
|
#include "src/args.h" /* mc_run_param0 */
|
2010-11-22 17:15:28 +03:00
|
|
|
#include "src/execute.h"
|
|
|
|
#include "src/setup.h"
|
|
|
|
#include "src/history.h"
|
|
|
|
|
2017-10-15 19:43:31 +03:00
|
|
|
#include "src/filemanager/dir.h"
|
2020-08-19 09:33:24 +03:00
|
|
|
#include "src/filemanager/filemanager.h"
|
2017-10-15 19:43:31 +03:00
|
|
|
#include "src/filemanager/layout.h"
|
2002-11-29 06:03:53 +03:00
|
|
|
|
2010-11-22 17:15:28 +03:00
|
|
|
#include "usermenu.h"
|
2010-11-22 14:45:18 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** global variables ****************************************************************************/
|
|
|
|
|
|
|
|
/*** file scope macro definitions ****************************************************************/
|
|
|
|
|
1999-11-01 23:49:03 +03:00
|
|
|
#define MAX_ENTRIES 16
|
1998-02-27 07:54:42 +03:00
|
|
|
#define MAX_ENTRY_LEN 60
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** file scope type declarations ****************************************************************/
|
|
|
|
|
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 ************************************************************************/
|
|
|
|
|
2016-01-04 11:00:49 +03:00
|
|
|
static gboolean debug_flag = FALSE;
|
|
|
|
static gboolean debug_error = FALSE;
|
2000-05-25 20:21:42 +04:00
|
|
|
static char *menu = NULL;
|
1998-02-27 07:54:42 +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
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
2010-11-10 14:09:42 +03:00
|
|
|
/*** file scope functions ************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/** strip file's extension */
|
1998-12-03 00:27:27 +03:00
|
|
|
static char *
|
2010-06-10 13:42:37 +04:00
|
|
|
strip_ext (char *ss)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2023-10-14 18:56:25 +03:00
|
|
|
char *s;
|
1998-02-27 07:54:42 +03:00
|
|
|
char *e = NULL;
|
2016-01-04 10:26:18 +03:00
|
|
|
|
2023-10-14 18:25:29 +03:00
|
|
|
if (ss == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2023-10-14 18:56:25 +03:00
|
|
|
for (s = ss; *s != '\0'; s++)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
|
|
|
if (*s == '.')
|
|
|
|
e = s;
|
2015-01-07 11:34:53 +03:00
|
|
|
if (IS_PATH_SEP (*s) && e != NULL)
|
2010-06-10 13:42:37 +04:00
|
|
|
e = NULL; /* '.' in *directory* name */
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2023-10-14 18:56:25 +03:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (e != NULL)
|
|
|
|
*e = '\0';
|
2023-10-14 18:56:25 +03:00
|
|
|
|
2023-10-14 18:25:29 +03:00
|
|
|
return (*ss == '\0' ? NULL : ss);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
* Check for the "shell_patterns" directive. If it's found and valid,
|
|
|
|
* interpret it and move the pointer past the directive. Return the
|
|
|
|
* current pointer.
|
|
|
|
*/
|
2009-11-14 16:54:11 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
static char *
|
|
|
|
check_patterns (char *p)
|
|
|
|
{
|
|
|
|
static const char def_name[] = "shell_patterns=";
|
|
|
|
char *p0 = p;
|
2010-06-10 13:42:37 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (strncmp (p, def_name, sizeof (def_name) - 1) != 0)
|
|
|
|
return p0;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
p += sizeof (def_name) - 1;
|
|
|
|
if (*p == '1')
|
2016-11-25 09:17:03 +03:00
|
|
|
easy_patterns = TRUE;
|
2010-11-10 14:09:42 +03:00
|
|
|
else if (*p == '0')
|
2016-11-25 09:17:03 +03:00
|
|
|
easy_patterns = FALSE;
|
1999-11-01 23:49:03 +03:00
|
|
|
else
|
2010-11-10 14:09:42 +03:00
|
|
|
return p0;
|
1999-11-01 23:49:03 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* Skip spaces */
|
|
|
|
p++;
|
2016-12-11 21:31:22 +03:00
|
|
|
while (whiteness (*p))
|
2010-11-10 14:09:42 +03:00
|
|
|
p++;
|
|
|
|
return p;
|
|
|
|
}
|
2002-08-24 21:25:27 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** Copies a whitespace separated argument from p to arg. Returns the
|
|
|
|
point after argument. */
|
2005-06-23 01:38:52 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
static char *
|
|
|
|
extract_arg (char *p, char *arg, int size)
|
|
|
|
{
|
2016-12-11 21:31:22 +03:00
|
|
|
while (*p != '\0' && whiteness (*p))
|
2010-11-10 14:09:42 +03:00
|
|
|
p++;
|
2016-01-04 10:26:18 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* support quote space .mnu */
|
2016-01-04 10:26:18 +03:00
|
|
|
while (*p != '\0' && (*p != ' ' || *(p - 1) == '\\') && *p != '\t' && *p != '\n')
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
char *np;
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
np = str_get_next_char (p);
|
|
|
|
if (np - p >= size)
|
|
|
|
break;
|
|
|
|
memcpy (arg, p, np - p);
|
|
|
|
arg += np - p;
|
|
|
|
size -= np - p;
|
|
|
|
p = np;
|
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
*arg = '\0';
|
|
|
|
if (*p == '\0' || *p == '\n')
|
2010-11-10 14:09:42 +03:00
|
|
|
str_prev_char (&p);
|
|
|
|
return p;
|
|
|
|
}
|
2005-06-23 01:38:52 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/* Tests whether the selected file in the panel is of any of the types
|
|
|
|
specified in argument. */
|
2005-06-23 01:38:52 +04:00
|
|
|
|
2016-01-04 11:00:49 +03:00
|
|
|
static gboolean
|
2024-06-01 21:12:14 +03:00
|
|
|
test_type (WPanel *panel, char *arg)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
int result = 0; /* False by default */
|
2023-04-15 14:05:38 +03:00
|
|
|
mode_t st_mode;
|
|
|
|
|
|
|
|
st_mode = panel_current_entry (panel)->st.st_mode;
|
2005-06-23 01:38:52 +04:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
for (; *arg != '\0'; arg++)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
switch (*arg)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
|
|
|
case 'n': /* Not a directory */
|
|
|
|
result |= !S_ISDIR (st_mode);
|
|
|
|
break;
|
|
|
|
case 'r': /* Regular file */
|
|
|
|
result |= S_ISREG (st_mode);
|
|
|
|
break;
|
|
|
|
case 'd': /* Directory */
|
|
|
|
result |= S_ISDIR (st_mode);
|
|
|
|
break;
|
|
|
|
case 'l': /* Link */
|
|
|
|
result |= S_ISLNK (st_mode);
|
|
|
|
break;
|
|
|
|
case 'c': /* Character special */
|
|
|
|
result |= S_ISCHR (st_mode);
|
|
|
|
break;
|
|
|
|
case 'b': /* Block special */
|
|
|
|
result |= S_ISBLK (st_mode);
|
|
|
|
break;
|
|
|
|
case 'f': /* Fifo (named pipe) */
|
|
|
|
result |= S_ISFIFO (st_mode);
|
|
|
|
break;
|
|
|
|
case 's': /* Socket */
|
|
|
|
result |= S_ISSOCK (st_mode);
|
|
|
|
break;
|
|
|
|
case 'x': /* Executable */
|
2016-01-04 10:26:18 +03:00
|
|
|
result |= (st_mode & 0111) != 0 ? 1 : 0;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 't':
|
2016-01-04 10:26:18 +03:00
|
|
|
result |= panel->marked != 0 ? 1 : 0;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
default:
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_error = TRUE;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2016-01-04 11:00:49 +03:00
|
|
|
|
|
|
|
return (result != 0);
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** Calculates the truth value of the next condition starting from
|
1998-02-27 07:54:42 +03:00
|
|
|
p. Returns the point after condition. */
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2009-07-28 10:53:26 +04:00
|
|
|
static char *
|
2024-06-01 21:12:14 +03:00
|
|
|
test_condition (const Widget *edit_widget, char *p, gboolean *condition)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2010-06-10 13:42:37 +04:00
|
|
|
char arg[256];
|
2010-12-05 19:13:21 +03:00
|
|
|
const mc_search_type_t search_type = easy_patterns ? MC_SEARCH_T_GLOB : MC_SEARCH_T_REGEX;
|
2023-03-11 10:01:04 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 17:14:47 +03:00
|
|
|
const WEdit *e = CONST_EDIT (edit_widget);
|
2023-03-11 10:01:04 +03:00
|
|
|
#endif
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Handle one condition */
|
2010-06-10 13:42:37 +04:00
|
|
|
for (; *p != '\n' && *p != '&' && *p != '|'; p++)
|
|
|
|
{
|
2010-12-05 19:13:21 +03:00
|
|
|
WPanel *panel = NULL;
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
/* support quote space .mnu */
|
|
|
|
if ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
|
|
|
|
continue;
|
|
|
|
if (*p >= 'a')
|
|
|
|
panel = current_panel;
|
2010-12-05 19:13:21 +03:00
|
|
|
else if (get_other_type () == view_listing)
|
|
|
|
panel = other_panel;
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
*p |= 0x20;
|
|
|
|
|
|
|
|
switch (*p++)
|
|
|
|
{
|
|
|
|
case '!':
|
|
|
|
p = test_condition (edit_widget, p, condition);
|
|
|
|
*condition = !*condition;
|
|
|
|
str_prev_char (&p);
|
|
|
|
break;
|
|
|
|
case 'f': /* file name pattern */
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
2010-12-05 19:13:21 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
2016-01-31 08:38:28 +03:00
|
|
|
const char *edit_filename;
|
2011-11-08 23:44:38 +04:00
|
|
|
|
2023-03-11 10:01:04 +03:00
|
|
|
edit_filename = edit_get_file_name (e);
|
2016-01-04 11:00:49 +03:00
|
|
|
*condition = mc_search (arg, DEFAULT_CHARSET, edit_filename, search_type);
|
2011-11-08 23:44:38 +04:00
|
|
|
}
|
2010-12-05 19:13:21 +03:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
*condition = panel != NULL &&
|
2023-04-15 14:05:38 +03:00
|
|
|
mc_search (arg, DEFAULT_CHARSET, panel_current_entry (panel)->fname->str,
|
2016-01-04 11:00:49 +03:00
|
|
|
search_type);
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 'y': /* syntax pattern */
|
2009-07-28 10:53:26 +04:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
const char *syntax_type;
|
|
|
|
|
2023-03-11 10:01:04 +03:00
|
|
|
syntax_type = edit_get_syntax_type (e);
|
2010-06-10 13:42:37 +04:00
|
|
|
if (syntax_type != NULL)
|
|
|
|
{
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
2016-01-04 11:00:49 +03:00
|
|
|
*condition = mc_search (arg, DEFAULT_CHARSET, syntax_type, MC_SEARCH_T_NORMAL);
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
#endif
|
2004-03-07 09:24:14 +03:00
|
|
|
break;
|
2010-06-10 13:42:37 +04:00
|
|
|
case 'd':
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
2013-04-14 17:38:37 +04:00
|
|
|
*condition = panel != NULL
|
2013-09-09 16:55:01 +04:00
|
|
|
&& mc_search (arg, DEFAULT_CHARSET, vfs_path_as_str (panel->cwd_vpath),
|
2016-01-04 11:00:49 +03:00
|
|
|
search_type);
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
2016-01-04 11:00:49 +03:00
|
|
|
*condition = panel != NULL && test_type (panel, arg);
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case 'x': /* executable */
|
|
|
|
{
|
|
|
|
struct stat status;
|
|
|
|
|
|
|
|
p = extract_arg (p, arg, sizeof (arg));
|
2016-01-04 11:00:49 +03:00
|
|
|
*condition = stat (arg, &status) == 0 && is_exe (status.st_mode);
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_error = TRUE;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
} /* switch */
|
|
|
|
} /* while */
|
1998-02-27 07:54:42 +03:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** General purpose condition debug output handler */
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_out (char *start, char *end, gboolean condition)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
static char *msg = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
if (start == NULL && end == NULL)
|
|
|
|
{
|
|
|
|
/* Show output */
|
2016-01-04 10:26:18 +03:00
|
|
|
if (debug_flag && msg != NULL)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
size_t len;
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
len = strlen (msg);
|
2013-10-15 10:34:04 +04:00
|
|
|
if (len != 0)
|
2016-01-04 10:26:18 +03:00
|
|
|
msg[len - 1] = '\0';
|
2010-06-10 13:42:37 +04:00
|
|
|
message (D_NORMAL, _("Debug"), "%s", msg);
|
|
|
|
|
|
|
|
}
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_flag = FALSE;
|
2014-08-05 11:18:30 +04:00
|
|
|
MC_PTR_FREE (msg);
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const char *type;
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
/* Save debug info for later output */
|
|
|
|
if (!debug_flag)
|
|
|
|
return;
|
|
|
|
/* Save the result of the condition */
|
|
|
|
if (debug_error)
|
|
|
|
{
|
|
|
|
type = _("ERROR:");
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_error = FALSE;
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
2016-01-04 11:00:49 +03:00
|
|
|
else if (condition)
|
2010-06-10 13:42:37 +04:00
|
|
|
type = _("True:");
|
|
|
|
else
|
|
|
|
type = _("False:");
|
|
|
|
/* This is for debugging, don't need to be super efficient. */
|
|
|
|
if (end == NULL)
|
|
|
|
p = g_strdup_printf ("%s %s %c \n", msg ? msg : "", type, *start);
|
|
|
|
else
|
|
|
|
p = g_strdup_printf ("%s %s %.*s \n", msg ? msg : "", type, (int) (end - start), start);
|
|
|
|
g_free (msg);
|
|
|
|
msg = p;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** Calculates the truth value of one lineful of conditions. Returns
|
1998-02-27 07:54:42 +03:00
|
|
|
the point just before the end of line. */
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2009-07-28 10:53:26 +04:00
|
|
|
static char *
|
2024-06-01 21:12:14 +03:00
|
|
|
test_line (const Widget *edit_widget, char *p, gboolean *result)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
char operator;
|
|
|
|
|
|
|
|
/* Repeat till end of line */
|
2016-01-04 10:26:18 +03:00
|
|
|
while (*p != '\0' && *p != '\n')
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
char *debug_start, *debug_end;
|
2016-01-04 11:00:49 +03:00
|
|
|
gboolean condition = TRUE;
|
2013-10-15 10:34:04 +04:00
|
|
|
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 05:18:27 +04:00
|
|
|
/* support quote space .mnu */
|
2010-06-10 13:42:37 +04:00
|
|
|
while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
|
|
|
|
p++;
|
2016-01-04 10:26:18 +03:00
|
|
|
if (*p == '\0' || *p == '\n')
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
operator = *p++;
|
|
|
|
if (*p == '?')
|
|
|
|
{
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_flag = TRUE;
|
2010-06-10 13:42:37 +04:00
|
|
|
p++;
|
|
|
|
}
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 05:18:27 +04:00
|
|
|
/* support quote space .mnu */
|
2010-06-10 13:42:37 +04:00
|
|
|
while ((*p == ' ' && *(p - 1) != '\\') || *p == '\t')
|
|
|
|
p++;
|
2016-01-04 10:26:18 +03:00
|
|
|
if (*p == '\0' || *p == '\n')
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
|
|
|
|
debug_start = p;
|
|
|
|
p = test_condition (edit_widget, p, &condition);
|
|
|
|
debug_end = p;
|
|
|
|
/* Add one debug statement */
|
|
|
|
debug_out (debug_start, debug_end, condition);
|
|
|
|
|
|
|
|
switch (operator)
|
|
|
|
{
|
|
|
|
case '+':
|
|
|
|
case '=':
|
|
|
|
/* Assignment */
|
|
|
|
*result = condition;
|
|
|
|
break;
|
|
|
|
case '&': /* Logical and */
|
2016-01-04 11:00:49 +03:00
|
|
|
*result = *result && condition;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
case '|': /* Logical or */
|
2016-01-04 11:00:49 +03:00
|
|
|
*result = *result || condition;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
default:
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_error = TRUE;
|
2010-06-10 13:42:37 +04:00
|
|
|
break;
|
|
|
|
} /* switch */
|
|
|
|
/* Add one debug statement */
|
|
|
|
debug_out (&operator, NULL, *result);
|
|
|
|
|
|
|
|
} /* while (*p != '\n') */
|
1998-02-27 07:54:42 +03:00
|
|
|
/* Report debug message */
|
2016-01-04 11:00:49 +03:00
|
|
|
debug_out (NULL, NULL, TRUE);
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (*p == '\0' || *p == '\n')
|
2010-06-10 13:42:37 +04:00
|
|
|
str_prev_char (&p);
|
1998-02-27 07:54:42 +03:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/** FIXME: recode this routine on version 3.0, it could be cleaner */
|
|
|
|
|
1998-12-03 00:27:27 +03:00
|
|
|
static void
|
2024-06-01 21:12:14 +03:00
|
|
|
execute_menu_command (const Widget *edit_widget, const char *commands, gboolean show_prompt)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
|
|
|
FILE *cmd_file;
|
2010-06-10 13:42:37 +04:00
|
|
|
int cmd_file_fd;
|
2016-01-04 11:00:49 +03:00
|
|
|
gboolean expand_prefix_found = FALSE;
|
2016-01-04 10:26:18 +03:00
|
|
|
char *parameter = NULL;
|
2010-02-02 13:48:08 +03:00
|
|
|
gboolean do_quote = FALSE;
|
2010-06-10 13:42:37 +04:00
|
|
|
char lc_prompt[80];
|
|
|
|
int col;
|
2012-01-04 16:34:05 +04:00
|
|
|
vfs_path_t *file_name_vpath;
|
2016-01-04 11:00:49 +03:00
|
|
|
gboolean run_view = FALSE;
|
2021-05-15 12:15:47 +03:00
|
|
|
char *cmd;
|
2003-07-23 07:22:32 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* Skip menu entry title line */
|
|
|
|
commands = strchr (commands, '\n');
|
2016-01-04 10:26:18 +03:00
|
|
|
if (commands == NULL)
|
2010-11-10 14:09:42 +03:00
|
|
|
return;
|
|
|
|
|
2012-01-04 16:34:05 +04:00
|
|
|
cmd_file_fd = mc_mkstemps (&file_name_vpath, "mcusr", SCRIPT_SUFFIX);
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
if (cmd_file_fd == -1)
|
|
|
|
{
|
|
|
|
message (D_ERROR, MSG_ERROR, _("Cannot create temporary command file\n%s"),
|
|
|
|
unix_error_string (errno));
|
|
|
|
return;
|
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
cmd_file = fdopen (cmd_file_fd, "w");
|
|
|
|
fputs ("#! /bin/sh\n", cmd_file);
|
|
|
|
commands++;
|
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
for (col = 0; *commands != '\0'; commands++)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
if (col == 0)
|
|
|
|
{
|
2016-12-11 21:31:22 +03:00
|
|
|
if (!whitespace (*commands))
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
2016-12-11 21:31:22 +03:00
|
|
|
while (whitespace (*commands))
|
2010-11-10 14:09:42 +03:00
|
|
|
commands++;
|
2016-01-04 10:26:18 +03:00
|
|
|
if (*commands == '\0')
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
col++;
|
|
|
|
if (*commands == '\n')
|
|
|
|
col = 0;
|
2016-01-04 10:26:18 +03:00
|
|
|
if (parameter != NULL)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
if (*commands == '}')
|
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
*parameter = '\0';
|
2010-11-10 14:09:42 +03:00
|
|
|
parameter =
|
2013-01-25 16:41:41 +04:00
|
|
|
input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, "",
|
2013-01-25 18:29:15 +04:00
|
|
|
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD |
|
|
|
|
INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_VARIABLES |
|
|
|
|
INPUT_COMPLETE_USERNAMES);
|
2016-01-04 10:26:18 +03:00
|
|
|
if (parameter == NULL || *parameter == '\0')
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
/* User canceled */
|
2021-05-15 12:02:08 +03:00
|
|
|
g_free (parameter);
|
2010-11-10 14:09:42 +03:00
|
|
|
fclose (cmd_file);
|
2012-01-04 16:34:05 +04:00
|
|
|
mc_unlink (file_name_vpath);
|
2021-02-21 19:30:18 +03:00
|
|
|
vfs_path_free (file_name_vpath, TRUE);
|
2010-11-10 14:09:42 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (do_quote)
|
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
char *tmp;
|
|
|
|
|
2014-09-03 10:59:37 +04:00
|
|
|
tmp = name_quote (parameter, FALSE);
|
2023-10-14 18:25:29 +03:00
|
|
|
if (tmp != NULL)
|
|
|
|
{
|
|
|
|
fputs (tmp, cmd_file);
|
|
|
|
g_free (tmp);
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
fputs (parameter, cmd_file);
|
2016-01-04 10:26:18 +03:00
|
|
|
|
|
|
|
MC_PTR_FREE (parameter);
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
else if (parameter < lc_prompt + sizeof (lc_prompt) - 1)
|
|
|
|
*parameter++ = *commands;
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
2016-01-04 11:00:49 +03:00
|
|
|
else if (expand_prefix_found)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2016-01-04 11:00:49 +03:00
|
|
|
expand_prefix_found = FALSE;
|
2010-11-10 14:09:42 +03:00
|
|
|
if (g_ascii_isdigit ((gchar) * commands))
|
|
|
|
{
|
|
|
|
do_quote = (atoi (commands) != 0);
|
|
|
|
while (g_ascii_isdigit ((gchar) * commands))
|
|
|
|
commands++;
|
|
|
|
}
|
|
|
|
if (*commands == '{')
|
|
|
|
parameter = lc_prompt;
|
|
|
|
else
|
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
char *text;
|
|
|
|
|
|
|
|
text = expand_format (edit_widget, *commands, do_quote);
|
2023-10-14 18:25:29 +03:00
|
|
|
if (text != NULL)
|
|
|
|
{
|
|
|
|
fputs (text, cmd_file);
|
|
|
|
g_free (text);
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
else if (*commands == '%')
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2018-01-05 11:04:11 +03:00
|
|
|
int i;
|
2016-01-04 10:26:18 +03:00
|
|
|
|
2018-01-05 11:04:11 +03:00
|
|
|
i = check_format_view (commands + 1);
|
|
|
|
if (i != 0)
|
|
|
|
{
|
|
|
|
commands += i;
|
|
|
|
run_view = TRUE;
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
else
|
2018-01-05 11:04:11 +03:00
|
|
|
{
|
|
|
|
do_quote = TRUE; /* Default: Quote expanded macro */
|
|
|
|
expand_prefix_found = TRUE;
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
else
|
|
|
|
fputc (*commands, cmd_file);
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
fclose (cmd_file);
|
2012-01-04 16:34:05 +04:00
|
|
|
mc_chmod (file_name_vpath, S_IRWXU);
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
/* Execute the command indirectly to allow execution even on no-exec filesystems. */
|
|
|
|
cmd = g_strconcat ("/bin/sh ", vfs_path_as_str (file_name_vpath), (char *) NULL);
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (run_view)
|
|
|
|
{
|
2021-05-15 12:08:44 +03:00
|
|
|
mcview_viewer (cmd, NULL, 0, 0, 0);
|
2010-11-10 14:09:42 +03:00
|
|
|
dialog_switch_process_pending ();
|
|
|
|
}
|
2021-05-15 12:15:47 +03:00
|
|
|
else if (show_prompt)
|
|
|
|
shell_execute (cmd, EXECUTE_HIDE);
|
2010-11-10 14:09:42 +03:00
|
|
|
else
|
|
|
|
{
|
2021-05-15 12:15:47 +03:00
|
|
|
gboolean ok;
|
2012-01-04 16:34:05 +04:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
/* Prepare the terminal by setting its flag to the initial ones. This will cause \r
|
|
|
|
* to work as expected, instead of being ignored. */
|
|
|
|
tty_reset_shell_mode ();
|
2021-01-12 22:34:52 +03:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
ok = (system (cmd) != -1);
|
2021-01-12 22:34:52 +03:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
/* Restore terminal configuration. */
|
|
|
|
tty_raw_mode ();
|
2021-01-12 22:34:52 +03:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
/* Redraw the original screen's contents. */
|
|
|
|
tty_clear_screen ();
|
|
|
|
repaint_screen ();
|
2021-01-12 22:34:52 +03:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
if (!ok)
|
|
|
|
message (D_ERROR, MSG_ERROR, "%s", _("Error calling program"));
|
|
|
|
}
|
2021-01-12 22:34:52 +03:00
|
|
|
|
2021-05-15 12:15:47 +03:00
|
|
|
g_free (cmd);
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2012-01-04 16:34:05 +04:00
|
|
|
mc_unlink (file_name_vpath);
|
2021-02-21 19:30:18 +03:00
|
|
|
vfs_path_free (file_name_vpath, TRUE);
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
|
|
|
** Check owner of the menu file. Using menu file is allowed, if
|
|
|
|
** owner of the menu is root or the actual user. In either case
|
|
|
|
** file should not be group and word-writable.
|
|
|
|
**
|
|
|
|
** Q. Should we apply this routine to system and home menu (and .ext files)?
|
|
|
|
*/
|
|
|
|
|
2016-01-04 11:00:49 +03:00
|
|
|
static gboolean
|
2010-11-10 14:09:42 +03:00
|
|
|
menu_file_own (char *path)
|
|
|
|
{
|
|
|
|
struct stat st;
|
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (stat (path, &st) == 0 && (st.st_uid == 0 || (st.st_uid == geteuid ()) != 0)
|
|
|
|
&& ((st.st_mode & (S_IWGRP | S_IWOTH)) == 0))
|
2016-01-04 11:00:49 +03:00
|
|
|
return TRUE;
|
2016-01-04 10:26:18 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (verbose)
|
|
|
|
message (D_NORMAL, _("Warning -- ignoring file"),
|
|
|
|
_("File %s is not owned by root or you or is world writable.\n"
|
|
|
|
"Using it may compromise your security"), path);
|
2016-01-04 10:26:18 +03:00
|
|
|
|
2016-01-04 11:00:49 +03:00
|
|
|
return FALSE;
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/*** public functions ****************************************************************************/
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/* Formats defined:
|
|
|
|
%% The % character
|
2017-10-15 20:14:49 +03:00
|
|
|
%f The current file in the active panel (if non-local vfs, file will be copied locally
|
|
|
|
and %f will be full path to it) or the opened file in the internal editor.
|
|
|
|
%p Likewise.
|
2010-11-10 14:09:42 +03:00
|
|
|
%d The current working directory
|
|
|
|
%s "Selected files"; the tagged files if any, otherwise the current file
|
|
|
|
%t Tagged files
|
|
|
|
%u Tagged files (and they are untagged on return from expand_format)
|
|
|
|
%view Runs the commands and pipes standard output to the view command.
|
|
|
|
If %view is immediately followed by '{', recognize keywords
|
|
|
|
ascii, hex, nroff and unform
|
|
|
|
|
|
|
|
If the format letter is in uppercase, it refers to the other panel.
|
|
|
|
|
|
|
|
With a number followed the % character you can turn quoting on (default)
|
|
|
|
and off. For example:
|
|
|
|
%f quote expanded macro
|
|
|
|
%1f ditto
|
|
|
|
%0f don't quote expanded macro
|
|
|
|
|
|
|
|
expand_format returns a memory block that must be free()d.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Returns how many characters we should advance if %view was found */
|
|
|
|
int
|
|
|
|
check_format_view (const char *p)
|
|
|
|
{
|
|
|
|
const char *q = p;
|
2016-01-04 10:26:18 +03:00
|
|
|
|
|
|
|
if (strncmp (p, "view", 4) == 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
q += 4;
|
|
|
|
if (*q == '{')
|
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
for (q++; *q != '\0' && *q != '}'; q++)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
if (strncmp (q, DEFAULT_CHARSET, 5) == 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2017-12-17 12:48:00 +03:00
|
|
|
mcview_global_flags.hex = FALSE;
|
2010-11-10 14:09:42 +03:00
|
|
|
q += 4;
|
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
else if (strncmp (q, "hex", 3) == 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2017-12-17 12:48:00 +03:00
|
|
|
mcview_global_flags.hex = TRUE;
|
2010-11-10 14:09:42 +03:00
|
|
|
q += 2;
|
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
else if (strncmp (q, "nroff", 5) == 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2017-12-17 12:48:00 +03:00
|
|
|
mcview_global_flags.nroff = TRUE;
|
2010-11-10 14:09:42 +03:00
|
|
|
q += 4;
|
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
else if (strncmp (q, "unform", 6) == 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2017-12-17 12:48:00 +03:00
|
|
|
mcview_global_flags.nroff = FALSE;
|
2010-11-10 14:09:42 +03:00
|
|
|
q += 5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (*q == '}')
|
|
|
|
q++;
|
|
|
|
}
|
|
|
|
return q - p;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
int
|
|
|
|
check_format_cd (const char *p)
|
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
return (strncmp (p, "cd", 2)) != 0 ? 0 : 3;
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/* Check if p has a "^var\{var-name\}" */
|
|
|
|
/* Returns the number of skipped characters (zero on not found) */
|
|
|
|
/* V will be set to the expanded variable name */
|
|
|
|
|
|
|
|
int
|
|
|
|
check_format_var (const char *p, char **v)
|
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
*v = NULL;
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (strncmp (p, "var{", 4) == 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2018-01-05 11:04:11 +03:00
|
|
|
const char *q = p;
|
2013-10-15 10:34:04 +04:00
|
|
|
const char *dots = NULL;
|
|
|
|
const char *value;
|
2018-01-05 11:04:11 +03:00
|
|
|
char *var_name;
|
2013-10-15 10:34:04 +04:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
for (q += 4; *q != '\0' && *q != '}'; q++)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
if (*q == ':')
|
|
|
|
dots = q + 1;
|
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
if (*q == '\0')
|
2010-11-10 14:09:42 +03:00
|
|
|
return 0;
|
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (dots == NULL || dots == q + 5)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
message (D_ERROR,
|
|
|
|
_("Format error on file Extensions File"),
|
|
|
|
!dots ? _("The %%var macro has no default")
|
|
|
|
: _("The %%var macro has no variable"));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy the variable name */
|
|
|
|
var_name = g_strndup (p + 4, dots - 2 - (p + 3));
|
|
|
|
value = getenv (var_name);
|
|
|
|
g_free (var_name);
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (value != NULL)
|
2010-11-10 14:09:42 +03:00
|
|
|
*v = g_strdup (value);
|
2018-01-05 11:04:11 +03:00
|
|
|
else
|
|
|
|
*v = g_strndup (dots, q - dots);
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
return q - p;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
char *
|
2024-06-01 21:12:14 +03:00
|
|
|
expand_format (const Widget *edit_widget, char c, gboolean do_quote)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
|
|
|
WPanel *panel = NULL;
|
2014-09-03 10:59:37 +04:00
|
|
|
char *(*quote_func) (const char *, gboolean);
|
2016-01-31 08:41:35 +03:00
|
|
|
const char *fname = NULL;
|
2010-11-10 14:09:42 +03:00
|
|
|
char *result;
|
|
|
|
char c_lc;
|
|
|
|
|
2023-03-11 10:01:04 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 17:14:47 +03:00
|
|
|
const WEdit *e = CONST_EDIT (edit_widget);
|
2023-03-11 10:01:04 +03:00
|
|
|
#else
|
2010-11-10 14:09:42 +03:00
|
|
|
(void) edit_widget;
|
|
|
|
#endif
|
1999-04-22 08:36:11 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (c == '%')
|
|
|
|
return g_strdup ("%");
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2012-07-30 10:14:46 +04:00
|
|
|
switch (mc_global.mc_run_mode)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2012-07-30 10:14:46 +04:00
|
|
|
case MC_RUN_FULL:
|
2017-10-15 19:53:20 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
|
|
|
fname = edit_get_file_name (e);
|
2010-11-10 14:09:42 +03:00
|
|
|
else
|
2017-10-15 19:53:20 +03:00
|
|
|
#endif
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2017-10-15 19:53:20 +03:00
|
|
|
if (g_ascii_islower ((gchar) c))
|
|
|
|
panel = current_panel;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (get_other_type () != view_listing)
|
2023-10-14 18:25:29 +03:00
|
|
|
return NULL;
|
2017-10-15 19:53:20 +03:00
|
|
|
panel = other_panel;
|
|
|
|
}
|
|
|
|
|
2023-04-15 14:05:38 +03:00
|
|
|
fname = panel_current_entry (panel)->fname->str;
|
2010-11-10 14:09:42 +03:00
|
|
|
}
|
2012-07-30 10:14:46 +04:00
|
|
|
break;
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2012-07-30 10:14:46 +04:00
|
|
|
case MC_RUN_EDITOR:
|
2023-03-11 10:01:04 +03:00
|
|
|
fname = edit_get_file_name (e);
|
2012-07-30 10:14:46 +04:00
|
|
|
break;
|
2010-11-10 14:09:42 +03:00
|
|
|
#endif
|
2010-06-10 13:42:37 +04:00
|
|
|
|
2021-10-31 09:49:45 +03:00
|
|
|
case MC_RUN_VIEWER:
|
|
|
|
/* mc_run_param0 is not NULL here because mcviewer isn't run without input file */
|
|
|
|
fname = (const char *) mc_run_param0;
|
|
|
|
break;
|
|
|
|
|
2012-07-30 10:14:46 +04:00
|
|
|
default:
|
|
|
|
/* other modes don't use formats */
|
2023-10-14 18:25:29 +03:00
|
|
|
return NULL;
|
2012-07-30 10:14:46 +04:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (do_quote)
|
|
|
|
quote_func = name_quote;
|
|
|
|
else
|
|
|
|
quote_func = fake_name_quote;
|
|
|
|
|
|
|
|
c_lc = g_ascii_tolower ((gchar) c);
|
|
|
|
|
|
|
|
switch (c_lc)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2010-11-10 14:09:42 +03:00
|
|
|
case 'f':
|
|
|
|
case 'p':
|
2014-09-03 10:59:37 +04:00
|
|
|
result = quote_func (fname, FALSE);
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
2010-11-10 14:09:42 +03:00
|
|
|
case 'x':
|
2014-09-03 10:59:37 +04:00
|
|
|
result = quote_func (extension (fname), FALSE);
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
2010-11-10 14:09:42 +03:00
|
|
|
case 'd':
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2015-10-18 08:07:08 +03:00
|
|
|
const char *cwd;
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2015-10-18 08:07:08 +03:00
|
|
|
if (panel != NULL)
|
|
|
|
cwd = vfs_path_as_str (panel->cwd_vpath);
|
2010-06-10 13:42:37 +04:00
|
|
|
else
|
2011-09-27 23:13:50 +04:00
|
|
|
cwd = vfs_get_current_dir ();
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2023-10-14 18:58:53 +03:00
|
|
|
result = quote_func (cwd, FALSE);
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
2017-10-04 11:56:43 +03:00
|
|
|
case 'c':
|
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2017-10-04 11:56:43 +03:00
|
|
|
{
|
2023-03-11 10:01:04 +03:00
|
|
|
result = g_strdup_printf ("%u", (unsigned int) edit_get_cursor_offset (e));
|
2017-10-04 11:56:43 +03:00
|
|
|
goto ret;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
2010-11-10 14:09:42 +03:00
|
|
|
case 'i': /* indent equal number cursor position in line */
|
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
2023-03-11 10:01:04 +03:00
|
|
|
result = g_strnfill (edit_get_curs_col (e), ' ');
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case 'y': /* syntax type */
|
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
const char *syntax_type;
|
|
|
|
|
2023-03-11 10:01:04 +03:00
|
|
|
syntax_type = edit_get_syntax_type (e);
|
2010-11-10 14:09:42 +03:00
|
|
|
if (syntax_type != NULL)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
|
|
|
result = g_strdup (syntax_type);
|
|
|
|
goto ret;
|
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case 'k': /* block file name */
|
|
|
|
case 'b': /* block file name / strip extension */
|
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2016-01-04 10:26:18 +03:00
|
|
|
{
|
|
|
|
char *file;
|
2011-11-08 23:44:38 +04:00
|
|
|
|
2020-05-03 11:07:01 +03:00
|
|
|
file = mc_config_get_full_path (EDIT_HOME_BLOCK_FILE);
|
2016-01-04 10:26:18 +03:00
|
|
|
result = quote_func (file, FALSE);
|
|
|
|
g_free (file);
|
|
|
|
goto ret;
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
#endif
|
2016-01-04 10:26:18 +03:00
|
|
|
if (c_lc == 'b')
|
|
|
|
{
|
|
|
|
result = strip_ext (quote_func (fname, FALSE));
|
|
|
|
goto ret;
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
2016-01-04 10:26:18 +03:00
|
|
|
break;
|
2010-11-10 14:09:42 +03:00
|
|
|
case 'n': /* strip extension in editor */
|
|
|
|
#ifdef USE_INTERNAL_EDIT
|
2023-03-11 10:01:04 +03:00
|
|
|
if (e != NULL)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
2014-09-03 10:59:37 +04:00
|
|
|
result = strip_ext (quote_func (fname, FALSE));
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
case 'm': /* menu file name */
|
2016-01-04 10:26:18 +03:00
|
|
|
if (menu != NULL)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
2014-09-03 10:59:37 +04:00
|
|
|
result = quote_func (menu, FALSE);
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
break;
|
|
|
|
case 's':
|
2016-01-04 10:26:18 +03:00
|
|
|
if (panel == NULL || panel->marked == 0)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
2014-09-03 10:59:37 +04:00
|
|
|
result = quote_func (fname, FALSE);
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2017-12-16 20:52:39 +03:00
|
|
|
MC_FALLTHROUGH;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
case 't':
|
|
|
|
case 'u':
|
|
|
|
{
|
2023-10-14 18:25:29 +03:00
|
|
|
GString *block = NULL;
|
2012-02-15 22:38:59 +04:00
|
|
|
int i;
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2012-02-15 22:38:59 +04:00
|
|
|
if (panel == NULL)
|
2011-11-08 23:44:38 +04:00
|
|
|
{
|
2023-10-14 18:25:29 +03:00
|
|
|
result = NULL;
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2013-08-16 10:36:43 +04:00
|
|
|
for (i = 0; i < panel->dir.len; i++)
|
2023-04-16 12:06:20 +03:00
|
|
|
if (panel->dir.list[i].f.marked != 0)
|
2010-11-10 14:09:42 +03:00
|
|
|
{
|
2012-02-15 22:38:59 +04:00
|
|
|
char *tmp;
|
|
|
|
|
2021-02-23 21:19:59 +03:00
|
|
|
tmp = quote_func (panel->dir.list[i].fname->str, FALSE);
|
2023-10-14 18:25:29 +03:00
|
|
|
if (tmp != NULL)
|
|
|
|
{
|
|
|
|
if (block == NULL)
|
2023-12-23 16:54:53 +03:00
|
|
|
block = g_string_new_take (tmp);
|
2023-10-14 18:25:29 +03:00
|
|
|
else
|
2023-12-23 16:54:53 +03:00
|
|
|
{
|
2023-10-14 18:25:29 +03:00
|
|
|
g_string_append (block, tmp);
|
2023-12-23 16:54:53 +03:00
|
|
|
g_free (tmp);
|
|
|
|
}
|
2023-10-14 18:25:29 +03:00
|
|
|
g_string_append_c (block, ' ');
|
|
|
|
}
|
2012-02-15 22:38:59 +04:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
if (c_lc == 'u')
|
|
|
|
do_file_mark (panel, i, 0);
|
|
|
|
}
|
2023-10-14 18:25:29 +03:00
|
|
|
result = block == NULL ? NULL : g_string_free (block, block->len == 0);
|
2011-11-08 23:44:38 +04:00
|
|
|
goto ret;
|
2010-11-10 14:09:42 +03:00
|
|
|
} /* sub case block */
|
2015-04-19 13:57:38 +03:00
|
|
|
default:
|
|
|
|
break;
|
2010-11-10 14:09:42 +03:00
|
|
|
} /* switch */
|
2015-04-19 13:57:38 +03:00
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
result = g_strdup ("% ");
|
|
|
|
result[1] = c;
|
2011-11-08 23:44:38 +04:00
|
|
|
ret:
|
2010-11-10 14:09:42 +03:00
|
|
|
return result;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2010-11-10 14:09:42 +03:00
|
|
|
/* --------------------------------------------------------------------------------------------- */
|
|
|
|
/**
|
2002-09-27 00:55:51 +04:00
|
|
|
* If edit_widget is NULL then we are called from the mc menu,
|
|
|
|
* otherwise we are called from the mcedit menu.
|
|
|
|
*/
|
2010-11-10 14:09:42 +03:00
|
|
|
|
2011-01-06 00:49:24 +03:00
|
|
|
gboolean
|
2024-06-01 21:12:14 +03:00
|
|
|
user_menu_cmd (const Widget *edit_widget, const char *menu_file, int selected_entry)
|
1998-02-27 07:54:42 +03:00
|
|
|
{
|
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add macro %k it is block file name
Add macro %e it is error file name
Add macro %i it is cursor column indent of spaces, only for edit
Add macro %y, it is syntax of current file in editor, only for edit
Add condition y , it is syntax pattern of current file in edit
Add macro %x it is extension of current file
Add macro %m it is current menu filename
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editcmd.c: Modify External Formatter (was C indent formatter) .
Autocreate a scripts in home, from templates /usr/lib/mc/edit.indent.rc,
edit.ispell.rc, etc. Remove leading and trailing spaces into _(""),
(the message of David H. Martin <dmartina@usa.net>)
2000-05-05 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* src/user.c: Add condition (x filename) into mc.menu .
for "Open next a free console" and like.
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
src/user.c: fix segfault in chunk_alloc of glibc, when into condition
of .mnu we have quoted space. (~.mc/menu: + f \.\ test$).
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/edit.c:
Add ability user edit menus: system: /usr/lib/mc/cedit.menu,
* gtkedit/editmenu.c: home: ~/.cedit.menu, local: .cedit.menu
Marked block is access now from an user edit menu
Access ~/.cedit/cooledit.block for insert to cursor place from
user edit menu.
Created system cedit.menu
2000-05-04 Valery Kornienkov <vlk@dimavb.st.simbirsk.su>
* gtkedit/editdraw.c:
Improved a status string of cool editor for best understand,
and to add char,hex view.
2000-05-04 Richard Hestilow <hestgray@ionet.net>
* gnome/gdesktop.c: Fixes snap to grid.
2000-05-09 05:18:27 +04:00
|
|
|
char *p;
|
1999-11-01 23:49:03 +03:00
|
|
|
char *data, **entries;
|
2010-06-10 13:42:37 +04:00
|
|
|
int max_cols, menu_lines, menu_limit;
|
2016-01-04 11:00:49 +03:00
|
|
|
int col, i;
|
|
|
|
gboolean accept_entry = TRUE;
|
2016-11-25 09:17:03 +03:00
|
|
|
int selected;
|
|
|
|
gboolean old_patterns;
|
2011-01-06 00:49:24 +03:00
|
|
|
gboolean res = FALSE;
|
2011-03-14 15:58:31 +03:00
|
|
|
gboolean interactive = TRUE;
|
2010-06-10 13:42:37 +04:00
|
|
|
|
|
|
|
if (!vfs_current_is_local ())
|
|
|
|
{
|
|
|
|
message (D_ERROR, MSG_ERROR, "%s", _("Cannot execute commands on non-local filesystems"));
|
2011-01-06 00:49:24 +03:00
|
|
|
return FALSE;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2011-01-26 03:12:30 +03:00
|
|
|
if (menu_file != NULL)
|
|
|
|
menu = g_strdup (menu_file);
|
|
|
|
else
|
2016-01-04 10:26:18 +03:00
|
|
|
menu = g_strdup (edit_widget != NULL ? EDIT_LOCAL_MENU : MC_LOCAL_MENU);
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!exist_file (menu) || !menu_file_own (menu))
|
|
|
|
{
|
2011-01-26 03:12:30 +03:00
|
|
|
if (menu_file != NULL)
|
|
|
|
{
|
2012-03-05 20:46:39 +04:00
|
|
|
message (D_ERROR, MSG_ERROR, _("Cannot open file %s\n%s"), menu,
|
2011-10-15 14:56:47 +04:00
|
|
|
unix_error_string (errno));
|
2014-08-05 11:18:30 +04:00
|
|
|
MC_PTR_FREE (menu);
|
2011-01-26 03:12:30 +03:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
g_free (menu);
|
2016-01-04 10:26:18 +03:00
|
|
|
if (edit_widget != NULL)
|
2011-11-24 02:28:07 +04:00
|
|
|
menu = mc_config_get_full_path (EDIT_HOME_MENU);
|
2010-06-10 13:42:37 +04:00
|
|
|
else
|
2011-11-24 02:28:07 +04:00
|
|
|
menu = mc_config_get_full_path (MC_USERMENU_FILE);
|
2010-06-10 13:42:37 +04:00
|
|
|
|
|
|
|
if (!exist_file (menu))
|
|
|
|
{
|
|
|
|
g_free (menu);
|
2010-12-29 18:12:59 +03:00
|
|
|
menu =
|
2011-11-09 01:10:51 +04:00
|
|
|
mc_build_filename (mc_config_get_home_dir (),
|
2016-03-25 21:33:44 +03:00
|
|
|
edit_widget != NULL ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU,
|
|
|
|
(char *) NULL);
|
2010-06-10 13:42:37 +04:00
|
|
|
if (!exist_file (menu))
|
|
|
|
{
|
|
|
|
g_free (menu);
|
2011-01-20 18:34:07 +03:00
|
|
|
menu =
|
2011-11-09 01:10:51 +04:00
|
|
|
mc_build_filename (mc_global.sysconfig_dir,
|
2016-01-04 10:26:18 +03:00
|
|
|
edit_widget != NULL ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU,
|
2016-03-25 21:33:44 +03:00
|
|
|
(char *) NULL);
|
2011-01-20 18:34:07 +03:00
|
|
|
if (!exist_file (menu))
|
|
|
|
{
|
|
|
|
g_free (menu);
|
2016-01-04 10:26:18 +03:00
|
|
|
menu =
|
|
|
|
mc_build_filename (mc_global.share_data_dir,
|
|
|
|
edit_widget != NULL ? EDIT_GLOBAL_MENU : MC_GLOBAL_MENU,
|
2016-03-25 21:33:44 +03:00
|
|
|
(char *) NULL);
|
2011-01-20 18:34:07 +03:00
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
|
|
|
|
2010-11-11 10:38:41 +03:00
|
|
|
if (!g_file_get_contents (menu, &data, NULL, NULL))
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2015-02-12 18:38:53 +03:00
|
|
|
message (D_ERROR, MSG_ERROR, _("Cannot open file %s\n%s"), menu, unix_error_string (errno));
|
2014-08-05 11:18:30 +04:00
|
|
|
MC_PTR_FREE (menu);
|
2011-01-06 00:49:24 +03:00
|
|
|
return FALSE;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2009-07-28 10:53:26 +04:00
|
|
|
|
1998-02-27 07:54:42 +03:00
|
|
|
max_cols = 0;
|
|
|
|
selected = 0;
|
1999-11-01 23:49:03 +03:00
|
|
|
menu_limit = 0;
|
2016-01-04 10:26:18 +03:00
|
|
|
entries = NULL;
|
1998-02-27 07:54:42 +03:00
|
|
|
|
|
|
|
/* Parse the menu file */
|
|
|
|
old_patterns = easy_patterns;
|
|
|
|
p = check_patterns (data);
|
2016-01-04 10:26:18 +03:00
|
|
|
for (menu_lines = col = 0; *p != '\0'; str_next_char (&p))
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
|
|
|
if (menu_lines >= menu_limit)
|
|
|
|
{
|
|
|
|
char **new_entries;
|
|
|
|
|
|
|
|
menu_limit += MAX_ENTRIES;
|
|
|
|
new_entries = g_try_realloc (entries, sizeof (new_entries[0]) * menu_limit);
|
|
|
|
if (new_entries == NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
entries = new_entries;
|
|
|
|
new_entries += menu_limit;
|
|
|
|
while (--new_entries >= &entries[menu_lines])
|
|
|
|
*new_entries = NULL;
|
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2016-01-04 10:26:18 +03:00
|
|
|
if (col == 0 && entries[menu_lines] == NULL)
|
2018-01-05 11:04:11 +03:00
|
|
|
switch (*p)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2018-01-05 11:04:11 +03:00
|
|
|
case '#':
|
2021-01-12 22:34:52 +03:00
|
|
|
/* do not show prompt if first line of external script is #silent */
|
2011-03-14 15:58:31 +03:00
|
|
|
if (selected_entry >= 0 && strncmp (p, "#silent", 7) == 0)
|
|
|
|
interactive = FALSE;
|
2010-06-10 13:42:37 +04:00
|
|
|
/* A commented menu entry */
|
2016-01-04 11:00:49 +03:00
|
|
|
accept_entry = TRUE;
|
2018-01-05 11:04:11 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case '+':
|
2010-06-10 13:42:37 +04:00
|
|
|
if (*(p + 1) == '=')
|
|
|
|
{
|
|
|
|
/* Combined adding and default */
|
|
|
|
p = test_line (edit_widget, p + 1, &accept_entry);
|
|
|
|
if (selected == 0 && accept_entry)
|
|
|
|
selected = menu_lines;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* A condition for adding the entry */
|
|
|
|
p = test_line (edit_widget, p, &accept_entry);
|
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case '=':
|
2010-06-10 13:42:37 +04:00
|
|
|
if (*(p + 1) == '+')
|
|
|
|
{
|
|
|
|
/* Combined adding and default */
|
|
|
|
p = test_line (edit_widget, p + 1, &accept_entry);
|
|
|
|
if (selected == 0 && accept_entry)
|
|
|
|
selected = menu_lines;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* A condition for making the entry default */
|
|
|
|
i = 1;
|
|
|
|
p = test_line (edit_widget, p, &i);
|
2016-01-04 10:26:18 +03:00
|
|
|
if (selected == 0 && i != 0)
|
2010-06-10 13:42:37 +04:00
|
|
|
selected = menu_lines;
|
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (!whitespace (*p) && str_isprint (p))
|
|
|
|
{
|
|
|
|
/* A menu entry title line */
|
|
|
|
if (accept_entry)
|
|
|
|
entries[menu_lines] = p;
|
|
|
|
else
|
|
|
|
accept_entry = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
2018-01-05 11:04:11 +03:00
|
|
|
|
2010-06-10 13:42:37 +04:00
|
|
|
if (*p == '\n')
|
|
|
|
{
|
2016-01-04 10:26:18 +03:00
|
|
|
if (entries[menu_lines] != NULL)
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
|
|
|
menu_lines++;
|
2016-01-04 11:00:49 +03:00
|
|
|
accept_entry = TRUE;
|
2010-06-10 13:42:37 +04:00
|
|
|
}
|
2016-04-07 10:52:04 +03:00
|
|
|
max_cols = MAX (max_cols, col);
|
2010-06-10 13:42:37 +04:00
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (*p == '\t')
|
|
|
|
*p = ' ';
|
|
|
|
col++;
|
|
|
|
}
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2000-05-25 20:21:42 +04:00
|
|
|
|
2009-07-28 10:53:26 +04:00
|
|
|
if (menu_lines == 0)
|
2011-01-06 00:49:24 +03:00
|
|
|
{
|
2010-06-10 13:42:37 +04:00
|
|
|
message (D_ERROR, MSG_ERROR, _("No suitable entries found in %s"), menu);
|
2011-01-06 00:49:24 +03:00
|
|
|
res = FALSE;
|
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
else
|
|
|
|
{
|
2011-01-26 03:12:30 +03:00
|
|
|
if (selected_entry >= 0)
|
|
|
|
selected = selected_entry;
|
|
|
|
else
|
2010-06-10 13:42:37 +04:00
|
|
|
{
|
2013-10-15 10:34:04 +04:00
|
|
|
Listbox *listbox;
|
|
|
|
|
2016-04-07 10:52:04 +03:00
|
|
|
max_cols = MIN (MAX (max_cols, col), MAX_ENTRY_LEN);
|
2010-06-10 13:42:37 +04:00
|
|
|
|
2011-01-26 03:12:30 +03:00
|
|
|
/* Create listbox */
|
2023-03-18 09:45:24 +03:00
|
|
|
listbox = listbox_window_new (menu_lines, max_cols + 2, _("User menu"),
|
|
|
|
"[Edit Menu File]");
|
2011-01-26 03:12:30 +03:00
|
|
|
/* insert all the items found */
|
|
|
|
for (i = 0; i < menu_lines; i++)
|
|
|
|
{
|
|
|
|
p = entries[i];
|
|
|
|
LISTBOX_APPEND_TEXT (listbox, (unsigned char) p[0],
|
2015-10-04 15:14:16 +03:00
|
|
|
extract_line (p, p + MAX_ENTRY_LEN), p, FALSE);
|
2011-01-26 03:12:30 +03:00
|
|
|
}
|
|
|
|
/* Select the default entry */
|
2023-04-15 14:56:07 +03:00
|
|
|
listbox_set_current (listbox->list, selected);
|
2011-01-26 03:12:30 +03:00
|
|
|
|
2023-03-18 09:45:24 +03:00
|
|
|
selected = listbox_run (listbox);
|
2011-01-26 03:12:30 +03:00
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
if (selected >= 0)
|
2011-01-06 00:49:24 +03:00
|
|
|
{
|
2011-02-01 01:08:15 +03:00
|
|
|
execute_menu_command (edit_widget, entries[selected], interactive);
|
2011-01-06 00:49:24 +03:00
|
|
|
res = TRUE;
|
|
|
|
}
|
2010-06-10 13:42:37 +04:00
|
|
|
|
|
|
|
do_refresh ();
|
2000-05-25 20:21:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
easy_patterns = old_patterns;
|
2014-08-05 11:18:30 +04:00
|
|
|
MC_PTR_FREE (menu);
|
2009-02-06 01:27:37 +03:00
|
|
|
g_free (entries);
|
|
|
|
g_free (data);
|
2011-01-06 00:49:24 +03:00
|
|
|
return res;
|
1998-02-27 07:54:42 +03:00
|
|
|
}
|
2010-11-10 14:09:42 +03:00
|
|
|
|
|
|
|
/* --------------------------------------------------------------------------------------------- */
|