/* Panel managing.
Copyright (C) 1994, 1995 Miguel de Icaza.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#endif
#ifndef PORT_HAS_PANEL_RESET_SORT_LABELS
-# define x_reset_sort_labels(x)
+# define x_reset_sort_labels(x)
#endif
/* This macro extracts the number of available lines in a panel */
delete_format (format_e *format)
{
format_e *next;
-
+
while (format){
next = format->next;
free (format);
add_permission_string (char *dest, int width, file_entry *fe, int attr, int color, int is_octal)
{
int i, r, l;
-
+
l = get_user_rights (&fe->buf);
-
+
if (is_octal){
/* Place of the access bit in octal mode */
l = width + l - 3;
l = l * 3 + 1;
r = l + 3;
}
-
+
for(i = 0; i < width; i++){
if (i >= l && i < r){
if (attr == SELECTED || attr == MARKED_SELECTED)
attrset (MARKED_COLOR);
} else
attrset (color);
-
+
addch (dest[i]);
}
}
#ifdef HAVE_ST_RDEV
if (S_ISBLK (fe->buf.st_mode) || S_ISCHR (fe->buf.st_mode))
- sprintf (buffer, "%3d,%3d", (int) (fe->buf.st_rdev >> 8),
+ sprintf (buffer, "%3d,%3d", (int) (fe->buf.st_rdev >> 8),
(int) (fe->buf.st_rdev & 0xff));
else
-#endif
- {
+#endif
+ {
sprintf (buffer, "%lu", (unsigned long) fe->buf.st_size);
if (len && (i = strlen (buffer)) > len) {
if (i - 2 > len) {
file_compute_color (int attr, file_entry *fe)
{
int color;
-
+
switch (attr){
case SELECTED:
color = SELECTED_COLOR;
char *cdest = dest;
format_e *format, *home;
file_entry *fe;
-
+
length = 0;
empty_line = (file_index >= panel->count);
- home = (isstatus) ? panel->status_format : panel->format;
+ home = (isstatus) ? panel->status_format : panel->format;
fe = &panel->dir.list [file_index];
if (!empty_line)
for (format = home; format; format = format->next){
if (format->string_fn){
int len;
-
+
if (empty_line)
txt = " ";
else
/* What shall we do? Will we color each line according to
* the file type? Any suggestions to mc@timur.kazan.su
*/
-
+
attrset (color);
-
+
if (permission_mode && !strcmp(format->id, "perm"))
add_permission_string (old_pos, format->field_len, fe, attr, color, 0);
else if (permission_mode && !strcmp(format->id, "mode"))
length++;
}
}
-
+
if (length < width){
int still = width - length;
while (still--)
offset = 0;
if (!isstatus && panel->split){
-
+
second_column = (file_index - panel->top_file) / llines (panel);
width = (panel->widget.cols - 2)/2 - 1;
-
+
if (second_column){
offset = 1 + width;
width = (panel->widget.cols-2) - (panel->widget.cols-2)/2 - 1;
- }
+ }
} else
width = (panel->widget.cols - 2);
} else
widget_move (&panel->widget, file_index - panel->top_file + 2, 1);
}
-
+
format_file (buffer, panel, file_index, width, attr, isstatus);
-
+
if (!isstatus && panel->split){
if (second_column)
addch (' ');
{
if (!show_mini_info)
return;
-
+
widget_move (&panel->widget, llines (panel)+3, 1);
-
+
if (panel->searching){
attrset (INPUT_COLOR);
printw ("/%-*s", panel->widget.cols-3, panel->search_buffer);
if (panel->marked){
char buffer [100];
char *p;
-
+
attrset (MARKED_COLOR);
printw ("%*s", panel->widget.cols-2, " ");
widget_move (&panel->widget, llines (panel)+3, 1);
/* Status resolves links and show them */
set_colors (panel);
-#ifndef OS2_NT
+#ifndef OS2_NT
if (S_ISLNK (panel->dir.list [panel->selected].buf.st_mode)){
char *link, link_target [MC_MAXPATHLEN];
int len;
link_target[len] = 0;
printw ("-> %-*s", panel->widget.cols - 5,
name_trunc (link_target, panel->widget.cols - 5));
- } else
+ } else
addstr (_("<readlink failed>"));
return;
}
int items; /* Number of items */
items = llines (panel) * (panel->split ? 2 : 1);
-
+
for (i = 0; i < items; i++){
if (i+panel->top_file >= panel->count)
color = 0;
color = 2 * (panel->dir.list [i+panel->top_file].f.marked);
color += (panel->selected==i+panel->top_file && panel->active);
}
- repaint_file (panel, i+panel->top_file, 1, color, 0);
+ repaint_file (panel, i+panel->top_file, 1, color, 0);
}
standend ();
panel->dirty = 0;
{
if (!show_mini_info)
return;
-
+
standend ();
widget_move (&panel->widget, llines (panel)+2, 1);
#ifdef HAVE_SLANG
#else
hline ((slow_terminal ? '-' : ACS_HLINE) | NORMAL_COLOR,
panel->widget.cols-2);
-#endif
+#endif
}
void
panel->widget.y, panel->widget.x,
panel->widget.lines, panel->widget.cols);
-#ifdef HAVE_SLANG
+#ifdef HAVE_SLANG
if (show_mini_info) {
#ifdef linux_unicode
if (SLtt_Unicode) {
- SLsmg_draw_unicode (panel->widget.y + llines (panel) + 2,
+ SLsmg_draw_unicode (panel->widget.y + llines (panel) + 2,
panel->widget.x, SLUNI_DSLTEE_CHAR);
- SLsmg_draw_unicode (panel->widget.y + llines (panel) + 2,
+ SLsmg_draw_unicode (panel->widget.y + llines (panel) + 2,
panel->widget.x + panel->widget.cols - 1, SLUNI_DSRTEE_CHAR);
} else
#endif /* linux_unicode */
}
}
#endif /* have_slang */
-
+
if (panel->active)
attrset (REVERSE_COLOR);
addstr (">");
widget_move (&panel->widget, 0, panel->widget.cols-3);
addstr ("v");
-
+
if (panel->active)
standend ();
}
adjust_top_file (WPanel *panel)
{
int old_top = panel->top_file;
-
+
if (panel->selected - old_top > llines (panel))
panel->top_file = panel->selected;
if (old_top - panel->count > llines (panel))
{
int i;
char *subdir;
-
+
if (!name){
panel->selected = 0;
panel->top_file = 0;
}
if (subdir < name)
subdir = name;
-
+
/* Search that subdirectory, if found select it */
for (i = 0; i < panel->count; i++){
if (strcmp (subdir, panel->dir.list [i].fname))
panel_update_cols (Widget *widget, int frame_size)
{
int cols, origin;
-
+
if (horizontal_split){
widget->cols = COLS;
return;
origin = first_panel_size;
}
}
-
+
widget->cols = cols;
widget->x = origin;
}
panel_save_name (WPanel *panel)
{
extern int saving_setup;
-
+
/* If the program is shuting down */
if ((midnight_shutdown && auto_save_setup) || saving_setup)
return copy_strings (panel->panel_name, 0);
panel_save_setup (p, name);
x_panel_destroy (p);
clean_dir (&p->dir, p->count);
-
+
/* save and clean history */
if (p->dir_history){
Hist *current, *old;
delete_format (p->format);
delete_format (p->status_format);
-
+
free (p->user_format);
for (i = 0; i < LIST_TYPES; i++)
free (p->user_status_format [i]);
panel = xmalloc (sizeof (WPanel), "panel_new");
memset (panel, 0, sizeof (WPanel));
-
+
/* No know sizes of the panel at startup */
init_widget (&panel->widget, 0, 0, 0, 0, (callback_fn)
panel_callback, (destroy_fn) panel_destroy,
/* We do not want the cursor */
widget_want_cursor (panel->widget, 0);
-
+
mc_get_current_wd (panel->cwd, sizeof (panel->cwd)-2);
strcpy (panel->lwd, ".");
panel->is_panelized = 0;
panel->has_dir_sizes = 0;
panel->format = 0;
- panel->status_format = 0;
+ panel->status_format = 0;
panel->format_modified = 1;
-
+
panel->panel_name = strdup (panel_name);
panel->user_format = strdup (DEFAULT_USER_FORMAT);
-
+
for(i = 0; i < LIST_TYPES; i++)
panel->user_status_format [i] = strdup (DEFAULT_USER_FORMAT);
-
+
panel->search_buffer [0] = 0;
panel->frame_size = frame_half;
section = copy_strings ("Temporal:", panel->panel_name, 0);
}
set_panel_formats (panel);
}
-
+
/* Load the default format */
panel->count = do_load_dir (&panel->dir, panel->sort_type,
panel->reverse, panel->case_sensitive, panel->filter);
bzero (&(panel->dir_stat), sizeof (panel->dir_stat));
show_dir (panel);
}
-
+
panel->count = do_reload_dir (&panel->dir, panel->sort_type, panel->count,
panel->reverse, panel->case_sensitive, panel->filter);
panel->marked = 0;
int header_len;
int spaces, extra;
int side, width;
-
+
char *txt, buffer[30]; /*Hope that this is enough ;-) */
if (!panel->split)
adjust_top_file (panel);
-
+
widget_erase (&panel->widget);
show_dir (panel);
for (side = 0; side <= panel->split; side++){
format_e *format;
-
+
if (side){
attrset (NORMAL_COLOR);
one_vline ();
width = panel->widget.cols/2 - 3;
else
width = panel->widget.cols - 2;
-
+
for (format = panel->format; format; format = format->next){
if (format->string_fn){
txt = format->title;
-
+
header_len = strlen (txt);
if (header_len > format->field_len){
strcpy (buffer, txt);
txt [format->field_len] = 0;
header_len = strlen (txt);
}
-
+
attrset (MARKED_COLOR);
spaces = (format->field_len - header_len) / 2;
extra = (format->field_len - header_len) % 2;
continue;
}
}
-
+
if (width > 0)
printw ("%*s", width, "");
}
panel->frame_size = frame;
panel->split = 0;
}
-
+
/* Now, the optional column specifier */
format = skip_separators (format);
-
+
if (*format == '1' || *format == '2'){
if (!isstatus)
panel->split = *format == '2';
if (!isstatus)
panel_update_cols (&(panel->widget), panel->frame_size);
-
+
return skip_separators (format);
}
opt_size := : size [opt_expand]
size := [0-9]+
opt_expand := +
-
+
*/
format_e *
int i;
*error = 0;
-
+
/*
* This makes sure that the panel and mini status full/half mode
* setting is equal
int found = 0;
darr = xmalloc (sizeof (format_e), "parse_display_format");
-
+
/* I'm so ugly, don't look at me :-) */
if (!home)
home = old = darr;
-
+
old->next = darr;
darr->next = 0;
old = darr;
-
+
format = skip_separators (format);
if (*format == '<' || *format == '>'){
format = skip_separators (format+1);
} else
set_justify = 0;
-
+
for (i = 0; i < ELEMENTS(formats); i++){
int klen = strlen (formats [i].id);
darr->title = "";
darr->id = formats [i].id;
darr->expand = formats [i].expands;
-
+
if (set_justify)
darr->just_mode = justify;
else
}
if (!found){
char old_char;
-
+
int pos = min (8, strlen (format));
delete_format (home);
old_char = format [pos];
}
total_cols += darr->requested_field_len;
}
-
+
*res_total_cols = total_cols;
if (home)
home->items = items;
char *expand_list [MAX_EXPAND]; /* Expand at most 4 fields. */
int i;
format_e *darr, *home;
-
+
if (!format)
format = DEFAULT_USER_FORMAT;
-
+
home = parse_display_format (panel, format, error, isstatus, &total_cols);
if (*error)
return 0;
-
+
/* Status needn't to be split */
usable_columns = ((panel->widget.cols-2)/((isstatus)
? 1
: (panel->split+1))) - (!isstatus && panel->split);
-
+
/* Clean expand list */
for (i = 0; i < MAX_EXPAND; i++)
expand_list [i] = '\0';
-
-
+
+
/* Look for the expandable fields and set field_len based on the requested field len */
for (darr = home; darr && expand_top < MAX_EXPAND; darr = darr->next){
darr->field_len = darr->requested_field_len;
if (darr->expand)
expand_list [expand_top++] = darr->id;
}
-
+
/* If we used more columns than the available columns, adjust that */
if (total_cols > usable_columns){
int pdif, dif = total_cols - usable_columns;
-
+
while (dif){
pdif = dif;
for (darr = home; darr; darr = darr->next){
/* avoid endless loop if num fields > 40 */
if (pdif == dif)
- break;
+ break;
}
total_cols = usable_columns; /* give up, the rest should be truncated */
}
set_panel_formats (WPanel *p)
{
format_e *form;
- char *err;
+ char *err;
int retcode = 0;
-
+
form = use_display_format (p, panel_format (p), &err, 0);
-
+
if (err){
free (err);
retcode = 1;
else {
if (p->format)
delete_format (p->format);
-
+
p->format = form;
}
-
+
if (show_mini_info){
-
+
form = use_display_format (p, mini_status_format (p), &err, 1);
-
+
if (err){
free (err);
retcode += 2;
else {
if (p->status_format)
delete_format (p->status_format);
-
+
p->status_format = form;
}
}
-
+
panel_format_modified (p);
panel_update_cols (&(p->widget), p->frame_size);
-
+
return retcode;
}
{
int repaint = 0;
int items = ITEMS (panel);
-
+
/* Although currently all over the code we set the selection and
top file to decent values before calling select_item, I could
forget it someday, so it's better to do the actual fitting here */
int old_top;
old_top = panel->top_file;
#endif
-
+
if (panel->top_file < 0){
repaint = 1;
panel->top_file = 0;
repaint = 1;
panel->top_file = panel->count-1;
}
-
+
if ((panel->count - panel->top_file) < items){
repaint = 1;
panel->top_file = panel->count - items;
if (panel->top_file < 0)
panel->top_file = 0;
}
-
+
if (panel->selected < panel->top_file){
repaint = 1;
panel->top_file = panel->selected;
panel->top_file = panel->selected - items + 1;
}
-#ifndef HAVE_X
+#ifndef HAVE_X
if (repaint)
paint_panel (panel);
else
{
if (panel->selected+1 == panel->count)
return;
-
+
unselect_item (panel);
panel->selected++;
move_rel (WPanel *panel, int rel)
{
unselect_item (panel);
-
+
if (rel < 0){
if (panel->selected + rel < 0)
panel->selected = 0;
panel->top_file += lines;
adjust = 1;
}
-
+
if (panel->selected - panel->top_file < 0){
panel->top_file += lines;
adjust = 1;
}
-
+
if (adjust){
if (panel->top_file > panel->selected)
panel->top_file = panel->selected;
if (panel->list_type == list_icons){
do_move_up (panel);
return 1;
- } else {
+ } else {
if (panel->split){
move_selection (panel, -llines (panel));
return 1;
- } else
+ } else
return maybe_cd (c_code, 0);
}
}
if (panel->selected == 0)
return;
unselect_item (panel);
-
+
if (torben_fj_mode){
int middle_pos = panel->top_file + (ITEMS (panel)/2);
return;
}
}
-
+
panel->top_file = 0;
panel->selected = 0;
return;
}
}
-
+
panel->selected = panel->count-1;
#ifndef HAVE_X
paint_dir (panel);
if (panel->has_dir_sizes)
panel->total += panel->dir.list [idx].buf.st_size;
panel->dirs_marked++;
- } else
+ } else
panel->total += panel->dir.list [idx].buf.st_size;
-#ifndef HAVE_XVIEW
+#ifndef HAVE_XVIEW
set_colors (panel);
#endif
} else {
int i, mark;
mark = !panel->dir.list [start].f.marked;
-
+
for (i = start; i < end; i++)
do_file_mark (panel, i, mark);
}
{
int idx = panel->selected;
do_file_mark (panel, idx, selection (panel)->f.marked ? 0 : 1);
-#ifndef HAVE_XVIEW
+#ifndef HAVE_XVIEW
repaint_file (panel, idx, 1, 2*panel->dir.list [idx].f.marked+1, 0);
-#endif
+#endif
if (mark_moves_down && do_move)
move_down (panel);
}
if (!found)
panel->search_buffer [--l] = 0;
-#ifndef HAVE_X
+#ifndef HAVE_X
paint_panel (panel);
#endif
}
|| link_isdir (selection (panel))){
do_cd (selection (panel)->fname, cd_exact);
return;
- } else {
+ } else {
if (is_exe (selection (panel)->buf.st_mode) &&
if_link_is_exe (selection (panel))) {
-#ifdef USE_VFS
- if (vfs_current_is_local ())
-#endif
+#ifdef USE_VFS
+ if (vfs_current_is_local ())
+#endif
{
char *tmp = name_quote (selection (panel)->fname, 0);
char *cmd = copy_strings (".", PATH_SEP_STR, tmp, 0);
execute (cmd);
free (tmp);
free (cmd);
- }
-#ifdef USE_VFS
+ }
+#ifdef USE_VFS
else if (vfs_current_is_extfs ()) {
char *tmp = vfs_get_current_dir();
char *tmp2;
extfs_run(tmp2);
free (tmp2);
}
-#endif /* USE_VFS */
+#endif /* USE_VFS */
return;
} else {
regex_command (selection (panel)->fname, "Open", NULL, 0);
change_panel ();
move_down (panel);
-
+
free (new_dir);
}
char buffer [MC_MAXPATHLEN], *p;
int i;
struct stat mybuf;
-
+
i = readlink (selection (panel)->fname, buffer, MC_MAXPATHLEN);
if (i < 0)
return;
change_panel ();
do_cd (new_dir, cd_exact);
change_panel ();
-
+
move_down (panel);
-
+
free (new_dir);
}
}
{ ALT(KEY_F(12)), drive_cmd_b },
{ ALT('d'), drive_chg },
#endif
-
+
/* Emacs-like bindings */
{ XCTRL('v'), next_page }, /* C-v like emacs */
{ ALT('v'), prev_page }, /* M-v like emacs */
{ KEY_KP_SUBTRACT, unselect_cmd_panel },
{ ALT('*'), reverse_selection_cmd_panel },
{ KEY_KP_MULTIPLY, reverse_selection_cmd_panel },
-
+
#ifdef HAVE_GNOME
{ '+', select_cmd_panel },
{ KEY_F(7), mkdir_panel_cmd },
{ KEY_F(8), delete_cmd },
#endif
-
+
{ 0, 0 }
};
-
+
static inline int
panel_key (WPanel *panel, int key)
{
define_label (h, (Widget *)panel, 7, _("Mkdir"), mkdir_panel_cmd);
define_label (h, (Widget *)panel, 8, _("Delete"), delete_cmd);
x_create_panel (h, h->wdata, panel);
-#endif
+#endif
return 1;
-
+
case WIDGET_DRAW:
#ifndef HAVE_XVIEW
paint_panel (panel);
#else
- show_dir (panel);
+ show_dir (panel);
#endif
break;
panel->cwd, unix_error_string (errno));
} else
subshell_chdir (panel->cwd);
-
+
show_dir (panel);
focus_select_item (panel);
-#ifndef HAVE_X
+#ifndef HAVE_X
define_label (h, (Widget *)panel, 1, _("Help"), help_cmd);
define_label (h, (Widget *)panel, 2, _("Menu"), user_menu_cmd);
define_label (h, (Widget *)panel, 3, _("View"), view_panel_cmd);
/* Chain behaviour */
default_proc (h, WIDGET_FOCUS, par);
return 1;
-
+
case WIDGET_UNFOCUS:
/* Janne: look at this for the multiple panel options */
if (panel->searching){
panel->searching = 0;
display_mini_info (panel);
}
-#ifdef HAVE_X
+#ifdef HAVE_X
show_dir (panel);
unfocus_unselect_item (panel);
panel->active = 0;
unselect_item (panel);
#endif
return 1;
-
+
case WIDGET_KEY:
return panel_key (panel, par);
break;
panel_event (Gpm_Event *event, WPanel *panel)
{
const int lines = panel->count;
-
+
int my_index;
extern void change_panel (void);
if (my_index >= panel->count)
my_index = panel->count - 1;
-
+
if (my_index != panel->selected){
unselect_item (panel);
panel->selected = my_index;
/* This one is new */
mark_if_marking (panel, event);
-
+
} else if ((event->type & (GPM_UP|GPM_DOUBLE)) == (GPM_UP|GPM_DOUBLE)){
if (event->y > 0 && event->y <= lines)
do_enter (panel);
panel_event (Gpm_Event *event, WPanel *panel)
{
const int lines = llines (panel);
-
+
int my_index;
extern void change_panel (void);
if (my_index >= panel->count)
my_index = panel->count - 1;
-
+
if (my_index != panel->selected){
unselect_item (panel);
panel->selected = my_index;
/* This one is new */
mark_if_marking (panel, event);
-
+
} else if ((event->type & (GPM_UP|GPM_DOUBLE)) == (GPM_UP|GPM_DOUBLE)){
if (event->y > 0 && event->y <= lines)
do_enter (panel);