mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
e5c0c7185e
svn path=/trunk/; revision=2456
1573 lines
35 KiB
C
1573 lines
35 KiB
C
/* Routines invoked by a function key
|
|
They normally operate on the current panel.
|
|
|
|
Copyright (C) 1994, 1995 Miguel de Icaza
|
|
Copyright (C) 1994, 1995 Janne Kukonlehto
|
|
|
|
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
|
|
#include <config.h>
|
|
#ifdef __os2__
|
|
# define INCL_DOSFILEMGR
|
|
# define INCL_DOSMISC
|
|
# define INCL_DOSERROR
|
|
#endif
|
|
#ifdef HAVE_UNISTD_H
|
|
# include <unistd.h>
|
|
#endif
|
|
#include "tty.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h> /* getenv (), rand */
|
|
#include <sys/types.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#if defined (__MINGW32__) || defined(_MSC_VER)
|
|
#include <sys/time.h___>
|
|
#else
|
|
#include <time.h>
|
|
#endif
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include <fcntl.h> /* open, O_RDWR */
|
|
#include <errno.h>
|
|
|
|
#ifdef OS2_NT
|
|
# include <io.h>
|
|
#endif
|
|
|
|
#ifdef USE_NETCODE
|
|
#include <netdb.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_MMAP
|
|
# include <sys/mman.h>
|
|
#endif
|
|
#include "mad.h"
|
|
#include "dir.h"
|
|
#include "util.h"
|
|
#include "panel.h"
|
|
#include "cmd.h" /* Our definitions */
|
|
#include "view.h" /* view() */
|
|
#include "dialog.h" /* query_dialog, message */
|
|
#include "file.h" /* the file operations */
|
|
#include "find.h" /* do_find */
|
|
#include "hotlist.h"
|
|
#include "tree.h"
|
|
#include "subshell.h" /* use_subshell */
|
|
#include "cons.saver.h"
|
|
#include "global.h"
|
|
#include "dlg.h" /* required by wtools.h */
|
|
#include "widget.h" /* required by wtools.h */
|
|
#include "wtools.h" /* listbox */
|
|
#include "command.h" /* for input_w */
|
|
#include "win.h" /* do_exit_ca_mode */
|
|
#include "layout.h" /* get_current/other_type */
|
|
#include "ext.h" /* regex_command */
|
|
#include "view.h" /* view */
|
|
#include "key.h" /* get_key_code */
|
|
#include "help.h" /* interactive_display */
|
|
#include "fs.h"
|
|
#include "boxes.h" /* cd_dialog */
|
|
#include "color.h"
|
|
#include "user.h"
|
|
#include "setup.h"
|
|
#include "x.h"
|
|
#include "profile.h"
|
|
|
|
#define MIDNIGHT
|
|
#ifdef USE_INTERNAL_EDIT
|
|
extern int edit (const char *file, int line);
|
|
#endif
|
|
#include "../vfs/vfs.h"
|
|
#define WANT_WIDGETS
|
|
#include "main.h" /* global variables, global functions */
|
|
#ifndef MAP_FILE
|
|
# define MAP_FILE 0
|
|
#endif
|
|
|
|
#ifdef HAVE_TK
|
|
# include "tkscreen.h"
|
|
#endif
|
|
|
|
/* If set and you don't have subshell support,then C-o will give you a shell */
|
|
int output_starts_shell = 0;
|
|
|
|
/* Source routing destination */
|
|
int source_route = 0;
|
|
|
|
/* If set, use the builtin editor */
|
|
int use_internal_edit = 1;
|
|
|
|
/* Ugly hack in order to distinguish between left and right panel in menubar */
|
|
int is_right;
|
|
#define MENU_PANEL_IDX (is_right ? 1 : 0)
|
|
|
|
|
|
#ifndef PORT_HAS_FILTER_CHANGED
|
|
# define x_filter_changed(p)
|
|
#endif
|
|
|
|
/* This is used since the parameter panel on some of the commands */
|
|
/* defined in this file may receive a 0 parameter if they are invoked */
|
|
/* The drop down menu */
|
|
|
|
WPanel *get_a_panel (WPanel *panel)
|
|
{
|
|
if (panel)
|
|
return panel;
|
|
if (get_current_type () == view_listing){
|
|
return cpanel;
|
|
} else
|
|
return other_panel;
|
|
}
|
|
|
|
/* view_file (filename, normal, internal)
|
|
*
|
|
* Inputs:
|
|
* filename: The file name to view
|
|
* plain_view: If set does not do any fancy pre-processing (no filtering) and
|
|
* always invokes the internal viewer.
|
|
* internal: If set uses the internal viewer, otherwise an external viewer.
|
|
*/
|
|
int view_file_at_line (char *filename, int plain_view, int internal, int start_line)
|
|
{
|
|
static char *viewer = 0;
|
|
int move_dir = 0;
|
|
|
|
|
|
if (plain_view) {
|
|
int changed_hex_mode = 0;
|
|
int changed_nroff_flag = 0;
|
|
int changed_magic_flag = 0;
|
|
|
|
altered_hex_mode = 0;
|
|
altered_nroff_flag = 0;
|
|
altered_magic_flag = 0;
|
|
if (default_hex_mode)
|
|
changed_hex_mode = 1;
|
|
if (default_nroff_flag)
|
|
changed_nroff_flag = 1;
|
|
if (default_magic_flag)
|
|
changed_magic_flag = 1;
|
|
default_hex_mode = 0;
|
|
default_nroff_flag = 0;
|
|
default_magic_flag = 0;
|
|
view (0, filename, &move_dir, start_line);
|
|
if (changed_hex_mode && !altered_hex_mode)
|
|
default_hex_mode = 1;
|
|
if (changed_nroff_flag && !altered_nroff_flag)
|
|
default_nroff_flag = 1;
|
|
if (changed_magic_flag && !altered_magic_flag)
|
|
default_magic_flag = 1;
|
|
repaint_screen ();
|
|
return move_dir;
|
|
}
|
|
if (internal){
|
|
char view_entry [32];
|
|
|
|
if (start_line != 0)
|
|
sprintf (view_entry, "View:%d", start_line);
|
|
else
|
|
strcpy (view_entry, "View");
|
|
|
|
if (!regex_command (filename, view_entry, NULL, &move_dir)){
|
|
view (0, filename, &move_dir, start_line);
|
|
repaint_screen ();
|
|
}
|
|
} else {
|
|
char *localcopy;
|
|
|
|
if (!viewer){
|
|
viewer = getenv ("PAGER");
|
|
if (!viewer)
|
|
viewer = "view";
|
|
}
|
|
/* The file may be a non local file, get a copy */
|
|
if (!vfs_file_is_local (filename)){
|
|
localcopy = mc_getlocalcopy (filename);
|
|
if (localcopy == NULL){
|
|
message (1, MSG_ERROR, _(" Can not fetch a local copy of %s "), filename);
|
|
return 0;
|
|
}
|
|
execute_internal (viewer, localcopy);
|
|
mc_ungetlocalcopy (filename, localcopy, 0);
|
|
} else
|
|
execute_internal (viewer, filename);
|
|
}
|
|
return move_dir;
|
|
}
|
|
|
|
int
|
|
view_file (char *filename, int plain_view, int internal)
|
|
{
|
|
return view_file_at_line (filename, plain_view, internal, 0);
|
|
}
|
|
|
|
/* scan_for_file (panel, idx, direction)
|
|
*
|
|
* Inputs:
|
|
* panel: pointer to the panel on which we operate
|
|
* idx: starting file.
|
|
* direction: 1, or -1
|
|
*/
|
|
static int scan_for_file (WPanel *panel, int idx, int direction)
|
|
{
|
|
int i = idx + direction;
|
|
|
|
while (i != idx){
|
|
if (i < 0)
|
|
i = panel->count - 1;
|
|
if (i == panel->count)
|
|
i = 0;
|
|
if (!S_ISDIR (panel->dir.list [i].buf.st_mode))
|
|
return i;
|
|
i += direction;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
/* do_view: Invoked as the F3/F13 key. */
|
|
static void do_view_cmd (WPanel *panel, int normal)
|
|
{
|
|
int dir, file_idx;
|
|
panel = get_a_panel (panel);
|
|
|
|
/* Directories are viewed by changing to them */
|
|
if (S_ISDIR (selection (panel)->buf.st_mode) ||
|
|
link_isdir (selection (panel))){
|
|
if (confirm_view_dir && (panel->marked || panel->dirs_marked)){
|
|
if (query_dialog (_(" CD "), _("Files tagged, want to cd?"),
|
|
0, 2, _("&Yes"), _("&No")) == 1){
|
|
return;
|
|
}
|
|
}
|
|
do_cd (selection (panel)->fname, cd_exact);
|
|
return;
|
|
|
|
}
|
|
|
|
file_idx = panel->selected;
|
|
while (1) {
|
|
char *filename;
|
|
|
|
filename = panel->dir.list [file_idx].fname;
|
|
|
|
dir = view_file (filename, normal, use_internal_view);
|
|
if (dir == 0)
|
|
break;
|
|
file_idx = scan_for_file (panel, file_idx, dir);
|
|
}
|
|
}
|
|
|
|
void view_cmd (WPanel *panel)
|
|
{
|
|
do_view_cmd (panel, 0);
|
|
}
|
|
|
|
void view_simple_cmd (WPanel *panel)
|
|
{
|
|
do_view_cmd (panel, 1);
|
|
}
|
|
|
|
void filtered_view_cmd (WPanel *panel)
|
|
{
|
|
char *command;
|
|
|
|
panel = get_a_panel (panel);
|
|
command = input_dialog (_(" Filtered view "), _(" Filter command and arguments:"),
|
|
selection (panel)->fname);
|
|
if (!command)
|
|
return;
|
|
|
|
view (command, "", 0, 0);
|
|
|
|
free (command);
|
|
}
|
|
|
|
void filtered_view_cmd_cpanel (void)
|
|
{
|
|
filtered_view_cmd (cpanel);
|
|
}
|
|
|
|
void do_edit_at_line (const char *what, int start_line)
|
|
{
|
|
static char *editor = 0;
|
|
|
|
#ifdef USE_INTERNAL_EDIT
|
|
if (use_internal_edit){
|
|
edit (what, start_line);
|
|
reread_cmd ();
|
|
return;
|
|
}
|
|
#endif
|
|
if (!editor){
|
|
editor = getenv ("EDITOR");
|
|
if (!editor)
|
|
editor = get_default_editor ();
|
|
}
|
|
execute_internal (editor, what);
|
|
reread_cmd ();
|
|
}
|
|
|
|
void
|
|
do_edit (const char *what)
|
|
{
|
|
do_edit_at_line (what, 1);
|
|
}
|
|
|
|
void edit_cmd (WPanel *panel)
|
|
{
|
|
panel = get_a_panel(panel);
|
|
if (!regex_command (selection (panel)->fname, "Edit", NULL, 0))
|
|
do_edit (selection (panel)->fname);
|
|
}
|
|
|
|
void edit_cmd_new (WPanel *panel)
|
|
{
|
|
do_edit ("");
|
|
}
|
|
|
|
void copy_cmd (void)
|
|
{
|
|
save_cwds_stat ();
|
|
if (panel_operate (cpanel, OP_COPY, NULL)){
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
}
|
|
|
|
void ren_cmd (void)
|
|
{
|
|
save_cwds_stat ();
|
|
if (panel_operate (cpanel, OP_MOVE, NULL)){
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
}
|
|
|
|
void copymove_cmd_with_default (int copy, char *thedefault)
|
|
{
|
|
save_cwds_stat ();
|
|
if (panel_operate (cpanel, copy ? OP_COPY : OP_MOVE, thedefault)){
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
}
|
|
|
|
void mkdir_cmd (WPanel *panel)
|
|
{
|
|
char *dir;
|
|
|
|
panel = get_a_panel (panel);
|
|
dir = input_expand_dialog (_(" Mkdir "), _(" Enter directory name:") , "");
|
|
|
|
if (!dir)
|
|
return;
|
|
|
|
save_cwds_stat ();
|
|
if (my_mkdir (dir, 0777) == 0){
|
|
update_panels (UP_OPTIMIZE, dir);
|
|
repaint_screen ();
|
|
select_item (cpanel);
|
|
free (dir);
|
|
return;
|
|
}
|
|
free (dir);
|
|
message (1, MSG_ERROR, " %s ", unix_error_string (errno));
|
|
}
|
|
|
|
void delete_cmd (void)
|
|
{
|
|
save_cwds_stat ();
|
|
|
|
if (panel_operate (cpanel, OP_DELETE, NULL)){
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
}
|
|
|
|
void find_cmd (void)
|
|
{
|
|
do_find ();
|
|
}
|
|
|
|
void
|
|
set_panel_filter_to (WPanel *p, char *allocated_filter_string)
|
|
{
|
|
if (p->filter){
|
|
free (p->filter);
|
|
p->filter = 0;
|
|
}
|
|
if (!(allocated_filter_string [0] == '*' && allocated_filter_string [1] == 0))
|
|
p->filter = allocated_filter_string;
|
|
else
|
|
free (allocated_filter_string);
|
|
reread_cmd ();
|
|
x_filter_changed (p);
|
|
}
|
|
|
|
/* Set a given panel filter expression */
|
|
void set_panel_filter (WPanel *p)
|
|
{
|
|
char *reg_exp;
|
|
char *x;
|
|
|
|
x = p->filter ? p->filter : easy_patterns ? "*" : ".";
|
|
|
|
reg_exp = input_dialog (_(" Filter "), _(" Set expression for filtering filenames"), x);
|
|
if (!reg_exp)
|
|
return;
|
|
set_panel_filter_to (p, reg_exp);
|
|
}
|
|
|
|
/* Invoked from the left/right menus */
|
|
void filter_cmd (void)
|
|
{
|
|
WPanel *p;
|
|
|
|
if (!SELECTED_IS_PANEL)
|
|
return;
|
|
|
|
p = MENU_PANEL;
|
|
set_panel_filter (p);
|
|
}
|
|
|
|
void reread_cmd (void)
|
|
{
|
|
int flag;
|
|
|
|
mad_check (__FILE__, __LINE__);
|
|
if (get_current_type () == view_listing &&
|
|
get_other_type () == view_listing)
|
|
flag = strcmp (cpanel->cwd, opanel->cwd) ? UP_ONLY_CURRENT : 0;
|
|
else
|
|
flag = UP_ONLY_CURRENT;
|
|
|
|
update_panels (UP_RELOAD|flag, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
|
|
/* Panel sorting related routines */
|
|
void do_re_sort (WPanel *panel)
|
|
{
|
|
char *filename;
|
|
int i;
|
|
|
|
panel = get_a_panel (panel);
|
|
filename = strdup (selection (cpanel)->fname);
|
|
unselect_item (panel);
|
|
do_sort (&panel->dir, panel->sort_type, panel->count-1, panel->reverse, panel->case_sensitive);
|
|
panel->selected = -1;
|
|
for (i = panel->count; i; i--){
|
|
if (!strcmp (panel->dir.list [i-1].fname, filename)){
|
|
panel->selected = i-1;
|
|
break;
|
|
}
|
|
}
|
|
free (filename);
|
|
cpanel->top_file = cpanel->selected - ITEMS (cpanel)/2;
|
|
if (cpanel->top_file < 0)
|
|
cpanel->top_file = 0;
|
|
select_item (panel);
|
|
panel_update_contents (panel);
|
|
}
|
|
|
|
void reverse_selection_cmd_panel (WPanel *panel)
|
|
{
|
|
file_entry *file;
|
|
int i;
|
|
|
|
for (i = 0; i < panel->count; i++){
|
|
file = &panel->dir.list [i];
|
|
if (S_ISDIR (file->buf.st_mode))
|
|
continue;
|
|
do_file_mark (panel, i, !file->f.marked);
|
|
}
|
|
paint_panel (panel);
|
|
}
|
|
|
|
void reverse_selection_cmd (void)
|
|
{
|
|
reverse_selection_cmd_panel (cpanel);
|
|
}
|
|
|
|
void select_cmd_panel (WPanel *panel)
|
|
{
|
|
char *reg_exp, *reg_exp_t;
|
|
int i;
|
|
int c;
|
|
int dirflag = 0;
|
|
|
|
reg_exp = input_dialog (_(" Select "), "", easy_patterns ? "*" : ".");
|
|
if (!reg_exp)
|
|
return;
|
|
|
|
reg_exp_t = reg_exp;
|
|
|
|
/* Check if they specified a directory */
|
|
if (*reg_exp_t == PATH_SEP){
|
|
dirflag = 1;
|
|
reg_exp_t++;
|
|
}
|
|
if (reg_exp_t [strlen(reg_exp_t) - 1] == PATH_SEP){
|
|
dirflag = 1;
|
|
reg_exp_t [strlen(reg_exp_t) - 1] = 0;
|
|
}
|
|
|
|
for (i = 0; i < panel->count; i++){
|
|
if (!strcmp (panel->dir.list [i].fname, ".."))
|
|
continue;
|
|
if (S_ISDIR (panel->dir.list [i].buf.st_mode)){
|
|
if (!dirflag)
|
|
continue;
|
|
} else {
|
|
if (dirflag)
|
|
continue;
|
|
}
|
|
c = regexp_match (reg_exp_t, panel->dir.list [i].fname, match_file);
|
|
if (c == -1){
|
|
message (1, MSG_ERROR, _(" Malformed regular expression "));
|
|
free (reg_exp);
|
|
return;
|
|
}
|
|
if (c){
|
|
do_file_mark (panel, i, 1);
|
|
}
|
|
}
|
|
paint_panel (panel);
|
|
free (reg_exp);
|
|
}
|
|
|
|
void select_cmd (void)
|
|
{
|
|
select_cmd_panel (cpanel);
|
|
}
|
|
|
|
void unselect_cmd_panel (WPanel *panel)
|
|
{
|
|
char *reg_exp, *reg_exp_t;
|
|
int i;
|
|
int c;
|
|
int dirflag = 0;
|
|
|
|
reg_exp = input_dialog (_(" Unselect "),"", easy_patterns ? "*" : ".");
|
|
if (!reg_exp)
|
|
return;
|
|
|
|
reg_exp_t = reg_exp;
|
|
|
|
/* Check if they specified directory matching */
|
|
if (*reg_exp_t == PATH_SEP){
|
|
dirflag = 1;
|
|
reg_exp_t ++;
|
|
}
|
|
if (reg_exp_t [strlen(reg_exp_t) - 1] == PATH_SEP){
|
|
dirflag = 1;
|
|
reg_exp_t [strlen(reg_exp_t) - 1] = 0;
|
|
}
|
|
for (i = 0; i < panel->count; i++){
|
|
if (!strcmp (panel->dir.list [i].fname, ".."))
|
|
continue;
|
|
if (S_ISDIR (panel->dir.list [i].buf.st_mode)){
|
|
if (!dirflag)
|
|
continue;
|
|
} else {
|
|
if (dirflag)
|
|
continue;
|
|
}
|
|
c = regexp_match (reg_exp_t, panel->dir.list [i].fname, match_file);
|
|
if (c == -1){
|
|
message (1, MSG_ERROR, _(" Malformed regular expression "));
|
|
free (reg_exp);
|
|
return;
|
|
}
|
|
if (c){
|
|
do_file_mark (panel, i, 0);
|
|
}
|
|
}
|
|
paint_panel (panel);
|
|
free (reg_exp);
|
|
}
|
|
|
|
void unselect_cmd (void)
|
|
{
|
|
unselect_cmd_panel (cpanel);
|
|
}
|
|
|
|
/* Check if the file exists */
|
|
/* If not copy the default */
|
|
static int check_for_default(char *default_file, char *file)
|
|
{
|
|
struct stat s;
|
|
if (mc_stat (file, &s)){
|
|
if (mc_stat (default_file, &s)){
|
|
return -1;
|
|
}
|
|
create_op_win (OP_COPY, 0);
|
|
file_mask_defaults ();
|
|
copy_file_file (default_file, file, 1);
|
|
destroy_op_win ();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ext_cmd (void)
|
|
{
|
|
char *buffer;
|
|
char *extdir;
|
|
int dir;
|
|
|
|
dir = 0;
|
|
if (geteuid () == 0){
|
|
dir = query_dialog (_("Extension file edit"),
|
|
_(" Which extension file you want to edit? "), 0, 2,
|
|
_("&User"), _("&System Wide"));
|
|
}
|
|
extdir = concat_dir_and_file (mc_home, MC_LIB_EXT);
|
|
|
|
if (dir == 0){
|
|
buffer = concat_dir_and_file (home_dir, MC_USER_EXT);
|
|
check_for_default (extdir, buffer);
|
|
do_edit (buffer);
|
|
free (buffer);
|
|
} else if (dir == 1)
|
|
do_edit (extdir);
|
|
|
|
free (extdir);
|
|
flush_extension_file ();
|
|
}
|
|
|
|
void menu_edit_cmd (void)
|
|
{
|
|
char *buffer;
|
|
char *menufile;
|
|
int dir = 0;
|
|
|
|
dir = query_dialog (
|
|
_("Menu file edit"),
|
|
_(" Which menu file will you edit? "),
|
|
0, geteuid() ? 2 : 3,
|
|
_("&Local"), _("&Home"), _("&System Wide")
|
|
);
|
|
|
|
menufile = concat_dir_and_file(mc_home, MC_GLOBAL_MENU);
|
|
|
|
switch (dir){
|
|
case 0:
|
|
buffer = strdup (MC_LOCAL_MENU);
|
|
check_for_default (menufile, buffer);
|
|
break;
|
|
|
|
case 1:
|
|
buffer = concat_dir_and_file (home_dir, MC_HOME_MENU);
|
|
check_for_default (menufile, buffer);
|
|
break;
|
|
|
|
case 2:
|
|
buffer = concat_dir_and_file (mc_home, MC_GLOBAL_MENU);
|
|
break;
|
|
|
|
default:
|
|
free (menufile);
|
|
return;
|
|
}
|
|
do_edit (buffer);
|
|
if (dir == 0)
|
|
chmod(buffer, 0600);
|
|
free (buffer);
|
|
free (menufile);
|
|
}
|
|
|
|
void quick_chdir_cmd (void)
|
|
{
|
|
char *target;
|
|
|
|
target = hotlist_cmd (LIST_HOTLIST);
|
|
if (!target)
|
|
return;
|
|
|
|
if (get_current_type () == view_tree)
|
|
tree_chdir (the_tree, target);
|
|
else
|
|
do_cd (target, cd_exact);
|
|
free (target);
|
|
}
|
|
|
|
#ifdef USE_VFS
|
|
void reselect_vfs (void)
|
|
{
|
|
char *target;
|
|
|
|
target = hotlist_cmd (LIST_VFSLIST);
|
|
if (!target)
|
|
return;
|
|
|
|
do_cd (target, cd_exact);
|
|
free (target);
|
|
}
|
|
#endif
|
|
|
|
static int compare_files (char *name1, char *name2, long size)
|
|
{
|
|
int file1, file2;
|
|
char *data1, *data2;
|
|
int result = -1; /* Different by default */
|
|
|
|
file1 = open (name1, O_RDONLY);
|
|
if (file1 >= 0){
|
|
file2 = open (name2, O_RDONLY);
|
|
if (file2 >= 0){
|
|
#ifdef HAVE_MMAP
|
|
/* Ugly if jungle */
|
|
data1 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file1, 0);
|
|
if (data1 != (char*) -1){
|
|
data2 = mmap (0, size, PROT_READ, MAP_FILE | MAP_PRIVATE, file2, 0);
|
|
if (data2 != (char*) -1){
|
|
rotate_dash ();
|
|
result = memcmp (data1, data2, size);
|
|
munmap (data2, size);
|
|
}
|
|
munmap (data1, size);
|
|
}
|
|
#else
|
|
/* Don't have mmap() :( Even more ugly :) */
|
|
char buf1[BUFSIZ], buf2[BUFSIZ];
|
|
int n1, n2;
|
|
rotate_dash ();
|
|
do
|
|
{
|
|
while((n1 = read(file1,buf1,BUFSIZ)) == -1 && errno == EINTR);
|
|
while((n2 = read(file2,buf2,BUFSIZ)) == -1 && errno == EINTR);
|
|
} while (n1 == n2 && n1 == BUFSIZ && !memcmp(buf1,buf2,BUFSIZ));
|
|
result = (n1 != n2) || memcmp(buf1,buf2,n1);
|
|
#endif
|
|
close (file2);
|
|
}
|
|
close (file1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
enum CompareMode {
|
|
compare_quick, compare_size_only, compare_thourough
|
|
};
|
|
|
|
static void
|
|
compare_dir (WPanel *panel, WPanel *other, enum CompareMode mode)
|
|
{
|
|
int i, j;
|
|
char *src_name, *dst_name;
|
|
|
|
panel = get_a_panel (panel);
|
|
|
|
/* No marks by default */
|
|
panel->marked = 0;
|
|
panel->total = 0;
|
|
panel->dirs_marked = 0;
|
|
|
|
/* Handle all files in the panel */
|
|
for (i = 0; i < panel->count; i++){
|
|
file_entry *source = &panel->dir.list[i];
|
|
|
|
/* Default: unmarked */
|
|
file_mark (panel, i, 0);
|
|
|
|
/* Skip directories */
|
|
if (S_ISDIR (source->buf.st_mode))
|
|
continue;
|
|
|
|
/* Search the corresponding entry from the other panel */
|
|
for (j = 0; j < other->count; j++){
|
|
if (strcmp (source->fname,
|
|
other->dir.list[j].fname) == 0)
|
|
break;
|
|
}
|
|
if (j >= other->count)
|
|
/* Not found -> mark */
|
|
do_file_mark (panel, i, 1);
|
|
else {
|
|
/* Found */
|
|
file_entry *target = &other->dir.list[j];
|
|
|
|
if (mode != compare_size_only){
|
|
/* Older version is not marked */
|
|
if (source->buf.st_mtime < target->buf.st_mtime)
|
|
continue;
|
|
}
|
|
|
|
/* Newer version with different size is marked */
|
|
if (source->buf.st_size != target->buf.st_size){
|
|
do_file_mark (panel, i, 1);
|
|
continue;
|
|
|
|
}
|
|
if (mode == compare_size_only)
|
|
continue;
|
|
|
|
if (mode == compare_quick){
|
|
/* Thorough compare off, compare only time stamps */
|
|
/* Mark newer version, don't mark version with the same date */
|
|
if (source->buf.st_mtime > target->buf.st_mtime){
|
|
do_file_mark (panel, i, 1);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
/* Thorough compare on, do byte-by-byte comparison */
|
|
src_name = get_full_name (panel->cwd, source->fname);
|
|
dst_name = get_full_name (other->cwd, target->fname);
|
|
if (compare_files (src_name, dst_name, source->buf.st_size))
|
|
do_file_mark (panel, i, 1);
|
|
free (src_name);
|
|
free (dst_name);
|
|
}
|
|
} /* for (i ...) */
|
|
}
|
|
|
|
void compare_dirs_cmd (void)
|
|
{
|
|
enum CompareMode thorough_flag = compare_quick;
|
|
|
|
thorough_flag = query_dialog (_(" Compare directories "), _(" Select compare method: "),
|
|
0, 3, _("&Quick"), _("&Size only"), _("&Thorough"), _("&Cancel"));
|
|
if (thorough_flag < 0 || thorough_flag > 2)
|
|
return;
|
|
if (get_current_type () == view_listing &&
|
|
get_other_type () == view_listing){
|
|
compare_dir (cpanel, opanel, thorough_flag);
|
|
compare_dir (opanel, cpanel, thorough_flag);
|
|
paint_panel (cpanel);
|
|
paint_panel (opanel);
|
|
} else {
|
|
message (1, MSG_ERROR, _(" Both panels should be on the listing view mode to use this command "));
|
|
}
|
|
}
|
|
|
|
void history_cmd (void)
|
|
{
|
|
Listbox *listbox;
|
|
Hist *current;
|
|
|
|
if (input_w (cmdline)->need_push){
|
|
if (push_history (input_w (cmdline), input_w (cmdline)->buffer) == 2)
|
|
input_w (cmdline)->need_push = 0;
|
|
}
|
|
if (!input_w (cmdline)->history){
|
|
message (1, MSG_ERROR, _(" The command history is empty "));
|
|
return;
|
|
}
|
|
current = input_w (cmdline)->history;
|
|
while (current->prev)
|
|
current = current->prev;
|
|
listbox = create_listbox_window (60, 10, _(" Command history "),
|
|
"[Command Menu]");
|
|
while (current){
|
|
LISTBOX_APPEND_TEXT (listbox, 0, current->text,
|
|
current);
|
|
current = current->next;
|
|
}
|
|
run_dlg (listbox->dlg);
|
|
if (listbox->dlg->ret_value == B_CANCEL)
|
|
current = NULL;
|
|
else
|
|
current = listbox->list->current->data;
|
|
destroy_dlg (listbox->dlg);
|
|
free (listbox);
|
|
|
|
if (!current)
|
|
return;
|
|
input_w (cmdline)->history = current;
|
|
assign_text (input_w (cmdline), input_w (cmdline)->history->text);
|
|
update_input (input_w (cmdline), 1);
|
|
}
|
|
|
|
#if !defined(HAVE_XVIEW) && !defined(HAVE_GNOME)
|
|
void swap_cmd (void)
|
|
{
|
|
swap_panels ();
|
|
touchwin (stdscr);
|
|
repaint_screen ();
|
|
}
|
|
#endif
|
|
|
|
void
|
|
view_other_cmd (void)
|
|
{
|
|
static int message_flag = TRUE;
|
|
#ifdef HAVE_SUBSHELL_SUPPORT
|
|
char *new_dir = NULL;
|
|
char **new_dir_p;
|
|
#endif
|
|
|
|
if (!xterm_flag && !console_flag && !use_subshell){
|
|
if (message_flag)
|
|
message (1, MSG_ERROR, _(" Not an xterm or Linux console; \n"
|
|
" the panels cannot be toggled. "));
|
|
message_flag = FALSE;
|
|
} else {
|
|
#ifndef HAVE_X
|
|
if (use_mouse_p)
|
|
shut_mouse ();
|
|
if (clear_before_exec)
|
|
clr_scr ();
|
|
if (alternate_plus_minus)
|
|
numeric_keypad_mode ();
|
|
#endif
|
|
#ifndef HAVE_SLANG
|
|
/* With slang we don't want any of this, since there
|
|
* is no mc_raw_mode supported
|
|
*/
|
|
reset_shell_mode ();
|
|
noecho ();
|
|
#endif
|
|
keypad(stdscr, FALSE);
|
|
endwin ();
|
|
if (!status_using_ncurses)
|
|
do_exit_ca_mode ();
|
|
mc_raw_mode ();
|
|
if (console_flag)
|
|
restore_console ();
|
|
|
|
#ifdef HAVE_SUBSHELL_SUPPORT
|
|
if (use_subshell){
|
|
new_dir_p = vfs_current_is_local () ? &new_dir : NULL;
|
|
if (invoke_subshell (NULL, VISIBLY, new_dir_p))
|
|
quiet_quit_cmd(); /* User did `exit' or `logout': quit MC quietly */
|
|
} else
|
|
#endif
|
|
{
|
|
if (output_starts_shell){
|
|
fprintf (stderr,
|
|
_("Type `exit' to return to the Midnight Commander\n\r\n\r"));
|
|
my_system (EXECUTE_AS_SHELL, shell, NULL);
|
|
} else
|
|
get_key_code (0);
|
|
}
|
|
if (console_flag)
|
|
handle_console (CONSOLE_SAVE);
|
|
|
|
if (!status_using_ncurses)
|
|
do_enter_ca_mode ();
|
|
|
|
reset_prog_mode ();
|
|
keypad(stdscr, TRUE);
|
|
#ifndef HAVE_X
|
|
if (use_mouse_p)
|
|
init_mouse ();
|
|
if (alternate_plus_minus)
|
|
application_keypad_mode ();
|
|
#endif
|
|
|
|
#ifdef HAVE_SUBSHELL_SUPPORT
|
|
if (use_subshell){
|
|
load_prompt (0, 0);
|
|
if (new_dir)
|
|
do_possible_cd (new_dir);
|
|
if (console_flag && output_lines)
|
|
show_console_contents (output_start_y,
|
|
LINES-keybar_visible-output_lines-1,
|
|
LINES-keybar_visible-1);
|
|
}
|
|
#endif
|
|
touchwin (stdscr);
|
|
|
|
/* prevent screen flash when user did 'exit' or 'logout' within
|
|
subshell */
|
|
if (!quit)
|
|
repaint_screen ();
|
|
}
|
|
}
|
|
|
|
#ifndef OS2_NT
|
|
static void
|
|
do_link (int symbolic_link, char *fname)
|
|
{
|
|
struct stat s;
|
|
char *dest, *src;
|
|
int stat_r;
|
|
|
|
if (!symbolic_link){
|
|
stat_r = mc_stat (fname, &s);
|
|
if (stat_r != 0){
|
|
message (1, MSG_ERROR, _(" Couldn't stat %s \n %s "),
|
|
fname, unix_error_string (errno));
|
|
return;
|
|
}
|
|
if (!S_ISREG (s.st_mode))
|
|
return;
|
|
}
|
|
|
|
if (!symbolic_link){
|
|
src = copy_strings (_(" Link "), name_trunc (fname, 46),
|
|
_(" to:"), NULL);
|
|
dest = input_expand_dialog (_(" Link "), src, "");
|
|
free (src);
|
|
if (!dest)
|
|
return;
|
|
if (!*dest) {
|
|
free (dest);
|
|
return;
|
|
}
|
|
save_cwds_stat ();
|
|
if (-1 == mc_link (fname, dest))
|
|
message (1, MSG_ERROR, _(" link: %s "), unix_error_string (errno));
|
|
} else {
|
|
#ifdef OLD_SYMLINK_VERSION
|
|
symlink_dialog (fname, "", &dest, &src);
|
|
#else
|
|
/* suggest the full path for symlink */
|
|
char s[MC_MAXPATHLEN];
|
|
char d[MC_MAXPATHLEN];
|
|
|
|
strcpy(s, cpanel->cwd);
|
|
if ( ! ((s[0] == '/') && (s[1] == 0)))
|
|
strcat(s, "/");
|
|
strcat(s, fname);
|
|
if (get_other_type () == view_listing)
|
|
strcpy(d, opanel->cwd);
|
|
else
|
|
strcpy (d,"");
|
|
|
|
if ( ! ((d[0] == '/') && (d[1] == 0)))
|
|
strcat(d, "/");
|
|
symlink_dialog (s, d, &dest, &src);
|
|
#endif
|
|
if (!dest || !*dest) {
|
|
if (src)
|
|
free (src);
|
|
if (dest)
|
|
free (dest);
|
|
return;
|
|
}
|
|
if (src){
|
|
if (*src) {
|
|
save_cwds_stat ();
|
|
if (-1 == mc_symlink (dest, src))
|
|
message (1, MSG_ERROR, _(" symlink: %s "),
|
|
unix_error_string (errno));
|
|
}
|
|
free (src);
|
|
}
|
|
}
|
|
free (dest);
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
|
|
void link_cmd (void)
|
|
{
|
|
do_link (0, selection (cpanel)->fname);
|
|
}
|
|
|
|
void symlink_cmd (void)
|
|
{
|
|
do_link (1, selection (cpanel)->fname);
|
|
}
|
|
|
|
void edit_symlink_cmd (void)
|
|
{
|
|
if (S_ISLNK (selection (cpanel)->buf.st_mode)) {
|
|
char buffer [MC_MAXPATHLEN], *p = selection (cpanel)->fname;
|
|
int i;
|
|
char *dest, *q = copy_strings (_(" Symlink "), name_trunc (p, 32), _(" points to:"), NULL);
|
|
|
|
i = readlink (p, buffer, MC_MAXPATHLEN);
|
|
if (i > 0) {
|
|
buffer [i] = 0;
|
|
dest = input_expand_dialog (_(" Edit symlink "), q, buffer);
|
|
if (dest) {
|
|
if (*dest && strcmp (buffer, dest)) {
|
|
save_cwds_stat ();
|
|
mc_unlink (p);
|
|
if (-1 == mc_symlink (dest, p))
|
|
message (1, MSG_ERROR, _(" edit symlink: %s "),
|
|
unix_error_string (errno));
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
}
|
|
free (dest);
|
|
}
|
|
}
|
|
free (q);
|
|
}
|
|
}
|
|
|
|
void other_symlink_cmd (void)
|
|
{
|
|
char *dest, *q, *p, *r, *s, *t;
|
|
|
|
if (get_other_type () != view_listing)
|
|
return;
|
|
|
|
if (!strcmp (selection (opanel)->fname, ".."))
|
|
return;
|
|
p = concat_dir_and_file (cpanel->cwd, selection (cpanel)->fname);
|
|
r = concat_dir_and_file (opanel->cwd, selection (cpanel)->fname);
|
|
|
|
q = copy_strings (_(" Link symbolically "), name_trunc (p, 32), _(" to:"), NULL);
|
|
dest = input_expand_dialog (_(" Relative symlink "), q, r);
|
|
if (dest) {
|
|
if (*dest) {
|
|
t = strrchr (dest, PATH_SEP);
|
|
if (t) {
|
|
t[1] = 0;
|
|
s = diff_two_paths (dest, p);
|
|
t[1] = PATH_SEP;
|
|
if (s) {
|
|
save_cwds_stat ();
|
|
if (-1 == mc_symlink (dest, s))
|
|
message (1, MSG_ERROR, _(" relative symlink: %s "),
|
|
unix_error_string (errno));
|
|
update_panels (UP_OPTIMIZE, UP_KEEPSEL);
|
|
repaint_screen ();
|
|
free (s);
|
|
}
|
|
}
|
|
}
|
|
free (dest);
|
|
}
|
|
free (q);
|
|
free (p);
|
|
free (r);
|
|
}
|
|
#endif
|
|
|
|
void help_cmd (void)
|
|
{
|
|
char *hlpfile = concat_dir_and_file (mc_home, "mc.hlp");
|
|
interactive_display (hlpfile, "[main]");
|
|
free (hlpfile);
|
|
}
|
|
|
|
void view_panel_cmd (void)
|
|
{
|
|
view_cmd (cpanel);
|
|
}
|
|
|
|
void edit_panel_cmd (void)
|
|
{
|
|
edit_cmd (cpanel);
|
|
}
|
|
|
|
void mkdir_panel_cmd (void)
|
|
{
|
|
mkdir_cmd (cpanel);
|
|
}
|
|
|
|
/* Returns a random hint */
|
|
char *get_random_hint (void)
|
|
{
|
|
char *data, *result, *eol;
|
|
char *hintfile;
|
|
int len;
|
|
int start;
|
|
|
|
/* Do not change hints more often than one minute */
|
|
|
|
#ifdef SCO_FLAVOR
|
|
static time_t last;
|
|
time_t now;
|
|
|
|
time (&now);
|
|
if ((now - last) < 60)
|
|
return strdup ("");
|
|
last = now;
|
|
#else
|
|
static int last_sec;
|
|
static struct timeval tv;
|
|
|
|
gettimeofday (&tv, NULL);
|
|
if (!(tv.tv_sec> last_sec+60))
|
|
return strdup ("");
|
|
last_sec = tv.tv_sec;
|
|
#endif
|
|
|
|
hintfile = concat_dir_and_file (mc_home, MC_HINT);
|
|
data = load_file (hintfile);
|
|
free (hintfile);
|
|
if (!data)
|
|
return 0;
|
|
|
|
#ifdef SCO_FLAVOR
|
|
srand ((short) now);
|
|
#else
|
|
srand (tv.tv_sec);
|
|
#endif
|
|
/* get a random entry */
|
|
len = strlen (data);
|
|
start = rand () % len;
|
|
|
|
for (;start; start--){
|
|
if (data [start] == '\n'){
|
|
start++;
|
|
break;
|
|
}
|
|
}
|
|
eol = strchr (&data [start], '\n');
|
|
if (eol)
|
|
*eol = 0;
|
|
result = strdup (&data [start]);
|
|
free (data);
|
|
return result;
|
|
}
|
|
|
|
#ifndef USE_VFS
|
|
#ifdef USE_NETCODE
|
|
#undef USE_NETCODE
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef USE_NETCODE
|
|
|
|
static char *machine_str = N_(" Enter machine name (F1 for details): ");
|
|
|
|
static void nice_cd (char *text, char *xtext, char *help, char *prefix, int to_home)
|
|
{
|
|
char *machine;
|
|
char *cd_path;
|
|
|
|
if (!SELECTED_IS_PANEL)
|
|
return;
|
|
|
|
machine = input_dialog_help (text,
|
|
xtext,
|
|
help, "");
|
|
if (!machine)
|
|
return;
|
|
|
|
if (strncmp (prefix, machine, strlen (prefix)) == 0)
|
|
cd_path = copy_strings (machine, to_home ? "/~/" : NULL, NULL);
|
|
else
|
|
cd_path = copy_strings (prefix, machine, to_home ? "/~/" : NULL, NULL);
|
|
|
|
if (do_panel_cd (MENU_PANEL, cd_path, 0))
|
|
directory_history_add (MENU_PANEL, (MENU_PANEL)->cwd);
|
|
else
|
|
message (1, MSG_ERROR, N_(" Could not chdir to %s "), cd_path);
|
|
free (cd_path);
|
|
free (machine);
|
|
}
|
|
|
|
void netlink_cmd (void)
|
|
{
|
|
nice_cd (_(" Link to a remote machine "), _(machine_str),
|
|
"[Network File System]", "mc:", 1);
|
|
}
|
|
|
|
void ftplink_cmd (void)
|
|
{
|
|
nice_cd (_(" FTP to machine "), _(machine_str),
|
|
"[FTP File System]", "ftp://", 1);
|
|
}
|
|
|
|
#ifdef HAVE_SETSOCKOPT
|
|
void source_routing (void)
|
|
{
|
|
char *source;
|
|
struct hostent *hp;
|
|
|
|
source = input_dialog (_(" Socket source routing setup "),
|
|
_(" Enter host name to use as a source routing hop: ")n,
|
|
"");
|
|
if (!source)
|
|
return;
|
|
|
|
hp = gethostbyname (source);
|
|
if (!hp){
|
|
message (1, _(" Host name "), _(" Error while looking up IP address "));
|
|
return;
|
|
}
|
|
source_route = *((int *)hp->h_addr);
|
|
}
|
|
#endif /* HAVE_SETSOCKOPT */
|
|
#endif /* USE_NETCODE */
|
|
|
|
#ifdef USE_EXT2FSLIB
|
|
void undelete_cmd (void)
|
|
{
|
|
nice_cd (_(" Undelete files on an ext2 file system "),
|
|
_(" Enter the file system name where you want to run the\n "
|
|
" undelete file system on: (F1 for details)"),
|
|
"[Undelete File System]", "undel:", 0);
|
|
}
|
|
#endif
|
|
|
|
void quick_cd_cmd (void)
|
|
{
|
|
char *p = cd_dialog ();
|
|
|
|
if (p && *p) {
|
|
char *q = copy_strings ("cd ", p, NULL);
|
|
|
|
do_cd_command (q);
|
|
free (q);
|
|
}
|
|
if (p)
|
|
free (p);
|
|
}
|
|
|
|
#ifdef SCO_FLAVOR
|
|
#undef DUSUM_USEB
|
|
#undef DUSUM_FACTOR
|
|
#endif /* SCO_FLAVOR */
|
|
|
|
#ifdef HAVE_DUSUM
|
|
void dirsizes_cmd (void)
|
|
{
|
|
WPanel *panel = cpanel;
|
|
int i, j = 0;
|
|
char *cmd, *p, *q, *r;
|
|
FILE *f;
|
|
#ifdef DUSUM_USEB
|
|
# define dirsizes_command "du -s -b "
|
|
#else
|
|
# define dirsizes_command "du -s "
|
|
#endif
|
|
#ifndef DUSUM_FACTOR
|
|
# define DUSUM_FACTOR 512
|
|
#endif
|
|
|
|
if (!vfs_current_is_local ())
|
|
return;
|
|
for (i = 0; i < panel->count; i++)
|
|
if (S_ISDIR (panel->dir.list [i].buf.st_mode))
|
|
j += strlen (panel->dir.list [i].fname) + 1;
|
|
if (!j)
|
|
return;
|
|
cmd = xmalloc (strlen (dirsizes_command) + j + 1, "dirsizes_cmd");
|
|
strcpy (cmd, dirsizes_command);
|
|
p = strchr (cmd, 0);
|
|
for (i = 0; i < panel->count; i++)
|
|
if (S_ISDIR (panel->dir.list [i].buf.st_mode) &&
|
|
strcmp (panel->dir.list [i].fname, "..")) {
|
|
strcpy (p, panel->dir.list [i].fname);
|
|
p = strchr (p, 0);
|
|
*(p++) = ' ';
|
|
}
|
|
*(--p) = 0;
|
|
open_error_pipe ();
|
|
f = popen (cmd, "r");
|
|
free (cmd);
|
|
if (f != NULL) {
|
|
/* Assume that du will display the directories in the order
|
|
* I've passed to it :(
|
|
*/
|
|
i = 0;
|
|
p = xmalloc (1024, "dirsizes_cmd");
|
|
while (fgets (p, 1024, f)) {
|
|
j = atoi (p) * DUSUM_FACTOR;
|
|
for (q = p; *q && *q != ' ' && *q != '\t'; q++);
|
|
while (*q == ' ' || *q == '\t')
|
|
q++;
|
|
r = strchr (q, '\n');
|
|
if (r == NULL)
|
|
r = strchr (q, 0);
|
|
for (; i < panel->count; i++)
|
|
if (S_ISDIR (panel->dir.list [i].buf.st_mode))
|
|
if (!strncmp (q, panel->dir.list [i].fname,
|
|
r - q)) {
|
|
if (panel->dir.list [i].f.marked)
|
|
panel->total += j -
|
|
((panel->has_dir_sizes) ? panel->dir.list [i].buf.st_size : 0);
|
|
panel->dir.list [i].buf.st_size = j;
|
|
break;
|
|
}
|
|
if (i == panel->count)
|
|
break;
|
|
}
|
|
free (p);
|
|
if (pclose (f) < 0)
|
|
#ifndef SCO_FLAVOR
|
|
message (0, _("Show directory sizes"), _("Pipe close failed"));
|
|
else
|
|
#else /* SCO_FLAVOR */
|
|
/*
|
|
** SCO reports about error while all seems to be ok. Just ignore it...
|
|
** (alex@bcs.zaporizhzhe.ua)
|
|
*/
|
|
;
|
|
#endif /* SCO_FLAVOR */
|
|
panel->has_dir_sizes = 1;
|
|
close_error_pipe (0, 0);
|
|
paint_panel (panel);
|
|
} else
|
|
close_error_pipe (1, _("Cannot invoke du command."));
|
|
}
|
|
#endif
|
|
|
|
void
|
|
save_setup_cmd (void)
|
|
{
|
|
char *str;
|
|
|
|
save_setup ();
|
|
sync_profiles ();
|
|
str = copy_strings ( _(" Setup saved to ~/"), PROFILE_NAME, NULL);
|
|
|
|
#ifdef HAVE_GNOME
|
|
set_hintbar (str);
|
|
#else
|
|
message (0, _(" Setup "), str);
|
|
#endif
|
|
free (str);
|
|
}
|
|
|
|
void
|
|
configure_panel_listing (WPanel *p, int view_type, int use_msformat, char *user, char *status)
|
|
{
|
|
int err;
|
|
|
|
p->user_mini_status = use_msformat;
|
|
p->list_type = view_type;
|
|
|
|
if (view_type == list_user || use_msformat){
|
|
free (p->user_format);
|
|
p->user_format = user;
|
|
|
|
free (p->user_status_format [view_type]);
|
|
p->user_status_format [view_type] = status;
|
|
|
|
err = set_panel_formats (p);
|
|
|
|
if (err){
|
|
if (err & 0x01){
|
|
free (p->user_format);
|
|
p->user_format = strdup (DEFAULT_USER_FORMAT);
|
|
}
|
|
|
|
if (err & 0x02){
|
|
free (p->user_status_format [view_type]);
|
|
p->user_status_format [view_type] = strdup (DEFAULT_USER_FORMAT);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
free (user);
|
|
free (status);
|
|
}
|
|
|
|
set_panel_formats (p);
|
|
paint_panel (p);
|
|
|
|
do_refresh ();
|
|
}
|
|
|
|
#ifndef HAVE_GNOME
|
|
void
|
|
info_cmd_no_menu (void)
|
|
{
|
|
set_display_type (cpanel == left_panel ? 1 : 0, view_info);
|
|
}
|
|
|
|
void
|
|
quick_cmd_no_menu (void)
|
|
{
|
|
set_display_type (cpanel == left_panel ? 1 : 0, view_quick);
|
|
}
|
|
|
|
void
|
|
switch_to_listing (int panel_index)
|
|
{
|
|
if (get_display_type (panel_index) != view_listing)
|
|
set_display_type (panel_index, view_listing);
|
|
}
|
|
|
|
void
|
|
listing_cmd (void)
|
|
{
|
|
int view_type, use_msformat;
|
|
char *user, *status;
|
|
WPanel *p;
|
|
int display_type;
|
|
|
|
display_type = get_display_type (MENU_PANEL_IDX);
|
|
if (display_type == view_listing)
|
|
p = MENU_PANEL_IDX == 0 ? left_panel : right_panel;
|
|
else
|
|
p = 0;
|
|
|
|
view_type = display_box (p, &user, &status, &use_msformat, MENU_PANEL_IDX);
|
|
|
|
if (view_type == -1)
|
|
return;
|
|
|
|
switch_to_listing (MENU_PANEL_IDX);
|
|
|
|
p = MENU_PANEL_IDX == 0 ? left_panel : right_panel;
|
|
|
|
configure_panel_listing (p, view_type, use_msformat, user, status);
|
|
}
|
|
|
|
void
|
|
tree_cmd (void)
|
|
{
|
|
set_display_type (MENU_PANEL_IDX, view_tree);
|
|
}
|
|
|
|
void
|
|
info_cmd (void)
|
|
{
|
|
set_display_type (MENU_PANEL_IDX, view_info);
|
|
}
|
|
|
|
void
|
|
quick_view_cmd (void)
|
|
{
|
|
set_display_type (MENU_PANEL_IDX, view_quick);
|
|
}
|
|
#endif
|
|
|
|
/* Handle the tree internal listing modes switching */
|
|
static int
|
|
set_basic_panel_listing_to (int panel_index, int listing_mode)
|
|
{
|
|
WPanel *p = (WPanel *) get_panel_widget (panel_index);
|
|
|
|
#ifndef HAVE_GNOME
|
|
switch_to_listing (panel_index);
|
|
#endif
|
|
p->list_type = listing_mode;
|
|
if (set_panel_formats (p))
|
|
return 0;
|
|
|
|
paint_panel (p);
|
|
do_refresh ();
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
toggle_listing_cmd (void)
|
|
{
|
|
int current = get_current_index ();
|
|
WPanel *p = (WPanel *) get_panel_widget (current);
|
|
int list_mode = p->list_type;
|
|
int m;
|
|
|
|
switch (list_mode){
|
|
case list_full:
|
|
case list_brief:
|
|
m = list_long;
|
|
break;
|
|
case list_long:
|
|
m = list_user;
|
|
break;
|
|
default:
|
|
m = list_full;
|
|
}
|
|
if (set_basic_panel_listing_to (current, m))
|
|
return;
|
|
set_basic_panel_listing_to (current, list_full);
|
|
}
|
|
|